PDA

View Full Version : Hardware Skinning Shader



the_met
03-10-2011, 11:05 PM
Hi Guys, I've been trying to implement Hardware Skinning for my project, but I'm having trouble in actually animating the object.
Here's my shader code, there shouldn't be any problem in it, but maybe someone can spot something I overlooked so far.

uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform mat3 edgeNormalMatrix;
uniform vec3 vLightDir;

uniform mat4 bones[29];
uniform mat4 mBindPose[29];


attribute vec3 vVertex;
attribute vec3 vNormal;
attribute vec2 vTexCoordAttrib;
//Adding Animation variables
attribute vec4 vWeights;
attribute vec4 vBoneIndices;

varying vec2 vTexCoordVary;
varying vec3 vEyeNormal;
varying vec3 vEdgeNormal;
varying vec3 vEyeLight;

float dot_product(in vec3 first, in vec3 second)
{
return first.x * second.x + first.y * second.y +
first.z * second.z;
}

mat4 orthoNormalInverse( in mat4 Matrix)
{
mat4 temp = Matrix;

//(xx, yx, zx, 0,
//xy, yy, zy, 0,
//xz, yz, zz, 0,
//-(wx * xx + wy * xy + wz * xz),
//-(wx * yx + wy * yy + wz * yz),
//-(wx * zx + wy * zy + wz * zz), 1);

vec3 wAxis = vec3(Matrix[0][3], Matrix[1][3], Matrix[2][3]);
vec3 xAxis = vec3(Matrix[0][0], Matrix[1][0], Matrix[2][0]);
vec3 yAxis = vec3(Matrix[0][1], Matrix[1][1], Matrix[2][1]);
vec3 zAxis = vec3(Matrix[0][2], Matrix[1][2], Matrix[2][2]);

//wx
//wy
//wz
temp[3][0] = -dot_product(wAxis, xAxis);
temp[3][1] = -dot_product(wAxis, yAxis);
temp[3][2] = -dot_product(wAxis, zAxis);
temp[3][3] = 1.0;

return temp;
}

vec3 VectorByMatrixMult(in vec3 Vector, in mat4 Matrix)
{
vec3 outVec;
outVec.x = Vector.x * Matrix[0][0] + Vector.y * Matrix[0][1] + Vector.z * Matrix[0][2] + Matrix[0][3];
outVec.y = Vector.x * Matrix[1][0] + Vector.y * Matrix[1][1] + Vector.z * Matrix[1][2] + Matrix[1][3];
outVec.z = Vector.x * Matrix[2][0] + Vector.y * Matrix[2][1] + Vector.z * Matrix[2][2] + Matrix[2][3];
return outVec;
}

void main(void)
{
float fWeightW = 1.0 - (vWeights.x + vWeights.y + vWeights.z);
float fWeights[4] = {vWeights.x, vWeights.y, vWeights.z, fWeightW};
vec3 pos = vec3(0.0, 0.0, 0.0);
vec3 toModify = vVertex;

for(int i = 0; i < 4; i++)
{
//Getting the inverse of the BindPose that was passed in
mat4 bindPoseInv;
mat4 currPose;

int nCurrBoneInd = int(vBoneIndices[i]);
currPose = bones[nCurrBoneInd];
bindPoseInv = orthoNormalInverse(mBindPose[nCurrBoneInd]);

vec3 BindTimesVert = VectorByMatrixMult(toModify, bindPoseInv);
vec3 CurrentTimesBindTimesVert = VectorByMatrixMult(BindTimesVert, currPose);
CurrentTimesBindTimesVert = CurrentTimesBindTimesVert * fWeights[i];
pos += CurrentTimesBindTimesVert;

}
//pass tex coords to the fragment program
vTexCoordVary = vTexCoordAttrib;

//calculate normal
vEyeNormal = normalMatrix * vNormal;
vEyeNormal = normalize(vEyeNormal);

vEyeLight = vLightDir;
vEyeLight = normalize(vEyeLight);

vEdgeNormal = (edgeNormalMatrix * vNormal);
vEdgeNormal = normalize(vEdgeNormal);


gl_Position = mvpMatrix * vec4(pos, 1.0);

}

And this is the render call (there's other stuff but this is the specific animation information binding):


int bones = -1;
bones =
glGetUniformLocation(CShaderManager::GetInstance() .GetShader(m_RenderTechnique->GetShaderHandle()), "bones");
glUniformMatrix4fv(bones, 29, GL_FALSE, (const GLfloat*)&amp;currPose[0]);

int bindPose = -1;
bindPose =
glGetUniformLocation(CShaderManager::GetInstance() .GetShader(m_RenderTechnique->GetShaderHandle()), "mBindPose");
glUniformMatrix4fv(bindPose, 29, GL_FALSE, (const GLfloat*)&amp;m_vShaderBindPose[0]);


glVertexAttribPointer(GL_ATTRIBUTE_VERTEX,3,GL_FLO AT,GL_FALSE,0,&amp;m_vVertices[0]);



//Bind to the normal data on the GPU
glVertexAttribPointer(GL_ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, &amp;m_vNormals[0]);

//Bind to the Texture Coordinates on the GPU
glVertexAttribPointer(GL_ATTRIBUTE_TEXTURE0, 2, GL_FLOAT, GL_FALSE, 0, &amp;vTexCoords[0]);

if(uiShaderHandle == SHADER_HARDWARE_SKINNING)
{
glVertexAttribPointer(GL_ATTRIBUTE_WEIGHTS, 4, GL_FLOAT, GL_FALSE, 0, &amp;m_vShaderWeights[0]);
glVertexAttribPointer(GL_ATTRIBUTE_INDICES, 4, GL_FLOAT, GL_FALSE, 0, &amp;m_vShaderIndices[0]);
}


THank you for your time