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