Skeletal Animation: Difference between revisions
No edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
This document will talk about doing skeletal based animation but it will be brief since the subject is complex and there are also other sources (websites and books and demoes at http://developer.nvidia.com in the SDK and individual downloads).<br> | This document will talk about doing skeletal based animation but it will be brief since the subject is complex and there are also other sources (websites and books and demoes at http://developer.nvidia.com in the SDK and individual downloads, http://gpwiki.org/index.php/OpenGL:Tutorials:Basic_Bones_System).<br> | ||
You would need to model the object or human or animal in the software of your choice and export it in the file format of your choice.<br> | You would need to model the object or human or animal in the software of your choice and export it in the file format of your choice.<br> | ||
<br> | <br> |
Revision as of 06:24, 9 January 2009
This document will talk about doing skeletal based animation but it will be brief since the subject is complex and there are also other sources (websites and books and demoes at http://developer.nvidia.com in the SDK and individual downloads, http://gpwiki.org/index.php/OpenGL:Tutorials:Basic_Bones_System).
You would need to model the object or human or animal in the software of your choice and export it in the file format of your choice.
Here is a description of one way to do it :
1. Your object will be in a default pose.
2. All the vertices are in their respective places.
3. You have an array of bones.
3. You have an array of offsets.
4. What's a bone? It is a rotation matrix. You only need a 3x3 matrix.
5. What's an offset? It is a XYZ value you use to translate your vertex.
6. A bone and its offset together make a 4x4 matrix.
7. Each vertex can have a certain amount of bones that influence it. 0, 1, 2, ...you name it!
8. For each bone that influences your vertex, you need to decide how much it influences. This is called a weight or blend factor. 1 weight per bone/offset matrix
9. In order to animate your object, you need to change the bones and offset matrix. Normally, you would not change the weights.
Let's assume our entire model will have 10 bones. Let's assume each vertex will have 2 bones.
So your vertex structure would look something like this :
struct MyVertex { float x, y, z; //Vertex float nx, ny, nz; //Normal float s0, t0; //Texcoord float index0, index1; //Index into the bone/offset matrix array float weight0, weight1; //The blend factor for each bone/offset matrix };
You would be boning your vertex and normals. The texcoords just pass through.
If you have tangent vectors, you would bone them as well.
Warning : notice that each bone matrix will consume a lot of register space on the GPU. Each matrix takes 4 registers.
Instead of uploading a mat4 for each bone, upload a pair of quaternion and offset. A quat uses a vec4 and offset uses a vec4.
As a result, you'll cut the register need of your shader in half.
Of course, your would have to convert them to a mat4 in your shader which will cost you a few clock cycles.
Here, we'll use a mat4 matrix.
//[Vertex Shader] attribute vec4 Vertex; attribute vec3 Normal; attribute vec2 TexCoord; attribute vec2 Index; attribute vec2 Weight; uniform mat4 ModelviewMatrix; uniform mat4 ProjectionModelviewMatrix; uniform mat4 Bone[10]; //Array of bones that you compute (animate) on the CPU and you upload to the shader //----------------------- varying vec2 TexCoord0; varying vec3 EyeNormal; //----------------------- void main() { vec4 newVertex; vec4 newNormal; int index; //----------------------- index=int(Index.x); //Cast to int newVertex = (Bone[index] * Vertex) * Weight.x; newNormal = (Bone[index] * vec4(Normal, 0.0)) * Weight.x; index=int(Index.y); //Cast to int newVertex = (Bone[index] * Vertex) * Weight.y + newVertex; newNormal = (Bone[index] * vec4(Normal, 0.0)) * Weight.y + newNormal; EyeNormal = vec3(ModelviewMatrix * newNormal); gl_Position = ProjectionModelviewMatrix * newVertex; TexCoord0 = TexCoord; }