GPU Skinning

#1 Load Skeletal Animation File

We need to implement Skeletal Animation first.

First, load .anim file with Assimp. If this done correctly, we can get data structure like this

As we get this data, we need to parse this datas into structure.

Each vertex affects by multiple bones with weighted factor, we need to specify those datas.

This is Animation Vertex Data

Position : 3D Position

Texture Coordinate : Texture Coordinates

Normal : Normal Direction

BoneID 0~3 : Indices of Affecting Bones

Weight 0~3 : Affection Strength

With these datas, we can Interpolate position of each vertices per time frame.

.Anim file included frame data, which means how bones moving in several frames, we need to interpolate vertex position by bone’s transformation data

#2 Interpolation

Each animation frame store every bone’s transformation datas by time factor. We should get transformation matrix by putting time value.

Using Linear Interpolation for translation / scaling factors, Spherical Linear Interpolation for rotation factor.

Put these transformation datas together into 4x4 matrix, now we have bone transformation.

We stored which bone affecting which vertex, and how much they affected, using Bone transformation, we can calculate vertex’s position by time.

Using this transformation, we can get animation object!

#3 GPU Skinning

Skeletal Animation implemented, but done in CPU, for drawing massive animating objects, it’s too slow.

Because transformation datas stored hierarchically like our body

Head -> Neck -> Spine -> Pelvis

Like this example, for getting right finger’s transformation data, we need to compute & accumulate transformation in this order

Right Finger Transformation * Arm Right Transformation * Uparm Right Transformation * Neck Transformation * Head transformation

And this interpolation & multiplication costs us a lot, so I moved this calculations to GPU

We need to put all animation datas like, All NodeTransforms, Hierarchical Orders of Nodes, translation keys, scaling keys, rotation keys, offset matrices in order to get proper transformation.

First, we need to get node transform, if it is animated node, it needs interpolation else, use default node’s transformation

Get Node Transform

Interpolation

Every frame have timestamp, we can get interpolated time value between 2 frames timestamp. And use this interpolated timestamp, we can interpolate between translation, rotation, scaling factors

Get Parent Matrix

Then, we need to get parent matrix of this node, we pass hierarchical order to GPU.

Read parent transformation in that order, and accumulate to current node transformation

Out Final Matrix

Almost done! Just check if this node needs offset calculation and store to out buffer.

And apply this bone transformations data to each verex

Looks Good!

But purpose of this technique is to simulate many animations! Let’s draw several kinds of animations!

Good!