Problema de Shader de animation de malla de piel

Tengo problemas para animar correctamente una malla de piel de un file .fbx. Siento que el problema está en el sombreado, pero no estoy seguro de lo que está pasando. Todo lo que sé es que estoy obteniendo resultados inesperados donde siento que estoy proporcionando toda la información adecuada.

Si utilizo un solo hueso para todas las posiciones en lugar de las que se pasan en la location del layout, pone los vértices en el lugar correcto, por lo que los cálculos son correctos.

Desde el aspecto de todo, mis cálculos óseos son correctos, los identificadores óseos están cargados y los pesos cargados bien, pero parece que no mantienen sus valores.

Parece que está sucediendo lo siguiente: BoneIDS y / o BoneWeights se están poniendo a cero o se han establecido en otra cosa.

Para reference:

typedef struct sFloat4 { float x, y, z, w; } sFloat4; typedef struct sInt4 { int x, y, z, w; } sInt4; typedef struct sVertex_p4t4n4b4i4 { sFloat4 Pos; sFloat4 TexUVx2; sFloat4 Normal; sInt4 BoneIDs; sFloat4 BoneWeights; } sVertex_p4t4n4b4i4; 

y

 unsigned int totalVertBufferSizeBYTES = numIndicesInIndexArray * sizeof ( sVertex_p4t4n4b4i4 ); ; glBufferData ( GL_ARRAY_BUFFER, totalVertBufferSizeBYTES, pTempVertArray, GL_STATIC_DRAW ); CheckGLError(); unsigned int bytesInOneVertex = sizeof( sVertex_p4t4n4b4i4 ); unsigned int byteOffsetToPosition = offsetof( sVertex_p4t4n4b4i4, Pos ); unsigned int byteOffsetToUVCoords = offsetof( sVertex_p4t4n4b4i4, TexUVx2 ); unsigned int byteOffsetToNormal = offsetof( sVertex_p4t4n4b4i4, Normal ); unsigned int byteOffsetToBoneIDs = offsetof( sVertex_p4t4n4b4i4, BoneIDs ); unsigned int byteOffsetToBoneWeights = offsetof( sVertex_p4t4n4b4i4, BoneWeights ); glEnableVertexAttribArray ( 0 ); // Position glEnableVertexAttribArray ( 1 ); // TexCoord glEnableVertexAttribArray ( 2 ); // Normal glEnableVertexAttribArray ( 3 ); // BoneIDs glEnableVertexAttribArray ( 4 ); // BoneWeights glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToPosition ); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToUVCoords ); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToNormal ); glVertexAttribPointer(3, 4, GL_INT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToBoneIDs ); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToBoneWeights ); CheckGLError(); 

He descargado toda la información en files de logging como este:

En la carga de malla: ( V: ertex, T: excoord, N: ormal, W: ocho, I: d )

 V: ( -10.7595, -90.5606, 10.2667, 1) T: ( 0.800398, 0.961321, 0, 0) N: ( -0.43245, -0.568786, -0.699621, 0) W: ( 1, 0, 0, 0) I: ( 1, 0, 0, 0) ------------------------------------ V: ( -13.78, -90.5591, 15.3024, 1) T: ( 0.791644, 0.936781, 0, 0) N: ( -0.786336, -0.582521, -0.205779, 0) W: ( 1, 0, 0, 0) I: ( 1, 0, 0, 0) ------------------------------------ V: ( -12.0146, -80.7495, 15.3008, 1) T: ( 0.842778, 0.927585, 0, 0) N: ( -0.994609, 0.0540453, -0.0884974, 0) W: ( 0.5, 0.5, 0, 0) I: ( 0, 1, 0, 0) ------------------------------------ V: ( -12.0146, -80.7495, 15.3008, 1) T: ( 0.842778, 0.927585, 0, 0) N: ( -0.994609, 0.0540453, -0.0884974, 0) W: ( 0.5, 0.5, 0, 0) I: ( 0, 1, 0, 0) ------------------------------------ V: ( -9.78351, -80.4126, 10.7916, 1) T: ( 0.84573, 0.957308, 0, 0) N: ( -0.517826, -0.0239735, -0.85515, 0) W: ( 0.5, 0.5, 0, 0) I: ( 0, 1, 0, 0) ------------------------------------ ... ... ... 

