Last update: 2 September 2015

Tutorial 3: Gpu Skinning

This tutorial shows how to achieve skinning on the GPU using the vertex programmable pipeline to offload the CPU.  Assimp is used to import the animated model. an animated model is composed of a mesh bound to an articulated skeleton. Skeleton is composed of hieararchy of bones , each bone is represented by a trasformation matrix. Each vertex position is affected by N bones. We store the indices of influenced bones and their corresponding weight in per vertex attribute. In the vertex shader we calculate the final vertex position by doing an additive blending of different bones contributions. For eg: a vertex 'vert' is influenced by 'bone0' with 'weight0'  and 'bone1' with 'weight1'. The final position of 'vert' is calculated as follow:

vert.finalpos = weight0 * (bone0.matrix * vert.pos) + weight1 * (bone1.matrix * vert.pos);

Code walkthrough

In the vertex shader, we find the the transfromation matrices for the influenced bones on the current vertex with their corresponding weight as follow:

 //skinningMatrix holds the transformation matrices for all bones, and bones.x/y/z/w holds the indices of the bones that affect the vertex 
    vec4 p0 = skinningMatrix[ int(bones.x) ] * position;
    vec4 p1 = skinningMatrix[ int(bones.y) ] * position;
    vec4 p2 = skinningMatrix[ int(bones.z) ] * position;
    vec4 p3 = skinningMatrix[ int(bones.w) ] * position;

The final position of the vertex is the sum of the four vertices each multiplied by the bone weight. ( sum of bone weights should is equal to 1):

    //blend position 
    vec4 interpolatedPosition = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;