Animation brings 3D scenes to life, turning static models into characters. In web-based 3D, animation is much more than just playing back keyframes. It involves careful management of geometry updates, skinning computations and blending logic to maintain smooth performance. Modern engines like Three.js and Babylon.js support several systems for this, primarily through the glTF format. Each of these systems comes with distinct costs and use cases so it is important for developers to know about them.
Animation Techniques
Skeletal Animation
The most common technique for character animation is skeletal animation, also known as skinning. Here, a model is bound to an armature of bones that define how parts of the mesh move relative to one another. Each vertex is assigned to one or more bones with a weight totaling a value of 1.0 per vertex. When the skeleton is posed, for example by rotating an arm bone, the vertex positions are computed by blending the transforms from all influencing bones according to their set weights. This skinning can happen on the CPU or GPU, although GPU is preferred for web as it can be very performance heavy.
In practice, skeletal animation performs well for characters or articulated objects, but the cost scales with vertex count and bone influence count. A character with 10.000 vertices skinned to 4 bones per vertex is manageable, but with 50.000 vertices and 8 influencing bones, it can lead to a strain on mobile GPUs. Engines mitigate this by limiting influence counts during exports and reusing skeletal data whenever possible.
Morph Target
For deformations that do not fit a skeletal rig, such as organic shape changes or a muscle flexing, morph target animation is ideal. Morph target animation, also known as blend shapes, store multiple vertex position sets representing different shapes of the same topology. An example for facial animations would be a blend shape for a neutral face, one for a smile and one with an angry frown. Animation is then achieved by blending between these morph targets. This is computationally simpler than skinning as it is just a weighted sum of vertex positions with no hierarchy involved.
Morph targets shine for localized deformations but become expensive with a high vertex count, since every target must be stored in memory and blended per vertex. They are perfect for faces or props like inflating balloons, but less suited for full body animation. In glTF exports from Blender, shape keys become morph targets and Three.js can load them directly for playback.
The Cost of Animation
Both of these two systems rely on keyframe data. Animation clips store tracks of changes, such as rotations and influences, sampled at specific points in time. Playing back these poses involves interpolation between keyframes using mathematical curves. The performance cost is generated by updating the skeleton or morph influences every frame and re-skinning the mesh. For smoother playback, engines like Three.js use an “AnimationMixer” that handles time scaling, looping and pausing. Another way to increase performance is to reduce the keyframe density during exports to cut down memory.
Optimizing animations for the web emphasizes reuse and simplification. Reusing rigs and skeletons across characters, baking simple animations to morph targets or to geometry if they do not need blending. Update rates can also be adjusted to increase performance based on the importance of the animation. Similar to LODs, animation can be reduced when it becomes less important or further away, switching from a 60Hz to a 30Hz update rate at higher distances.
Interactivity
Interactive animation adds a whole new world of challenges such as physics integration or procedural posing / animations. Full inverse kinematics for example are very expensive compared to simple bone manipulations via uniforms. Physics based interactive animations such as cloth simulations are so performance heavy that they should only be used for key objects of a scene.
SOURCES
1: https://github.com/akash-coded/mern/discussions/217
2: https://www.tutorialspoint.com/babylonjs/babylonjs_animations.htm
3: https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons
4: https://firxworx.com/blog/code/creating-an-animated-3d-ecard-using-webgl-react-three-fiber-gltf-models-with-animations/
5: https://dev.to/derrickrichard/unlocking-the-web-in-3d-an-introduction-to-threejs-57dn