Interpolating glTF Camera Position and FOV

Smoothly transitioning between two glTF cameras requires distinct mathematical techniques for translational coordinates and perspective projection properties. In glTF 2.0, camera nodes define spatial position through transform matrices or translation-rotation-scale (TRS) vectors, while perspective optics are defined by vertical field-of-view (yfov) values stored in radians. Achieving visually natural camera animation involves applying easing functions to position vectors and interpolating field-of-view through tangent space rather than simple linear angle blending.

Position Interpolation

A glTF node's camera position is represented as a 3D Cartesian vector \(P = (x, y, z)\). Moving from an initial camera position \(P_0\) to a target position \(P_1\) over a normalized time interval \(t \in [0, 1]\) relies on vector interpolation.

Linear Interpolation (Lerp)

The baseline formula for translation is standard linear interpolation:

\[P(t) = (1 - t)P_0 + t P_1\]

While computationally simple, standard linear interpolation causes abrupt starts and stops because velocity jumps instantaneously from zero to a constant rate.

Smooth Easing Functions

To remove mechanical jarring, map the normalized time parameter \(t\) through an S-curve easing function before applying it to the position vector.

A standard cubic smoothstep function provides zero velocity at both endpoints:

\[s(t) = 3t^2 - 2t^3\]

For zero acceleration at the endpoints (yielding even smoother motion), use the quintic smootherstep function:

\[s(t) = 6t^5 - 15t^4 + 10t^3\]

The eased position is then calculated as:

\[P(t) = (1 - s(t))P_0 + s(t)P_1\]

Field-of-View Interpolation

In a glTF schema, perspective cameras specify the vertical field-of-view via the yfov property in radians.

The Problem with Direct Angular Lerp

Directly interpolating the angle using \(\text{FOV}(t) = (1 - t)\text{FOV}_0 + t\text{FOV}_1\) causes non-linear perceptual distortion. Because perspective projection maps world coordinates to normalized device coordinates using trigonometric division, the perceived size of objects changes non-linearly with angle changes. A uniform change in radians does not produce a uniform visual zoom.

Tangent-Space Interpolation

To achieve visually uniform transitions, interpolate in the half-angle tangent domain, which directly corresponds to focal length and image magnification.

  1. Convert both glTF yfov angles to their half-angle tangents:

\[k_0 = \tan\left(\frac{\text{yfov}_0}{2}\right)\]

\[k_1 = \tan\left(\frac{\text{yfov}_1}{2}\right)\]

  1. Interpolate linearly (or with an easing function \(s(t)\)) between the tangent scales:

\[k(t) = (1 - s(t))k_0 + s(t)k_1\]

  1. Reconstruct the interpolated field-of-view angle:

\[\text{yfov}(t) = 2 \cdot \arctan(k(t))\]

This preserves constant visual scale acceleration across the transition.

Combined Camera Matrix Construction

To render the interpolated camera state at any time step \(t\):

  1. Compute the interpolated scalar \(s(t)\) using the quintic curve.
  2. Evaluate \(P(t)\) for the position translation.
  3. If camera orientation changes, interpolate the glTF node rotation quaternions using Spherical Linear Interpolation (Slerp):

\[\text{Slerp}(q_0, q_1, s(t)) = \frac{\sin((1 - s(t))\theta)}{\sin(\theta)}q_0 + \frac{\sin(s(t)\theta)}{\sin(\theta)}q_1\]

where \(\cos(\theta) = q_0 \cdot q_1\).

  1. Evaluate \(\text{yfov}(t)\) using the tangent-space formula.
  2. Reconstruct the projection matrix using \(\text{yfov}(t)\) alongside the interpolated or constant znear, zfar, and aspectRatio attributes defined in the glTF camera payload.