glTF Cubic Spline Keyframe Data Structure
In glTF 2.0 binary files, cubic spline animation data is organized within binary buffers as a contiguous, interleaved array of structural triplets. Rather than storing keyframe values and tangents in separate streams, each keyframe packs an in-tangent, a target value, and an out-tangent in sequence. This article breaks down the exact layout, accessor characteristics, and memory organization used to store cubic spline keyframes inside glTF buffers.
The Keyframe Triplet Layout
When an animation sampler in glTF defines its
interpolation algorithm as CUBICSPLINE, the
output accessor points to binary data grouped into
triplets. For every keyframe index \(k\), the binary stream contains three
consecutive elements of identical type:
- In-Tangent (
inTangent): The incoming tangent vector representing the slope of the curve as it approaches the keyframe. - Point Value (
value): The actual animated property value (such as translation, rotation, or scale) at that specific keyframe time. - Out-Tangent (
outTangent): The outgoing tangent vector representing the slope of the curve as it leaves the keyframe.
In raw binary representation, for \(n\) keyframes, the buffer contains a sequential array structured conceptually as:
[inTangent_0, value_0, outTangent_0, inTangent_1, value_1, outTangent_1, ..., inTangent_n-1, value_n-1, outTangent_n-1]
Accessor and BufferView Configuration
glTF maps this data using standard bufferView and
accessor objects:
- Element Count: If an animation channel has \(n\) keyframe timestamps in its input
accessor, the cubic spline output accessor has a
countequal to \(3 \times n\). - Type and Component Type: The
type(e.g.,SCALAR,VEC3,VEC4) andcomponentType(e.g.,5126forFLOAT) match the property being animated. For example, a translation track usesVEC3floats. Therefore, each keyframe occupies threeVEC3elements (9 float values in total: 3 forinTangent, 3 forvalue, 3 foroutTangent). - Byte Offset and Stride: The data is packed tightly by default without padding between tangent and value vectors, resulting in a contiguous array where each keyframe payload is \(3 \times \text{sizeOf(type)}\) bytes.
Interpretation During Interpolation
During playback, runtime engines reconstruct cubic Hermite splines between keyframe \(k\) and keyframe \(k+1\). The tangents stored in the buffer are normalized relative to unit time. To evaluate the spline, the runtime scales the out-tangent of keyframe \(k\) and the in-tangent of keyframe \(k+1\) by the duration between the two keyframe timestamps (\(\Delta t = t_{k+1} - t_k\)). Because the tangents and values are stored adjacently in memory, engines can efficiently read all required interpolation parameters with localized cache access.