Bezier Curves and Splines for Games

Updated July 2026
Bezier curves define smooth, curved paths using a small number of control points, and they appear everywhere in game development: projectile arcs, camera rails, enemy patrol routes, road generation, particle trajectories, and UI animation curves. The math is built entirely on linear interpolation (lerp), which means that if you understand lerp, you already understand the building block of every bezier curve. Splines chain multiple curve segments together for longer, more complex paths.

Quadratic Bezier Curves

A quadratic bezier curve uses three control points: P0 (start), P1 (control), and P2 (end). The curve starts at P0, bends toward P1 without actually touching it, and ends at P2. The parameter t moves from 0 to 1 along the curve. At t=0, the curve is at P0. At t=1, the curve is at P2. At t=0.5, the curve is roughly nearest to P1.

The formula uses nested lerps. First, lerp between P0 and P1 at parameter t to get an intermediate point A. Then, lerp between P1 and P2 at parameter t to get intermediate point B. Finally, lerp between A and B at parameter t to get the curve point. In code: var ax = lerp(P0.x, P1.x, t); var ay = lerp(P0.y, P1.y, t); var bx = lerp(P1.x, P2.x, t); var by = lerp(P1.y, P2.y, t); var cx = lerp(ax, bx, t); var cy = lerp(ay, by, t);

The equivalent polynomial form is B(t) = (1-t)^2 * P0 + 2*(1-t)*t * P1 + t^2 * P2. This produces identical results and is slightly faster to compute because it avoids the intermediate lerp values. Use the polynomial form in performance-critical code and the nested lerp form for understanding and teaching.

Quadratic bezier curves produce smooth parabolic arcs. They are ideal for simple projectile arcs (throw a grenade in a parabolic path), jump trajectories (non-physics-based arcs), and gentle curved transitions. The limitation is that quadratic curves can only produce simple arcs, not S-shapes or complex curves. For more complex shapes, use cubic bezier curves.

Cubic Bezier Curves

A cubic bezier curve uses four control points: P0 (start), P1 (first control), P2 (second control), and P3 (end). The curve starts at P0, is pulled toward P1 and P2, and ends at P3. Having two control points instead of one allows S-curves, sharper bends, and more complex shapes. The nested lerp construction adds one more level: three initial lerps, two intermediate lerps, and one final lerp.

The polynomial form is B(t) = (1-t)^3 * P0 + 3*(1-t)^2*t * P1 + 3*(1-t)*t^2 * P2 + t^3 * P3. CSS animations and SVG paths use cubic bezier curves extensively, and the syntax cubic-bezier(x1, y1, x2, y2) in CSS specifies the two interior control points (P1 and P2) with P0 fixed at (0,0) and P3 at (1,1).

Cubic bezier curves are the standard curve type in professional tools and game engines. Spine animation curves, After Effects motion paths, and vector drawing tools (Figma, Illustrator) all use cubic beziers. Three.js provides THREE.CubicBezierCurve3 and Babylon.js offers bezier curve utilities for camera paths and animations.

The tangent (direction) at any point on a cubic bezier is the derivative of the curve function. At parameter t, the tangent is B'(t) = 3*(1-t)^2*(P1-P0) + 6*(1-t)*t*(P2-P1) + 3*t^2*(P3-P2). Normalizing this vector gives the forward direction, which is useful for orienting objects that travel along the curve (making a car face the direction of the road, or making a missile point along its trajectory).

Catmull-Rom Splines

Bezier curves do not pass through their interior control points. The curve is influenced by P1 and P2 but does not touch them. When you need a smooth curve that passes through every specified point, use a Catmull-Rom spline. Given a sequence of points, a Catmull-Rom spline generates a smooth curve that interpolates (passes through) each point with continuous tangents at each junction.

The Catmull-Rom formula for the segment between points P1 and P2 (using neighboring points P0 and P3 for tangent calculation) is: q(t) = 0.5 * ((2*P1) + (-P0 + P2)*t + (2*P0 - 5*P1 + 4*P2 - P3)*t^2 + (-P0 + 3*P1 - 3*P2 + P3)*t^3). The t parameter goes from 0 (at P1) to 1 (at P2). The neighboring points P0 and P3 determine the tangent direction at P1 and P2, creating smooth transitions between segments.

Camera paths are the most common use case for Catmull-Rom splines in games. Place waypoints at interesting viewpoints in the scene. The spline generates a smooth camera path that visits each waypoint exactly, with smooth turns at each one. Animating the camera along the spline at constant t-increment per frame produces a cinematic flythrough.

Enemy patrol routes use Catmull-Rom splines when the designer wants precise control over where the enemy walks. Place patrol waypoints, generate the spline, and the enemy follows a smooth path through every point. Unlike straight-line waypoint following (which creates sharp turns), the spline produces natural, curved motion.

For closed loops (the last point connects back to the first), wrap the point array so the first two points appear again at the end. This gives the final segment's formula the correct neighboring points for smooth closure. A patrol loop, circular camera orbit, or racetrack outline all use closed Catmull-Rom splines.

Practical Applications in Games

Projectile arcs: A quadratic bezier from the launcher position through a control point above the midpoint to the target position creates a natural arc. The control point's height determines the arc's apex. Higher control point means a higher, slower arc. Lower control point means a flatter, faster trajectory. This approach gives designers direct control over the arc shape without physics simulation.

Easing and animation curves: A cubic bezier from (0,0) to (1,1) with two interior control points defines a custom easing function. The x-axis represents input t (time progress) and the y-axis represents output t (animation progress). By adjusting the control points, you create custom acceleration profiles that standard easing functions cannot match. CSS transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1.0) uses this exact approach.

Procedural road generation: Place control points along the desired road path. Generate a cubic bezier or Catmull-Rom spline through the points. Sample the curve at regular intervals to get center-line positions. At each sample, compute the tangent (curve derivative) and perpendicular to create road edges. Extrude the road width perpendicular to the tangent at each point to generate road geometry. This technique creates smooth, winding roads from sparse control points.

Particle trajectories: Instead of physics-driven particles (which require velocity and acceleration calculations per frame), define a bezier curve from emission point through control points to the destination. Advance each particle along its curve by incrementing t. This produces deterministic, artistically controllable particle motion that looks organic without the computational cost of per-particle physics.

UI animation paths: Slide a notification from off-screen through a curved path to its final position. A cubic bezier with the first control point directly below the start and the second directly above the end creates a smooth arc that enters from the side with a slight upward swoop. Animating t from 0 to 1 with ease-out timing produces a polished entrance effect.

Sampling and Performance

Evaluating a bezier curve at a single t value requires a few multiplications and additions, which is negligible in terms of performance. The practical concern is how many samples you compute per frame. Drawing a bezier curve as a visible path requires sampling many points and drawing line segments between them. Ten samples look blocky. Fifty samples look smooth. One hundred samples are visually indistinguishable from a perfect curve at typical game resolutions.

For objects moving along curves, you typically compute one curve point per frame (the position at the current t value), which is trivially fast. The challenge is uniform-speed movement. Incrementing t by a constant each frame produces non-uniform speed because curve segments are not the same length. Sections where the curve bends sharply are denser (more curve length per unit of t) than straight sections. For constant-speed movement, pre-compute an arc-length lookup table by sampling many points, computing cumulative distances, and using inverse lerp to map desired travel distance to the correct t value.

Key Takeaway

Bezier curves are nested lerps applied to control points. Quadratic (3 points) produces arcs, cubic (4 points) produces S-curves. Catmull-Rom splines pass through every control point for camera paths and patrol routes. The underlying math is simple interpolation applied recursively.