버텍스 쉐이더에 여러 행렬을 보내려면 어떻게해야합니까? 많기 때문에 아직 시도하지 않은 두 번째

뼈 / 스킨을 사용하여 애니메이션을 연습하고 있습니다. 버텍스 당 하나의 행렬을 셰이더를 보내려고합니다. 이 두 가지 접근법을 생각할 수 있습니다.

방법 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]. 그러나 각 뼈의 행렬을 수정하는 것은 약간 지루합니다. 예를 들어, 3 번째 행렬을 얻으려면

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

값을 저장하면 더욱 성 가실 수 있습니다.


지금 방법 1을 사용하고 있지만 그리 똑똑하지는 않습니다 …

여러 행렬을 OpenGL ES 2 셰이더에 보내는 가장 좋은 방법은 무엇입니까?

LE : Android를 사용하고 있으므로 Java 솔루션을 찾고 있습니다.



답변

여러 매트릭스를 셰이더에 보내는 것은 간단합니다.

쉐이더 :

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

답변

VBO를 사용하는 것이 좋습니다. VBO를 행렬로 채우고 유니폼 대신 속성을 사용하여 전달하십시오. 그렇게하면 VBO는 쉐이더에서 버텍스 패스 당 새로운 mat4를 배포합니다.

그리기 전에 VBO를 바인딩하거나 다음 상태에 대한 VAO를 만들 때 :

  • 꼭짓점 속성 사용 (glEnableVertexAttribArray)
  • 꼭짓점 속성 제수를 0으로 설정 (glVertexAttribDivisor)
  • 꼭짓점 속성 포인터 설정 (glVertexAttribPointer)

mat4를 속성으로 전달하는 방법을 살펴보십시오. /programming/17355051/using-a-matrix-as-vertex-attribute-in-opengl3-core-profile

도움이 되었기를 바랍니다


답변

메소드 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);