मैं एक शीर्ष छायाकर्ता को कई मैट्रिसेस कैसे भेजूं?


9

मैं हड्डियों / चमड़ी का उपयोग करके एनिमेशन का अभ्यास कर रहा हूं। मैं प्रति शीर्ष पर shader एक मैट्रिक्स भेजने की कोशिश कर रहा हूँ। मैं इन दोनों दृष्टिकोणों के बारे में सोच सकता हूं।

विधि 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);

अगर मेरे पास बड़ी संख्या में मैट्रीस हैं, तो यह स्पष्ट रूप से एक अच्छा तरीका नहीं है। मेरा दूसरा विचार जिसे मैंने अभी तक आज़माया नहीं है क्योंकि रिफ्लेक्टर के लिए बहुत सारे कोड हैं

विधि 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 का उपयोग कर रहा हूं, लेकिन यह बहुत स्मार्ट नहीं दिखता है ...

OpenGL ES 2 shader में कई मैट्रिक्स भेजने का सबसे अच्छा तरीका क्या है?

LE: मैं एंड्रॉइड का उपयोग कर रहा हूं, इसलिए मैं एक जावा समाधान की तलाश कर रहा हूं।


बस एक सिदोते: यदि आपके पास बहुत अधिक मेट्रिसेस हैं तो आप उन्हें fp बनावट के माध्यम से भी भेज सकते हैं।
क्रॉस्टर

जवाबों:


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

मैं एक VBO का उपयोग करने का सुझाव दूंगा। अपने वीबीओ को मेट्रिसेस से भरें, और एक समान के बजाय एक विशेषता का उपयोग करके उन्हें पास करें। इस तरह VBO छाया में एक नया mat4 प्रति शीर्ष पास वितरित करेगा।

जब आप ड्राइंग से पहले VBO को बांधते हैं (या इन राज्यों के लिए VAO बनाते हैं):

  • शीर्ष गुण सक्षम करें (glEnableVertexAttribArray)
  • शीर्ष गुण विभाजक को 0 पर सेट करें (glVertexAttribDivisor)
  • शीर्ष गुण सूचक सेट करें (glVertexAttribPointer)

एक विशेषता के रूप में एक मैट 4 पास करने का तरीका देखें : /programming/17355051/use-a-matrix-as-vertex-attribute-in-opengl3-core-profile

उम्मीद है की यह मदद करेगा


1
दिलचस्प। हालांकि, मैट्रिसेस काफी बार बदल सकते हैं (उदाहरण के लिए मैं उनमें से हर फ्रेम में एक अतिरिक्त घुमाव जोड़ सकता हूं)। वे वही नहीं रहेंगे। क्या वीबीओ इस परिदृश्य के लिए उपयुक्त हैं?
async

हाँ, आप बस नए मेट्रिसेस को हर फ्रेम में अपलोड करें glBufferData
Luka

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.