Hey, I’ve recently began investigating how would I implement hardware skinning. As of yet I don’t have any experience with shaders so I’ll probably missay some things.
I figure if I have a model with it’s skeleton, I only need to pass a shader the transformations regarding the bones. The shader should then apply the transformations to meshes(vertices) that are “assigned” to each bone. How would I achive that the shader only operates on the vertices that belong to a certain bone?
Maybe this code can help:
// additional vertex attributes. max 4 influence
// if vertex have less than 4 influences, then set unused slots to 0.0
attribute vec4 vWeight;
attribute vec4 vBoneIndex;
// max 30 bones. you may increase this number
uniform mat4 bones;
varying vec4 col;
// this function calculate skin matrix based on vertex bone indices and weights
// keep in mind that sum of weights must be 1.0f
mat4 result; // not initialised?
for (i=0; i<4; i++)
result = result + (vWeight[i] * bones [int(vBoneIndex[i])]);
col = gl_Color;
gl_TexCoord = gl_MultiTexCoord0;
mat4 skinmatrix = BuildSkinMatrix();
// skin vertex
vtx = skinmatrix * gl_Vertex;
// skin normal
nrm = skinmatrix * vec4(gl_Normal, 0.0);
// if you need to skin tangents and binormals, do it here
// transform skinned normal
nrm = vec4(gl_NormalMatrix * nrm.xyz, 0.0);
// transorm skinned vertex
gl_Position = gl_ModelViewProjectionMatrix * vtx;
thanks for the code, one more thing though. If I understood the code correctly, you do the transformations on the vertices with a certain bone(id) attribute. I presume one would have to tell the vertex the id of the bone when loading the model . how would I do that?
Instead of keeping list of vertices for each bone, make list of bones for each vertex. You can do this in loading time or during model export.
Here is a example of vertex structure:
typedef struct tagChVertex
float pos; // position
float norm; // normal
float tex0; // mapping coordinate
float col; // vertex color
float weights; // weights[i] is in relation with boneindices[i];
float boneindices; // up to four indices in array of mat4 in vertex shader
float tangent; // tangent
float binormal; / binormal