Walk Animation @ 0.1 seconds.log

 ... ... ... RigLArmPinky1 Scaling: 0.999793, 1.00015, 1.00005 Rotation: -0.00196581, -0.000597763, -0.301885, 0.953342 Position: 11.2164, -0.0247269, -1.10963 >> [ Bone #35 ] Global Transformation > Translation: 37.7533, 75.6701, 35.4029 > Scaling: 0.999963, 1.00049, 1.00026 > Rotation: 0.159073, 0.536706, 0.58563, 0.586242 -------------------- ... ... ... -------------------- RigRArmIndex2 Scaling: 1.00019, 0.999862, 0.999948 Rotation: 2.10373e-005, -4.84573e-005, -0.399209, 0.91686 Position: 2.76004, 3.8147e-006, -9.53674e-007 >> [ Bone #20 ] Global Transformation > Translation: -37.1777, 57.9378, -6.8726 > Scaling: 1.00027, 1.00014, 0.999923 > Rotation: -0.96948, 0.194101, 0.141847, 0.0482982 ... ... ... 

Imágenes

Si utilizo identificadores de hueso provistos de la location de layout: Uso de BoneID proporcionados

Si utilizo todos los ID de huesos como 20 position += BoneMatrices[20] * in_Position * in_BoneWeights[0]; : Usando todo BoneID como 20

Si uso todos los identificadores óseos como position += BoneMatrices[35] * in_Position * in_BoneWeights[0]; 35 position += BoneMatrices[35] * in_Position * in_BoneWeights[0]; : Usando todo BoneID como 35

Vertex Shader

 #version 400 layout(location=0) in vec4 in_Position; // x,y,z,1.0f layout(location=1) in vec4 in_UV_x2; layout(location=2) in vec4 in_Normal; // x,y,z,0.0f layout(location=3) in ivec4 in_BoneIDs; layout(location=4) in vec4 in_BoneWeights; out vec4 ex_Position; out vec4 ex_PositionWorld; out vec4 ex_Normal; out vec4 ex_UV_x2; out vec4 ex_BoneWeights; out vec4 ex_BoneIDs; uniform mat4 RotationMatrix; uniform mat4 ModelMatrix; uniform mat4 ViewMatrix; uniform mat4 ProjectionMatrix; const int MAX_BONES = 100; uniform mat4 BoneMatrices[MAX_BONES]; //uniform mat4 BoneRotationMatrices[47]; uniform bool bHasBones; void main(void) { // Calculate MVP Matrix mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; if ( bHasBones == false ) { gl_Position = MVP * in_Position; ex_Position = in_Position; ex_PositionWorld = ModelMatrix * in_Position; ex_Normal = RotationMatrix * normalize(in_Normal); ex_UV_x2 = in_UV_x2; return; } int BoneID0 = in_BoneIDs[0]; int BoneID1 = in_BoneIDs[1]; int BoneID2 = in_BoneIDs[2]; int BoneID3 = in_BoneIDs[3]; // calculate positionworld vec4 position = vec4(0.0f, 0.0f, 0.0f, 0.0f); position += BoneMatrices[BoneID0] * in_Position * in_BoneWeights[0]; position += BoneMatrices[BoneID1] * in_Position * in_BoneWeights[1]; position += BoneMatrices[BoneID2] * in_Position * in_BoneWeights[2]; position += BoneMatrices[BoneID3] * in_Position * in_BoneWeights[3]; gl_Position = MVP * position; ex_Normal = RotationMatrix * in_Normal; ex_Position = position; ex_PositionWorld = ModelMatrix * position; ex_UV_x2 = in_UV_x2; ex_BoneWeights = in_BoneWeights; ex_BoneIDs = in_BoneIDs; return; } 

Si necesita que proporcione algo más, estoy más que feliz de publicar más código, imágenes o volcar cualquier información para usted

Editar # 1

Así que estoy trabajando en la teoría de que los identificadores están siendo alterados (establecido en 0). Lo que hice fue esto:

  int BoneID0 = in_BoneIDs[0] + 46; int BoneID1 = in_BoneIDs[1] + 46; int BoneID2 = in_BoneIDs[2] + 46; int BoneID3 = in_BoneIDs[3] + 46; // calculate positionworld vec4 position = vec4(0.0f, 0.0f, 0.0f, 0.0f); position += BoneMatrices[BoneID0] * in_Position * in_BoneWeights[0]; position += BoneMatrices[BoneID1] * in_Position * in_BoneWeights[1]; position += BoneMatrices[BoneID2] * in_Position * in_BoneWeights[2]; position += BoneMatrices[BoneID3] * in_Position * in_BoneWeights[3]; 

Eso tiene el mismo resultado que la primera image. Si agrego 47 (El tamaño de la matriz ósea) lanza INVALID_OPERATION . ¿Eso testing que los identificadores no se están configurando correctamente?

Editar # 2 Cambió sVertex_p4t4n4b4i4 para que todos sean flotantes y las ubicaciones de layout cambiadas sean vec4 lugar de ivec4 . Emitió los ids para ser ints, y todo funciona perfectamente ahora.

Puede borrar / cerrar esto

Gracias de antemano a cualquiera que pueda señalar algo