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[30];

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 BuildSkinMatrix()
{
mat4 result; // not initialised?
int i;
for (i=0; i<4; i++)
{
result = result + (vWeight[i] * bones [int(vBoneIndex[i])]);
}
return result;
}

void main(void)
{
vec4 vtx;
vec4 nrm;

col = gl_Color;
gl_TexCoord[0] = 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;
}
``````

yooyo

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[3];   // position
float norm[3];  // normal
float tex0[2];	// mapping coordinate
float col[4];   // vertex color
float weights[4];  // weights[i] is in relation with boneindices[i];
float boneindices[4]; // up to four indices in array of mat4 in vertex shader
float tangent[3];  // tangent
float binormal[3]; / binormal
} tChVertex;
``````

yooyo

thanks for the info