Bir tepe gölgelendiricisine nasıl birden fazla matris gönderirim?


9

Kemikler / deri kullanarak animasyonlar yapıyorum. Gölgelendiriciye köşe başına bir matris göndermeye çalışıyorum. Bu iki yaklaşımı düşünebilirim.

Yöntem 1

Bunun gibi her kemik matrisi için tek bir kolum var

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

ve onDrawher birini gölgelendiriciye gönderiyorum: GLES20.glUniformMatrix4fv(u_Bone0, 1, false, matrix0, 0);

Çok sayıda matrisim varsa bu iyi bir yaklaşım değildir. Refactor için çok fazla kod olduğu için henüz denemediğim ikinci fikrim

Yöntem 2

glUniformMatrix4fvHepsini aynı anda göndermek için kullanmaktır (20 matrisim olduğunu varsayın)

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

nerede matricesolduğunu float[16 * 20]. Ancak daha sonra her kemik için matrisleri değiştirmek biraz sıkıcı olur. Örneğin, 3. matrisi elde etmek istersem,

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

ve değerleri geri kaydetmek daha can sıkıcı olabilir.


Şimdi Yöntem 1 kullanıyorum, ama çok akıllı görünmüyor ...

Bir OpenGL ES 2 gölgelendiricisine birden çok matris göndermenin en iyi yolu nedir?

LE: Android kullanıyorum, bu yüzden bir Java çözümü arıyorum.


Sadece bir sidenote: Çok fazla matrisiniz varsa bunları fp dokusu ile de gönderebilirsiniz.
Kromster

Yanıtlar:


2

Gölgelendiriciye birden fazla matris göndermek basittir:

Shader:

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

Programı:

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

Her kemik için matrisleri değiştirmek, bunları gölgelendiriciye nasıl geçirdiğinizle ilgili değildir. Sayı dizisi yerine yapılarla çalışıyorsanız değişiklikleri basitleştirebilirsiniz.

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

1
Android / Java kullanıyorum. Bu nedenle "yapıları" veya diğer veri türlerini kullanamıyorum (Kısa yorum için özür dilerim, atm'i ayrıntılı olarak anlayamıyorum, ancak daha sonra tekrar geleceğim)
async

2

Bir VBO kullanmanızı öneririm. VBO'nuzu matrislerle doldurun ve üniforma yerine bir özellik kullanarak geçirin. Bu şekilde VBO gölgelendiricideki köşe geçişi başına yeni bir mat4 dağıtacaktır.

VBO'yu çizmeden önce bağladığınızda (veya bu durumlar için bir VAO oluşturduğunuzda):

  • Köşe özelliklerini etkinleştir (glEnableVertexAttribArray)
  • Köşe özellikleri bölücülerini 0 olarak ayarlayın (glVertexAttribDivisor)
  • Köşe özellikleri işaretçisini ayarlama (glVertexAttribPointer)

Bir mat4'ü özellik olarak nasıl geçireceğinize bir göz atın: /programming/17355051/using-a-matrix-as-vertex-attribute-in-opengl3-core-profile

Bu yardımcı olur umarım


1
İlginç. Bununla birlikte, matrisler oldukça sık değişebilir (örneğin, her kareden birine ek bir dönüş ekleyebilirim). Aynı kalmayacaklar. VBO'lar bu senaryo için uygun mu?
async

evet sadece glBufferData
Luka

0

yöntem 1, koddaki matris sayısını belirlemek için dizileri kullanmak üzere genişletilebilir: (java varsayarak)

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+"]");

ve sonra matrisleri ayarladığınızda

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

Sonunda bunu uygulamaya başladım, ancak yine de bir şeyleri çok fazla geliştirmiyorum. Ama şimdiye kadar en iyi yaklaşım olabilir.
async
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.