How glTF CUBICSPLINE Computes Keyframe Tangents
This article provides an overview of how glTF 2.0 handles
CUBICSPLINE animation interpolation. In glTF, tangents are
not dynamically computed or derived from neighboring values at runtime;
rather, explicit in-tangent and out-tangent values are precomputed by an
exporter and stored directly inside the glTF asset alongside the
keyframe values. At runtime, the animation engine scales these stored
tangents by the keyframe time interval and evaluates them using a
standard cubic Hermite spline formula to generate smooth transitions
between keyframes.
Data Layout in glTF Keyframe Buffers
When an animation sampler specifies the CUBICSPLINE
interpolation algorithm, the output accessor does not simply contain the
animated property values. Instead, for each keyframe timestamp \(t_k\), the accessor stores three
consecutive components in the following order:
- In-tangent (\(a_k\)): The arrival tangent slope at keyframe \(k\).
- Keyframe value (\(v_k\)): The actual property value (e.g., translation, rotation, scale, or morph target weights) at keyframe \(k\).
- Out-tangent (\(b_k\)): The departure tangent slope from keyframe \(k\).
Because every keyframe stores three elements, the total number of elements in the output buffer is three times the number of timestamps in the input accessor. For the very first keyframe, the in-tangent is unused and typically set to zero. Similarly, for the final keyframe, the out-tangent is unused.
Tangent Scaling and the Hermite Spline
To interpolate between keyframe \(k\) and keyframe \(k+1\) at a given time \(t_{current}\), the runtime first calculates the duration of the segment:
\[\Delta t = t_{k+1} - t_k\]
The normalized interpolation factor \(t \in [0, 1]\) is then computed as:
\[t = \frac{t_{current} - t_k}{\Delta t}\]
The tangents stored in the glTF file represent instantaneous rates of change per unit of time (\(\frac{dv}{dt}\)). To apply them to standard cubic Hermite basis functions defined on the domain \([0, 1]\), the tangents must be multiplied by the time step \(\Delta t\):
- \(p_0 = v_k\) (value at keyframe \(k\))
- \(p_1 = v_{k+1}\) (value at keyframe \(k+1\))
- \(m_0 = \Delta t \cdot b_k\) (scaled out-tangent of keyframe \(k\))
- \(m_1 = \Delta t \cdot a_{k+1}\) (scaled in-tangent of keyframe \(k+1\))
Cubic Hermite Polynomial Evaluation
The final interpolated value \(V(t)\) is calculated using the standard cubic Hermite spline formula:
\[V(t) = (2t^3 - 3t^2 + 1)p_0 + (t^3 - 2t^2 + t)m_0 + (-2t^3 + 3t^2)p_1 + (t^3 - t^2)m_1\]
Expanding the equation using the scaled parameters yields:
\[V(t) = (2t^3 - 3t^2 + 1)v_k + (t^3 - 2t^2 + t)\Delta t \cdot b_k + (-2t^3 + 3t^2)v_{k+1} + (t^3 - t^2)\Delta t \cdot a_{k+1}\]
Special Considerations for Rotations
When interpolating rotations stored as quaternions, the standard Hermite evaluation is applied component-wise to the four values \((x, y, z, w)\). Because component-wise cubic interpolation does not inherently maintain unit length, the resulting interpolated quaternion must be normalized before it is applied to a node's transform matrix.