Processing math: 100%

Skinning

The process of attaching the vertices of a 3D mesh to a posed skeleton is known as "Skinning".

Each vertex can be bound to one or more joints.

The vertex's positions is a weighted average of the positions it would have assumed if it had been bound to each joint independently.

At each vertex, you ned to have the following information:

  • The index or indices of the Joints to which it is bound,
  • The weighting factor describing how much influence that joint should have on the final vertex position.
#![allow(unused)] fn main() { struct SkinnedVertex { position: Vector3, normal: Vector3, texture_coordinates: Vector2, joint_indices: [u8; 4], // max of 4 joints joint_weight: [u8; 3], // you don't need 4 weights since the last can be calculated on the fly. } }

Tracking mesh vertices to joints

A skinning matrix is a matrix that can transform the vertices of a mesh from bind pose into new positions that correspond to the current pose of the skeleton.

The position of a skinned vertex is specified in model space, like all mesh vertices.

Unlike other matrix transforms, a skinning matrix is NOT a change of basis transform: it goes from model space (bind pose) to model space (actual pose)

Given the bind pose of the joint j in model space, BjM, this matrix transforms a point whose coordinates expressed in j's space into an equivalent set of model-space coordinates.

Then, given a vertex whose coordinates are expressed in model-space, if you want to express it in joint-space, you can do so with the inverse of the above bind pose matrix.

vj=vBMBMj=vBM(BjM)1

Given a joint's current pose, similar to the bind pose matrix, it defines vertices in joint space in model space, i.e., CjM.

vCM=vjCjM=vBM(BjM>)1CjM=vBMKj

Where

  • Kj=vBM(BjM>)1CjM
  • This Kj is known as the skinning matrix.

When you have multiple joints, it can be useful to create an array of skinning matrices Kj for every joint.

BjM matrices never change so can be calculated once per vertex. The current poses CjM change on each frame and will therefore need to be calculated on the fly.

Don't forget that a single matrix from joint space to model space represents a global pose, meaning for a given joint, you have to walk up its local pose matrices to the root joint to create either BjM or CjM.

When multiple joints per vertex are involved

Calculate a new vector for each joint individually, then average all the vectors together.

vCM=N1i=0wivBMKji

Where

  • N is the number of joints associated with vertex v.
  • wi is the weighting factor of joint i.
  • Kji is the skinning matrix for joint ji.