for( i = 0; i < _numVerts; ++i ) {
Vector3f finalVertex = kZeroVectorf;
Vector3f finalNormal = kZeroVectorf;
// Calculate final vertex to draw with weights
for( int j = 0; j < _verts->countWeight; ++j ) {
const Weight_t *pWeight = _weights[ _verts->startWeight + j ];
const Joint_t *pJoint = skel->getJoint( pWeight->joint );
// Calculate transformed vertex for this weight
Vector3f wv = pWeight->pos;
pJoint->orient.rotate( wv );
// The sum of all pWeight->bias should be 1.0
finalVertex += (pJoint->pos + wv) * pWeight->bias;
Vector3f wn = pWeight->norm;
pJoint->orient.rotate( wn );
finalNormal += wn * pWeight->bias;
}
_vertexArray[0] = finalVertex._x;
_vertexArray[1] = finalVertex._y;
_vertexArray[2] = finalVertex._z;
_normalArray[0] = finalNormal._x;
_normalArray[1] = finalNormal._y;
_normalArray[2] = finalNormal._z;
}
Computing normals for weighted vertices (vertex skinning)
Hello,
I'm wondering how to compute vertex normals when using vertex skinning?
I would like to pre-compute normals from vertex weights in order to get final vertex normals like I get final vertices:
What I want is to compute pWeight->norm, which is the weighted normal associated to a weighted vertex, preferably at loading time.
Perhaps I'm wrong and this is not a good idea... But then I would like to know how to compute these normals without having to rebuild all triangle normals at rendering time, then averaging them for vertices, etc.
Hey V3rt3x,
I think you're going about it the wrong way. You only need to compute the normals for each vertex in its bind pose. When you multiple the normal by the bones final combined transformation it will transform the normal to the correct space.
So just use the models original normals with all the frames original transforms.
I think you're going about it the wrong way. You only need to compute the normals for each vertex in its bind pose. When you multiple the normal by the bones final combined transformation it will transform the normal to the correct space.
So just use the models original normals with all the frames original transforms.
The bind pose? is it that the bind pose?
I'm using the MD5 model format, but vertices have ”multiple positions” stored separately with the weight factor and joint index (in order to get access to quaternion orientation and joint's position).
So if I want to compute normals I need to use a Skeleton because a vertex weights give a position depending on their joint...
I'm completely lost with theses weight positions... In books I have the position is the same but there are multiple transformation matrices (one for each bone). Here we have multiple positions and multiple matrices :(
I'm using the MD5 model format, but vertices have ”multiple positions” stored separately with the weight factor and joint index (in order to get access to quaternion orientation and joint's position).
struct Md5Vertex_t{ float st[2]; // Texture coordinates int startWeight; // Start index weights int countWeight; // Number of weights};struct Md5Weight_t{ int joint; // Joint index float bias; // Weight factor Vector3f pos; Vector3f norm; // what I would like in my dreams (o_o)};
So if I want to compute normals I need to use a Skeleton because a vertex weights give a position depending on their joint...
I'm completely lost with theses weight positions... In books I have the position is the same but there are multiple transformation matrices (one for each bone). Here we have multiple positions and multiple matrices :(
I got the solution at doom3world :-)
http://www.doom3world.org/phpbb2/viewtopic.php?p=100174#100020
Problem solved.
http://www.doom3world.org/phpbb2/viewtopic.php?p=100174#100020
Problem solved.
Well, there are 2 good ways to do it.
You can apply the rotation of the different bones to the normal (not the translation!) and scale by the respective weights, BUT you're not going to have a unit-length normal after this step so you'll need to normalize.
Or, a lot of ps2 games do this:
Just transform the normal by the most heavily weighted bone. If there isn't scaling on the bone (which is true 99% of the time), you don't need to re-normalize the normal, so in many cases this is super cheap to do and there isn't significant visual difference. It's especially easy if you use the convention that the most heavily weighted bone is stored as the first weight/idx.
You can apply the rotation of the different bones to the normal (not the translation!) and scale by the respective weights, BUT you're not going to have a unit-length normal after this step so you'll need to normalize.
Or, a lot of ps2 games do this:
Just transform the normal by the most heavily weighted bone. If there isn't scaling on the bone (which is true 99% of the time), you don't need to re-normalize the normal, so in many cases this is super cheap to do and there isn't significant visual difference. It's especially easy if you use the convention that the most heavily weighted bone is stored as the first weight/idx.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement