5 min read
On this page

Animation

Overview

Animation in computer graphics brings scenes to life by defining how objects, characters, and effects change over time. Techniques range from simple keyframe interpolation to complex physics simulations, each suited to different levels of realism and control.

Keyframe Animation

Principle

Define poses (key values) at specific times. The system interpolates between them to produce smooth motion.

Time:    0.0    0.5    1.0    1.5    2.0
Value:   0      30     60     45     0      (e.g., rotation in degrees)

Linear Interpolation (Lerp)

v(t) = (1 - alpha) * v0 + alpha * v1,    alpha = (t - t0) / (t1 - t0)

Simple but produces abrupt changes at keyframes (C0 continuity only).

Interpolation Curves

Bezier Curves

Defined by control points. A cubic Bezier uses 4 points (P0, P1, P2, P3):

B(t) = (1-t)^3 * P0 + 3(1-t)^2 * t * P1 + 3(1-t) * t^2 * P2 + t^3 * P3

Properties:

  • Passes through P0 and P3 (endpoints)
  • Tangent at P0 is toward P1; tangent at P3 is from P2
  • Lies within the convex hull of control points
  • Affine invariant

Animators control easing by adjusting the interior control points (ease-in, ease-out, overshoot).

Catmull-Rom Splines

Interpolating spline that passes through all control points. Given points P_{i-1}, P_i, P_{i+1}, P_{i+2}:

q(t) = 0.5 * [(2*P_i) +
               (-P_{i-1} + P_{i+1}) * t +
               (2*P_{i-1} - 5*P_i + 4*P_{i+1} - P_{i+2}) * t^2 +
               (-P_{i-1} + 3*P_i - 3*P_{i+1} + P_{i+2}) * t^3]

C1 continuous. Tangent at each point is derived from neighbors: T_i = 0.5 * (P_{i+1} - P_{i-1}).

Widely used for camera paths and animation curves due to intuitive control (points lie on the curve).

Hermite Splines

Defined by positions and tangents at each endpoint. Cubic Hermite basis:

h(t) = h00*p0 + h10*m0 + h01*p1 + h11*m1

h00 = 2t^3 - 3t^2 + 1
h10 = t^3 - 2t^2 + t
h01 = -2t^3 + 3t^2
h11 = t^3 - t^2

Catmull-Rom is a special case of Hermite interpolation with specific tangent computation.

Rotation Interpolation

Euler Angles

Represent rotation as three angles (roll, pitch, yaw). Simple but suffers from:

  • Gimbal lock: Loss of one degree of freedom when two axes align
  • Interpolation artifacts: Lerping Euler angles produces unexpected paths

Quaternions

Rotation represented as q = (w, x, y, z) = w + xi + yj + zk, where |q| = 1.

A rotation of angle theta about unit axis a:

q = (cos(theta/2), sin(theta/2) * a)

Rotating a point p: p' = q * p * q^(-1) (where p is embedded as a pure quaternion).

Advantages: compact (4 floats), no gimbal lock, smooth interpolation, easy composition (multiplication).

SLERP (Spherical Linear Interpolation)

Interpolates along the shortest arc on the unit quaternion sphere:

slerp(q0, q1, t) = q0 * sin((1-t)*theta) / sin(theta) + q1 * sin(t*theta) / sin(theta)

Where theta = acos(q0 . q1). If q0 . q1 < 0, negate one quaternion to take the short path.

Constant angular velocity (unlike lerp followed by normalization, which varies speed).

SQUAD (Spherical Cubic Interpolation)

For smooth interpolation through multiple rotations (analogous to cubic splines):

squad(q_i, q_{i+1}, s_i, s_{i+1}, t) = slerp(slerp(q_i, q_{i+1}, t), slerp(s_i, s_{i+1}, t), 2t(1-t))

Where s_i are intermediate control quaternions computed from neighboring keyframes.

Skeletal Animation

Skeleton Hierarchy

A skeleton is a tree of joints (bones). Each joint stores a local transform relative to its parent:

Joint 0 (root): T_local_0
  Joint 1 (spine): T_local_1
    Joint 2 (shoulder): T_local_2
      Joint 3 (elbow): T_local_3

World transform of joint j: T_world_j = T_world_parent * T_local_j (recursive chain).

Skinning

Each vertex is associated with one or more joints via weights. The vertex position is computed from the joint transforms.

Bind pose matrix B_j: The world transform of joint j in the rest pose. Inverse bind matrix: B_j^(-1) transforms a vertex from model space to joint-local space.

Linear Blend Skinning (LBS)

The most common skinning method:

v' = sum_{j} w_j * (T_world_j * B_j^(-1)) * v

Where w_j are the blend weights (sum to 1, typically 4 per vertex max).

Artifacts: Produces the "candy wrapper" effect at twisted joints and volume loss at bent joints (elbows, shoulders). This is because linearly blending matrices does not preserve rigidity.

Dual Quaternion Skinning (DQS)

Represents joint transforms as dual quaternions and blends them:

dq = sum_{j} w_j * dq_j        // weighted sum of dual quaternions
dq = dq / |dq|                  // normalize
v' = transform(dq, v)

A dual quaternion encodes both rotation (quaternion) and translation:

dq = q_real + epsilon * q_dual
q_real = rotation quaternion
q_dual = 0.5 * t * q_real       (where t is the translation quaternion)

Advantages over LBS: preserves volume, eliminates candy-wrapper artifacts. Slightly more expensive but widely adopted in games.

Animation Blending

Combine multiple animations (e.g., walk + wave):

  • Lerp blending: Interpolate bone transforms between two animations
  • Additive blending: Add a delta animation on top of a base pose
  • Blend trees: Parameterized blending (e.g., walk speed controls blend between walk/run)
  • Animation state machines: Transitions between states with crossfade durations

Inverse Kinematics (IK)

Given a target position for an end-effector (e.g., hand, foot), compute the joint angles that achieve it. The inverse of forward kinematics.

Cyclic Coordinate Descent (CCD)

Iterative method that adjusts one joint at a time, from the end-effector toward the root:

for each iteration:
    for j = end_effector_parent down to root:
        v_to_end = end_effector_pos - joint[j].pos
        v_to_target = target_pos - joint[j].pos
        rotation = rotation_from_to(v_to_end, v_to_target)
        joint[j].rotation *= rotation
        apply constraints (angle limits)

Converges quickly but can produce unnatural poses. Joint angle constraints help.

FABRIK (Forward And Backward Reaching IK)

Operates on joint positions rather than angles. Two passes per iteration:

Forward pass (end-effector to root):

  1. Move end-effector to target
  2. For each joint from end toward root: place it at distance d (bone length) from the next joint toward the target chain

Backward pass (root to end-effector):

  1. Move root back to its fixed position
  2. For each joint from root toward end: place it at distance d from the previous joint
Converges in very few iterations. Natural-looking results.
Easily handles multiple end-effectors and constraints.

Physics-Based Animation

Rigid Body Dynamics

Objects with mass but no deformation. State: position, orientation, linear velocity, angular velocity.

F = m * a                          // Newton's second law
tau = I * alpha                    // Torque and angular acceleration
I = R * I_body * R^T              // World-space inertia tensor

Integration (semi-implicit Euler):
v(t+dt) = v(t) + (F/m) * dt
x(t+dt) = x(t) + v(t+dt) * dt

Collision detection: broad phase (spatial hashing, BVH) then narrow phase (GJK, SAT). Contact resolution via impulse-based or constraint-based solvers.

Soft Body / Deformable Bodies

  • Mass-spring systems: Particles connected by springs (Hooke's law). Simple but hard to tune and not volume-preserving.
  • Finite Element Method (FEM): Discretize continuum mechanics equations on a tetrahedral mesh. Physically accurate but expensive.
  • Position-Based Dynamics (PBD): Directly manipulate positions to satisfy constraints. Stable, fast, controllable. Used in many game engines.

Cloth Simulation

Modeled as a mesh of particles with structural, shear, and bending springs (or PBD constraints).

Key forces: gravity, wind, spring/constraint forces, collision response.

For each timestep:
    Apply external forces (gravity, wind)
    Integrate velocities and positions
    Solve constraints (distance, bending, collision) iteratively
    Update velocities from position changes

Self-collision detection is expensive; spatial hashing or BVH on cloth triangles.

Fluid Simulation

  • Eulerian (grid-based): Solve Navier-Stokes on a fixed grid. Steps: advection, diffusion, pressure solve (Poisson equation), projection.
  • Lagrangian (particle-based): SPH (Smoothed Particle Hydrodynamics) or FLIP/PIC. Particles carry fluid properties, kernel-weighted interactions.
  • Hybrid: FLIP/APIC combine particles (advection) with a grid (pressure solve). State of the art for liquid simulation.

Surface extraction: marching cubes on a level set or particle-based surface reconstruction.

Particle Systems

Emit, simulate, and render large numbers of small elements (sparks, smoke, rain, fire).

Lifecycle

for each frame:
    Emit new particles (position, velocity, lifetime, color, size)
    Update existing particles:
        apply forces (gravity, wind, turbulence)
        integrate position
        age += dt
        if age > lifetime: remove
    Sort (for transparency) and render (billboards, trails, meshes)

GPU Particle Systems

  • Store particles in GPU buffers
  • Compute shader updates positions and emits/kills particles
  • Indirect draw for variable particle count
  • Millions of particles at interactive rates

Rendering Techniques

  • Billboards: Camera-facing quads with a sprite texture
  • Ribbon/trail: Connect sequential positions into a strip
  • Mesh particles: Instance a mesh per particle
  • Volumetric: Splat particles into a 3D texture, ray-march for smoke/fog