Limiting the shader

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