HLSL vertex skinning vertex normals

A528d11e2590c45b74a53dadde386125
0
Xcrypt 101 Apr 30, 2012 at 10:52

I’m learning about animation, and vertex skinning for normals usually goes like this:

//VERTEXNORM
for(int i = 0; i<m_VecIndices.size(); i+=3) {
VertexPosColNorm* triVertex[3];
triVertex[0] = &m_SkinnedVertices[m_VecIndices[i]];
triVertex[1] = &m_SkinnedVertices[m_VecIndices[i+1]];
triVertex[2] = &m_SkinnedVertices[m_VecIndices[i+2]];

D3DXVECTOR3 triSide[2];
triSide[0] = triVertex[1]->pos - triVertex[0]->pos;
triSide[1] = triVertex[2]->pos - triVertex[0]->pos;

D3DXVECTOR3 triNorm;
D3DXVec3Cross(&triNorm, &triSide[0], &triSide[1]);
D3DXVec3Normalize(&triNorm, &triNorm);

triVertex[0]->normal += triNorm;
triVertex[1]->normal += triNorm;
triVertex[2]->normal += triNorm;
}


//normalize
for (int i= 0; i < m_VecVertices.size(); ++i)
{
D3DXVec3Normalize(&m_VecVertices[i].normal, &m_VecVertices[i].normal);
}

Basically recalculating all the normals. The reason you can’t do a simple matrix transformation (float3x3(BoneBindPoseT)*float3x3(boneMST)) is because translation of a bone also affects the orientation of the normals.

But the problem is implementing this in hlsl. Can anyone tell me how I would do this?

Atm I have this:

VS_OUTPUT VS_Skinned(VS_INPUT_SKINNED input){

VS_OUTPUT output = (VS_OUTPUT)0;

float4 vertex = float4(input.iPosL,1);
float4 normal = float4(input.iNormal,0);
float4 tVertex = 0;
float3 tNormal =0;

for (int i =0; i < 4 ;i++)
{
   int id = input.BoneIndices[i];
   float4x4 bT = gBoneMatrices[id];
   float bWeight = input.BoneWeights[i];

   tVertex += mul(bT,vertex)*bWeight;
   tNormal += mul((float3x3)bT,normal.xyz)*bWeight;
}
tVertex.w = 1.0f;
output.oPosH = mul(tVertex,matWorldViewProj);
output.oNormal = normalize( mul(tNormal, (float3x3)matWorld));
output.oColor=input.iColor;
return output;
}

But this isn’t correct because it doesn’t take into account the translation part. How do I fix this?

EDIT: actually, I have a second question about animation. Why do we store the bindposetransformation of all the bones, and the world transformation per bone per animation frame and then after that recaluclate each vertex of the model?
I would think it is more performance friendly to just store all the vertices per frame per animation, since we don’t need to do any computing afterwards. Or would this take up too much memory?

1 Reply

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 168 Apr 30, 2012 at 16:41

Re: your second question, yes, it would likely take up too much memory to store every vertex of every frame for every animation on a high-detail character. Besides, you’d lose any possibility of doing any runtime animation that manipulates bones, such as IK-ing a character’s feet onto the ground, or his hands onto an object he’s interacting with in the environment such as a button, etc.