Parent-Child Relationships in glTF Scene Graphs
This article provides an overview of how the glTF (GL Transmission Format) specification defines scene graph hierarchies. It explains how nodes reference child elements using index-based arrays, how local transformation matrices propagate down the hierarchy to compute global transforms, and the structural constraints enforced to maintain a valid tree structure.
In glTF, 3D scenes are organized as directed acyclic graphs (DAGs),
typically functioning as strict tree structures. The entire asset
defines a top-level nodes array in the JSON schema. Rather
than embedding child objects directly inside parent objects, glTF uses a
flat array of node objects where relationships are mapped through array
indices.
A parent node establishes a relationship with its children using the
children property. This property is an array of integer
indices, with each integer pointing to another node within the global
nodes array:
{
"nodes": [
{
"name": "ParentNode",
"children": [1, 2]
},
{
"name": "ChildNodeA"
},
{
"name": "ChildNodeB"
}
]
}In this structure, the parent explicitly defines its descendants, while child nodes do not contain a direct pointer back to their parent. Run-time engines resolve upward traversal by parsing the hierarchy from top to bottom on import.
The root of the hierarchy is defined at the scene level. The glTF
scenes array contains individual scene definitions, each
possessing a nodes array listing the root-level node
indices. Any node not listed in another node's children
array and present in the scene's nodes array is treated as
a root node.
Parent-child relationships dictate how spatial transformations
propagate through the scene. A node can define its local transform using
either a 4x4 column-major matrix (matrix) or a decoupled
set of translation, rotation, and scale components
(translation, rotation, scale). A
child node’s local transform is evaluated relative to its parent’s
coordinate space. To derive a child’s global (world) transform matrix, a
renderer multiplies the parent’s global transform matrix by the child’s
local transform matrix:
\[\mathbf{M}_{\text{world, child}} = \mathbf{M}_{\text{world, parent}} \times \mathbf{M}_{\text{local, child}}\]
Any translation, rotation, or scale applied to a parent node automatically affects all of its descendants down the chain.
The glTF specification enforces strict rules regarding these relationships:
- A node cannot be a child of multiple parents. Each node index can
appear at most once across all
childrenarrays within the file. - Circular dependencies are prohibited. A node cannot be an ancestor of itself.
- Nodes used in skeletal animation (joints) follow the exact same
indexing and transform propagation rules, linked to meshes via the
skinsdefinition.