আমি কীভাবে একটি ভার্টেক্স শ্যাডারে একাধিক ম্যাট্রিক পাঠাতে পারি?


9

আমি হাড় / ত্বক ব্যবহার করে অ্যানিমেশন অনুশীলন করছি। আমি শেডারটি ভার্টেক্সে এক ম্যাট্রিক্স প্রেরণের চেষ্টা করছি। আমি এই দুটি পদ্ধতির কথা ভাবতে পারি।

পদ্ধতি 1

এই জাতীয় প্রতিটি হাড়ের ম্যাট্রিক্সের জন্য আমার একটি ইউনিফর্ম হ্যান্ডেল রয়েছে

u_Bone0 = GLES20.glGetUniformLocation(mProgram, "u_Bone[0]");
u_Bone1 = GLES20.glGetUniformLocation(mProgram, "u_Bone[1]");

এবং onDrawআমি তাদের প্রত্যেককে শ্যাডারে প্রেরণ করব: GLES20.glUniformMatrix4fv(u_Bone0, 1, false, matrix0, 0);

যদি আমার কাছে প্রচুর পরিমাণে ম্যাট্রিক থাকে তবে এটি অবশ্যই ভাল উপায় নয় approach আমার দ্বিতীয় ধারণাটি যা আমি এখনও চেষ্টা করি নি যেহেতু রিফ্যাক্টরের জন্য প্রচুর কোড রয়েছে

পদ্ধতি 2

glUniformMatrix4fvতাদের একবারে পাঠানোর জন্য ব্যবহার করতে হবে (ধরুন আমার কাছে 20 টি ম্যাট্রিক রয়েছে)

GLES20.glUniformMatrix4fv(u_Bones, 20, false, matrices, 0);

যেখানে matricesহয় float[16 * 20]। তবে তারপরে প্রতিটি হাড়ের ম্যাট্রিক পরিবর্তন করা কিছুটা ক্লান্তিকর হয়ে ওঠে। উদাহরণস্বরূপ, আমি যদি তৃতীয় ম্যাট্রিক্স পেতে চাই তবে আমার লাইনের সাথে কিছু দরকার

float[] _3rd = Arrays.copy(matrices, 3*16, 4*16);

এবং মানগুলি সংরক্ষণ করা আরও বিরক্তিকর হয়ে উঠতে পারে।


আমি এখন পদ্ধতি 1 ব্যবহার করছি তবে এটি খুব স্মার্ট দেখাচ্ছে না ...

ওপেনজিএল ইএস 2 শেডারে একাধিক ম্যাট্রিক পাঠানোর সর্বোত্তম উপায় কী?

এলই: আমি অ্যান্ড্রয়েড ব্যবহার করছি, তাই আমি জাভা সমাধান খুঁজছি।


কেবলমাত্র একটি সিডেনোট: আপনার যদি অনেক বেশি ম্যাট্রিক থাকে তবে আপনি এগুলি এফপি টেক্সচারের মাধ্যমেও পাঠাতে পারেন।
ক্রোমস্টার

উত্তর:


2

শেডারে একাধিক ম্যাট্রিক পাঠানো সহজবোধ্য:

Shader:

uniform mat4 mBones[20]; //20 matrices
.. skipped code ..
vec4 vert = vec4(vPosition, 1.0) * mBones[int(vaBoneId)];

কার্যক্রম:

glUniformMatrix4fv(fShaderUnitSkeletal.uBones, 20, False, @bones20[0]); // Passing 20 matrices

প্রতিটি হাড়ের জন্য ম্যাট্রিক পরিবর্তন করা আপনি কীভাবে শেডারে পাস করেন তার সাথে সম্পর্কিত নয়। আপনি সংখ্যার অ্যারের পরিবর্তে কাঠামোর সাথে কাজ করলে আপনি পরিবর্তনগুলি আরও সহজ করতে পারেন।

bones20: array of TMatrix; // Declare array of matrices
bones20[2] := TMatrix.Identity; //Reset 3rd matrix

1
আমি অ্যান্ড্রয়েড / জাভা ব্যবহার করছি। অতএব আমি "কাঠামো" বা অন্যান্য ডেটা ধরণের ব্যবহার করতে পারি না (সংক্ষিপ্ত মন্তব্যের জন্য দুঃখিত, আমি এটিএমটি বিস্তারিতভাবে জানাতে পারি না, তবে পরে ফিরে আসব)
async

2

আমি একটি ভিবিও ব্যবহার করার পরামর্শ দেব। ম্যাট্রিকগুলি দিয়ে আপনার ভিবিও পূরণ করুন এবং ইউনিফর্মের পরিবর্তে কোনও বৈশিষ্ট্য ব্যবহার করে তাদের পাস করুন। এইভাবে ভিবিও শ্যাডারে প্রতি ভেরিটেক্স পাসের জন্য একটি নতুন ম্যাট 4 বিতরণ করবে।

যখন আপনি আঁকার আগে VBO কে আবদ্ধ করবেন (বা এই রাজ্যের জন্য ভিএও তৈরি করুন):

  • ভার্টেক্স গুণাবলী সক্ষম করুন (glEnableVertexAttribArray)
  • প্রান্তিক বৈশিষ্ট্য বিভাজকগুলিকে 0 তে সেট করুন (glVertexAttribDivizer)
  • ভার্টেক্স অ্যাট্রিবিউটস পয়েন্টার সেট করুন (glVertexAttribPointer)

কীভাবে একটি ম্যাট 4 কে অ্যাট্রিবিউট হিসাবে পাস করতে হবে তা একবার দেখুন: https://stackoverflow.com

আশাকরি এটা সাহায্য করবে


1
মজাদার. যাইহোক, ম্যাট্রিকগুলি বেশ ঘন ঘন পরিবর্তিত হতে পারে (উদাহরণস্বরূপ আমি প্রতিটি ফ্রেমের মধ্যে একটিতে অতিরিক্ত রোটেশন যুক্ত করতে পারি)। তারা একই থাকবে না। ভিবিও কি এই দৃশ্যের জন্য উপযুক্ত?
async

হ্যাঁ আপনি শুধু গ্লোফারডাটা ব্যবহার করে প্রতিটি ফ্রেমে নতুন ম্যাট্রিকগুলি আপলোড করুন
লুকা

0

কোডটিতে ম্যাট্রিকের সংখ্যা বিমূর্ত করতে অ্যারে ব্যবহার করতে পদ্ধতি 1 প্রসারিত করা যেতে পারে: (জাভা ধরে নিচ্ছেন)

int[] u_Bone=new int[NUM_MATRICES];

for(int i=0;i<u_Bone.length;i++)
   u_Bone[i]=GLES20.glGetUniformLocation(mProgram, "u_Bone["+i+"]");

এবং তারপরে আপনি ম্যাট্রিকগুলি সেট করার সময় আপনি করতে পারেন

for(int i=0;i<matrix.length;i++)
    GLES20.glUniformMatrix4fv(u_Bone[i], 1, false, matrix[i], 0);

আমি এটিকে বাস্তবায়ন করেছিলাম, তবে এখনও তেমন কিছু উন্নতি করে না। তবে এখন পর্যন্ত এটি সেরা পদ্ধতির হতে পারে।
async
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.