glTF Animation Timeline Sampling Explained

In the glTF 2.0 specification, the animation object drives runtime motion by pairing keyframe timelines with specific node transformations. This article provides a technical breakdown of how glTF structures timeline sampling, focusing on the relationship between animation samplers, time accessor inputs, transform outputs, and the supported mathematical interpolation algorithms.

The Architecture of Animation Samplers

Timeline sampling in glTF is primarily managed by the samplers array inside an animation object. Each sampler defines the relationship between keyframe timestamps and corresponding values, which are then routed to targeted node properties via animation channels.

An animation sampler consists of three core properties:

  • input: An index referring to an accessor containing the timeline timestamps.
  • output: An index referring to an accessor containing the animation keyframe values.
  • interpolation: A string defining the mathematical formula used to sample between keyframe points.

Timeline Input Requirements

The input property points to an accessor that stores the timeline data. The glTF specification enforces strict rules for timeline inputs:

  • Data Format: Timeline inputs must be floating-point scalar values (SCALAR type with FLOAT component type).
  • Measurement Units: Time is measured strictly in seconds, starting at zero or a positive offset.
  • Monotonic Progression: Timestamps within the accessor must be strictly increasing (\(t_{k+1} > t_k\)). This guarantees a deterministic timeline where no two keyframes share the same time index.
  • Min/Max Metadata: The accessor must define min and max values, representing the start and end times of the animation track, allowing runtimes to establish the duration without scanning the entire buffer.

Interpolation Mechanisms

When sampling a timeline at an arbitrary time \(t\) between two keyframes \(t_k\) and \(t_{k+1}\), a glTF runtime computes a normalized time factor:

\[s = \frac{t - t_k}{t_{k+1} - t_k}\]

The value at \(t\) is calculated based on the sampler's interpolation property, which supports three standard algorithms:

1. STEP

The STEP mechanism disables intermediate interpolation. The output maintains the value of the previous keyframe until the timeline reaches the next keyframe:

\[\text{value}(t) = v_k\]

This is commonly used for discrete state changes, visibility toggles, or mechanical, non-smoothing motions.

2. LINEAR

The LINEAR mechanism performs linear interpolation between adjacent keyframes:

\[\text{value}(t) = (1 - s) \cdot v_k + s \cdot v_{k+1}\]

When the target property is a rotation (represented by quaternions in glTF), runtimes apply spherical linear interpolation (Slerp) or normalized linear interpolation (Nlerp) to preserve quaternion normalization.

3. CUBICSPLINE

The CUBICSPLINE mechanism uses cubic Hermite spline interpolation. Unlike STEP and LINEAR, which store only values in the output accessor, CUBICSPLINE requires three separate values per keyframe in the output buffer:

  1. In-tangent (\(a_k\)): The incoming tangent vector.
  2. Keyframe value (\(v_k\)): The actual property value at time \(t_k\).
  3. Out-tangent (\(b_k\)): The outgoing tangent vector.

To compute the interpolated value between \(t_k\) and \(t_{k+1}\), the runtime evaluates the standard Hermite basis functions:

\[\text{value}(t) = (2s^3 - 3s^2 + 1)v_k + (t_{k+1} - t_k)(s^3 - 2s^2 + s)b_k + (-2s^3 + 3s^2)v_{k+1} + (t_{k+1} - t_k)(s^3 - s^2)a_{k+1}\]

The tangents scale proportionally with the duration of the time interval \((t_{k+1} - t_k)\), ensuring smooth curves across keyframes with non-uniform time distributions.

Out-of-Bounds Evaluation

For timeline queries occurring before the first keyframe (\(t < t_0\)) or after the final keyframe (\(t > t_n\)), glTF specifies that runtimes should clamp the values to the first and last keyframe, respectively, unless an external playback loop or application-specific behavior is enforced.