From naive blend to the great-circle arc
Step 1 — the naive try: lerp the components. The obvious idea is straight-line
interpolation, treating the four numbers as a vector:
\operatorname{lerp}(q_0, q_1, t) = (1 - t)\,q_0 + t\,q_1, \qquad t \in [0, 1].
At t=0 it is q_0, at
t=1 it is q_1 — good endpoints. But a unit
quaternion must lie on the 4-D unit sphere, and the straight chord between two points on a sphere cuts
through it, so the blend is no longer unit-length.
Step 2 — patch it: NLERP (normalised lerp). Just renormalise each step,
\operatorname{nlerp}(q_0, q_1, t) = \frac{(1-t)\,q_0 + t\,q_1}{\,|(1-t)\,q_0 + t\,q_1|\,}.
This stays on the sphere and is cheap. But because the chord is being projected back out to the sphere,
equal steps in t do not give equal steps in angle: the motion
speeds up in the middle and lingers near the ends. Fine for a quick blend, wrong for a
camera that should pan at constant rate.
Step 3 — do it right: walk the great-circle arc. The honest path between two points on
a sphere is the shortest great-circle arc joining them, traversed at constant
angular velocity. Call the angle between q_0 and
q_1 on the 4-D sphere \Omega; we want a point that
sweeps from q_0 to q_1 along that arc, covering an
equal slice of \Omega for each equal slice of t.
Step 4 — find the angle from the dot product. Both quaternions are unit vectors in
\mathbb{R}^4, so their
dot product is the
cosine of the angle between them:
\cos\Omega = q_0 \cdot q_1 = w_0 w_1 + x_0 x_1 + y_0 y_1 + z_0 z_1.
Step 5 — the SLERP formula. The constant-speed point on the arc is the
sine-weighted combination
\operatorname{slerp}(q_0, q_1, t) = \frac{\sin\big((1-t)\,\Omega\big)}{\sin\Omega}\,q_0 + \frac{\sin\big(t\,\Omega\big)}{\sin\Omega}\,q_1.
Check the endpoints. At t=0: the first weight is
\sin\Omega/\sin\Omega = 1 and the second is
\sin 0/\sin\Omega = 0, giving exactly q_0. At
t=1: the weights flip, giving exactly q_1. In
between, because the weights are sines of angles linear in t, the
result traces the arc at a steady angular rate — constant speed, by construction. (The two scalar
weights are exactly the coefficients that decompose the arc point in the
\{q_0, q_1\} plane; they are the spherical analogue of
(1-t) and t, and as
\Omega \to 0 they reduce to them.)
Step 6 — take the short way (the double-cover sign flip). Here is the one quaternion
gotcha. A quaternion and its negative represent the same rotation:
q and -q rotate identically (the unit quaternions
double-cover the rotations). So q_1 and
-q_1 are the same destination but sit on opposite sides of the
sphere. If q_0 \cdot q_1 < 0 the arc to q_1 goes the
long way round (more than 90° through orientation space); flipping the
sign,
\text{if } q_0 \cdot q_1 < 0: \quad q_1 \leftarrow -q_1,
picks the nearer representative so SLERP takes the genuinely shortest path. Skip this and your camera
occasionally takes the scenic 270° route to a pose 90°
away — a classic engine bug.
For unit quaternions q_0, q_1 and t \in [0,1],
spherical linear interpolation is
\operatorname{slerp}(q_0, q_1, t) = \frac{\sin\big((1-t)\Omega\big)}{\sin\Omega}\,q_0 + \frac{\sin\big(t\Omega\big)}{\sin\Omega}\,q_1.
-
It walks the shortest great-circle arc on the 4-D unit sphere from
q_0 to q_1.
-
The arc angle comes from the dot product: \cos\Omega = q_0 \cdot q_1.
-
Endpoints are exact: \operatorname{slerp}(\cdot,\cdot,0) = q_0 and
\operatorname{slerp}(\cdot,\cdot,1) = q_1.
-
It moves at constant angular velocity — equal t steps are
equal angle steps.
-
Double-cover sign flip: if q_0 \cdot q_1 < 0, replace
q_1 by -q_1 (same rotation, nearer point) to take
the short way.
NLERP and SLERP reach the same endpoints and trace the same arc — the difference is purely the
timing along it.
-
SLERP moves at constant angular speed: rock-steady, the right choice for a
camera pan, a turret tracking a target, or any motion the eye reads as "smooth and even".
The cost is two \sin evaluations (and a divide) per sample.
-
NLERP is a lerp plus one normalisation — much cheaper, and commutative and
associative (handy for blending several poses at once). Its angular speed is uneven (faster in the
middle), but for short blends, or many skinned-mesh bones where the wobble is imperceptible
and the budget is tight, that error is invisible and the speed wins.
Rule of thumb engines actually follow: NLERP for cheap, high-volume animation blends with small angles;
SLERP when the path is long or the constant rate is visible (cinematic camera moves). A common hybrid
even SLERPs only when q_0 \cdot q_1 shows a wide angle and NLERPs otherwise.