Skeletal Skinning With Quaternion (OpenGL)

This topic is 1114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello, I've been struggling with this for a month. I did skeletal animation in deprecated way and I wanna move on with Shader, how to do this with shader?

The skeleton has 3 axis angles (x,y,z) and 3 positions, here is the way I did:

1. Built joint transformation matrices

2. Get the rotation between 2 axis rotations & positions

3. Set those rotations to matrix and store the positions in matrix

4. SLERP the quaternion

5. Convert the slerp output quaternion to Matrix 4x4

6. Multiply the matrix with pre built joint transformation matrix

7. Multiply the child matrix with parent matrix

The problems when I convert these to shader are, instead of sending the bone matrices to shader, I convert the multiplied child & parent matrix to quaternion and send it to shader and convert them again to matrix in GPU then multiply it with the vertices & weight. However, to get the vertices going, I have to send the pre built matrices which I don't want to. Is there any method to transform the vertex without sending the pre built transformation matrices? What is the correct step of interpolating the joints? I don't want to send matrices but quaternion instead.

Thank you.

for (int i = 0; i < pMesh[mesh].VertNum; ++i)
{
memcpy(pOut[i].Pos, pMesh[mesh].pVertex[i].Pos, sizeof (Vertex));

float tmp[3], vert[3];
// mGlobalSkeleton & mGlobal must have to be sent to the GPU too in order to make the vertices work
VectorITransform(pMesh[mesh].pVertex[i].Pos, pAnim.pBones[pMesh[mesh].pVertex[i].BoneID].mGlobalSkeleton, tmp);
VectorTransform(tmp, pAnim.pBones[pMesh[mesh].pVertex[i].BoneID].mGlobal, vert);

pOut[i].Pos[0] = vert[0] * 1.0;
pOut[i].Pos[1] = vert[1] * 1.0;
pOut[i].Pos[2] = vert[2] * 1.0;
}

#version 400 compatibility

in vec3 vPosition;
in vec2 vTexCoord;
in vec3 vNormal;
in ivec4 vIndex;

uniform mat2x4 mQuat[100];

mat4 Quaternion_ToMatrix(in mat2x4 mIn)
{
float sqw = mIn[0][0]*mIn[0][0];
float sqx = mIn[0][1]*mIn[0][1];
float sqy = mIn[0][2]*mIn[0][2];
float sqz = mIn[0][3]*mIn[0][3];

// invs (inverse square length) is only required if quaternion is not already normalised
float fInv = 1.0 / (sqx + sqy + sqz + sqw);

mat4x4 mOut;

mOut[0][0] = (sqx - sqy - sqz + sqw) * fInv; // since sqw + sqx + sqy + sqz =1/invs*invs
mOut[1][1] = (-sqx + sqy - sqz + sqw) * fInv;
mOut[2][2] = (-sqx - sqy + sqz + sqw) * fInv;

mOut[1][0] = 2.0 * (mIn[0][1]*mIn[0][2] + mIn[0][3]*mIn[0][0]) * fInv;
mOut[0][1] = 2.0 * (mIn[0][1]*mIn[0][2] - mIn[0][3]*mIn[0][0]) * fInv;

mOut[2][0] = 2.0 * (mIn[0][1]*mIn[0][3] - mIn[0][2]*mIn[0][0]) * fInv;
mOut[0][2] = 2.0 * (mIn[0][1]*mIn[0][3] + mIn[0][2]*mIn[0][0]) * fInv;

mOut[2][1] = 2.0 * (mIn[0][2]*mIn[0][3] + mIn[0][1]*mIn[0][0]) * fInv;
mOut[1][2] = 2.0 * (mIn[0][2]*mIn[0][3] - mIn[0][1]*mIn[0][0]) * fInv;

mOut[3][0] = 0.0;
mOut[3][1] = 0.0;
mOut[3][2] = 0.0;

mOut[0][3] = mIn[1][0];
mOut[1][3] = mIn[1][1];
mOut[2][3] = mIn[1][2];
mOut[3][3] = mIn[1][3];

return mOut;
}
mat2x4 mTemp;
void main()
{
mat4 mMat = Quaternion_ToMatrix(mQuat[vIndex.x]);

vec4 vVertex = mMat * vec4(vPosition, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * vVertex;
}

1. 1
2. 2
Rutin
20
3. 3
4. 4
A4L
15
5. 5
khawk
14

• 13
• 26
• 10
• 11
• 9
• Forum Statistics

• Total Topics
633737
• Total Posts
3013614
×