glTF Root Nodes and Transformation Hierarchies
This article examines the procedural relationship between root nodes and transformation hierarchies within the glTF (GL Transmission Format) specification. It details how scenes define top-level root nodes, how transformation data is defined at the node level, and how matrix concatenation traverses parent-child relationships to compute global world coordinates from local object spaces.
In a glTF asset, the scene graph is represented as a directed acyclic
graph (DAG) organized into trees of nodes. The structure begins with the
scenes array, where an active scene declares a
nodes array containing the integer indices of its root
nodes. These root nodes serve as the procedural entry points for
evaluating spatial relationships in a 3D environment. Any node not
listed as a child of another node, but referenced by the scene, acts as
an independent root.
Each node in glTF can define its local transformation using either a 4x4 matrix or separate Translation, Rotation, and Scale (TRS) properties. If defined via TRS, the rotation is stored as a unit quaternion \([x, y, z, w]\), translation as a 3-element vector \([x, y, z]\), and scale as a 3-element vector \([s_x, s_y, s_z]\). Procedurally, if TRS properties are provided, the local transformation matrix \(M_{local}\) is computed by evaluating the product:
\[M_{local} = T \times R \times S\]
If a 16-element matrix array is explicitly defined
instead, it directly represents \(M_{local}\) stored in column-major order.
If neither is specified, the node defaults to an identity matrix.
The procedural relationship between root nodes and transformation hierarchies relies on depth-first or breadth-first forward kinematics traversal. A root node has no parent; therefore, its global (world) transformation matrix \(M_{world}\) is equal to its evaluated local transformation matrix \(M_{local}\):
\[M_{world}^{root} = M_{local}^{root}\]
For child nodes listed in a parent’s children array, the
global transformation is computed hierarchically by post-multiplying the
parent's accumulated world matrix by the child’s local matrix:
\[M_{world}^{child} = M_{world}^{parent} \times M_{local}^{child}\]
This accumulation enforces strict directional inheritance:
- Inherited Displacement: Changes applied to a root node propagate to all descendant nodes, altering their global position, orientation, and scale.
- Local Isolation: Modifications made to a child's local properties affect only that child and its subsequent sub-tree, leaving parent and sibling nodes unaffected.
- Topological Independence: Multiple root nodes operate entirely independently of each other within the same scene, enabling distinct coordinate reference frames before being merged into the unified scene view.
When resolving transforms for rendering or skinning, runtimes compute an array of global model matrices by traversing from the roots downward. Meshes, cameras, or skinning joints attached to any node inherit the final evaluated \(M_{world}\) of that specific node, completing the pipeline from local geometric definition to final world-space positioning.