Jump to content


HLSL vertex skinning vertex normals


1 reply to this topic

#1 Xcrypt

    New Member

  • Members
  • PipPipPip
  • 144 posts
  • LocationBelgium

Posted 30 April 2012 - 10:52 AM

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?

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5340 posts
  • LocationSanta Clara, CA

Posted 30 April 2012 - 04:41 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users