Texture baked animations (optimisation)

Problem

During the early development process we decided that we wanted large battles, and needed to animate up to 80 game characters concurrently

  • Each game characters could be unique and animate individually

  • Each character is animated with walk, attack, spawn and death animations, with blending between animation states

We found that in game skinning and animating on CPU cores was too expensive to support 80 game characters.

  • Many low end devices had a limited number of CPU cores

  • Reducing mesh vertex counts improved performance but visual quality compromised

  • We could only afford 20 characters on our low end devices


Solution

We developed an offline process that baked the vertex data into (RGB) animation textures, and we removed the CPU skinning system from the game runtime.

Offline process :

  • The skinned animations were played and vertex data captured

  • Position and normal data stored in the animation texture as keyframes

Then at game runtime :

  • Each character's vertex shader samples the animation texture to retrieve animation keyframes

  • Sample two keyframes at once, then interpolate for actual position and normal values


We found that the GPU cost of reconstructing the vertex data from the animation textures allowed a sufficient vertex budget per character, and allowed us up to 80 concurrent characters on our low end devices.