GLSL hardware skinning

Started by
7 comments, last by oc2k1 16 years, 1 month ago
Hello - im trying to do a hardware skinning vertex shader. I will try to explain to you the best i can the problem im facing. Here is how i do my rendering of the character glInterleavedArrays( GL_V3F, 0, pObject->pVerts); glDrawElements( GL_TRIANGLES, pObject->numOfFaces*3, GL_UNSIGNED_INT, &indic[0]); now.. i have the bones and weight put in a structure. Im interested if theres a way in the glsl to get the current vertex index and with that index to do something like this: vec4 qRotation1 = m_boneInfo[currentFrame].pBoneMatrices[boneIndex].qRotation; vec3 vTranslation1 = m_boneInfo[currentFrame].pBoneMatrices[boneIndex].vTranslation; vec4 qRotation2 = m_boneInfo[nextFrame].pBoneMatrices[boneIndex].qRotation; vec3 vTranslation2 = m_boneInfo[nextFrame].pBoneMatrices[boneIndex].vTranslation; im also facing the problem of not beeing able to pass all my data to the shader .. all my bone and weight info becouse of the glsl limitation of uniform variables (512 - i think is the maximum) so if someone can help me explain what the best method of doing hardware skinning or point me to some tutorial i will much apreciated. Thanks alot :)
Advertisement
the 512 are the minimum that have to be supported. and that are vec4, That is enough for up to 64 matrices. Because some of them are required for other uniforms up to 60 bones are realistic...

A small tutorial with shader code:
http://lumina.sourceforge.net/Tutorials/Armature.html
I just found out in one of my recent posts that you can find arbitrary buffers for each vertex. So instead of passing as a uniform, you pass it as regular vertex data.

I don't know why you want the index or what you are trying to do with it.

What I do in my app is pass a matrix for each bone and I compute those on the cpu. It looks like you have your matrices hardcoded in GLSL or something:

"_boneInfo[currentFrame]."

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

Quote:Original post by guvidu

glInterleavedArrays( GL_V3F, 0, pObject->pVerts);
glDrawElements( GL_TRIANGLES, pObject->numOfFaces*3, GL_UNSIGNED_INT, &indic[0]);


I suggest that you not use glInterleavedArrays as it can be considered depricated. Just use glVertexPointer and the other gl***Pointer functions to "make interlaced arrays".
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
i have my matrices computed at initialization on the cpu - then after i compute them i pass them to the shader in a struct.

struct BonesMatrices{	vec3 vTranslation;	vec4 qRotation;};struct BoneInfo{	int numBones;	BonesMatrices pBoneMatrices[NUM_OF_BONES]; //de numarul de BONES};struct WeightInfo{	int numBlendLinks;	vec2 WeightInfo[NUM_OF_BLENDLINKS]; //un numar mai mare ca numarul maxim de numBlendLinks;};//astea le dau in renderuniform int currentFrame; uniform int nextFrame;uniform float timp;//toate astea le dau la initializareuniform WeightInfo m_weightInfo[WEIGHT_INFO]; //de numarul de vertexi; uniform BoneInfo m_boneInfo[BONE_INFO]; 	// de numarul de frame-uri;uniform vec3 vertInfo[NUM_OF_VERTS];



after that at rendering i pass currentFrame, nextFrame and time. I just need the index to know wich matrix influence the current vertex. Like i said i dont know if this is the best solution or if it is a solution.

thanks
I use glEnableVertexAttribArray and glVertexAttribPointer for the bone and weigth information.

example shader with one bone and no weigth:

attribute int mBone;
uniform mat4 mMatrix[20];

void main()
{
gl_FrontColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * mMatrix[mBone] *gl_Vertex;
}

Thanks - this could be usefull - i will try it and post my resolts
Correct me if i'm wrong. But from what i make of it, you are passing all the bones for all the frames?

Well obviously you wont have sufficient registers to store all your keyframes at once. This is how i do it,

CPU
find currentTime
find 2 keyframes which "surround" currentTime
based on these 2 keyframes find interpolation value = IV
calculate interpolated matrices for bones for the model
submit interpolated matrices as uniforms(1 matrice per bone)
submit [boneNum1,boneNum2,boneNum3,boneNum4],[weight1, weight2,weight3,weight4] as vertex attributes for every vertex (For efficiency i store this in a VBO since it doesnt change)

GPU
gl_Position = gl_ModelViewProjectionMatrix* bone[ boneNum1 ] * weight1 * gl_Vertex;


Clicky for demo
structs aren allowed as uniforms. Use two arrays for quaternions and positions. But for beginning it's recommend to use an array of mat4....

This topic is closed to new replies.

Advertisement