Role of inverseBindMatrices in glTF Mesh Skinning
This article provides a concise technical explanation of the
inverseBindMatrices accessor in the glTF (GL Transmission
Format) 2.0 specification. It covers why this data is mathematically
necessary for linear blend skinning, how it transforms vertex data
between coordinate spaces, the default behavior when it is omitted, and
how it ensures smooth 3D character deformation.
The Coordinate Space Problem in Skinning
In skeletal animation (skinning), a 3D mesh's vertices are deformed according to the movement of an underlying joint hierarchy. By default, the vertices of a mesh are defined in a single, shared coordinate system known as mesh space or model space (often matching the initial "bind pose").
When a joint moves or rotates, its transform is computed relative to the scene's hierarchy. However, you cannot directly apply a joint's world-space transformation to a vertex that is defined in mesh space. Doing so would apply the joint's global position to vertices that are already offset in world space, causing severe visual artifacts or mesh explosion. To deform a vertex properly, the rendering engine must first calculate the vertex's position relative to the joint itself.
The Function of
inverseBindMatrices
The inverseBindMatrices accessor provides an array of
\(4 \times 4\) floating-point
matrices—one for each joint listed in the skin.joints
array.
Each inverse bind matrix is the inverse of the joint's world-space transform at the exact moment the mesh was bound to the skeleton (the bind pose). Its primary mathematical purpose is to transform a vertex from mesh space into the local coordinate space of a specific joint.
Once the vertex is in the joint's local coordinate space, the runtime skinning algorithm applies the joint's current transform to move the vertex to its new animated position.
The Skinning Math Breakdown
In standard linear blend skinning (LBS), each vertex is transformed by calculating a weighted sum across all affecting joints. For each joint \(j\) influencing a vertex, the transformation pipeline functions as follows:
- Transform to Joint Space: The vertex position in mesh space (\(v\)) is multiplied by the joint's inverse bind matrix (\(IBM_j\)): \[\text{Local Vertex} = IBM_j \times v\]
- Transform to Animated Space: The local vertex is multiplied by the joint's current global transform matrix (\(M_j\)): \[\text{Skin Matrix}_j = M_j \times IBM_j\]
- Blend the Results: The final vertex position (\(v'\)) is computed by weighting the results of all contributing joints: \[v' = \sum_{j} (w_j \times \text{Skin Matrix}_j \times v)\] (where \(w_j\) represents the vertex weight for joint \(j\), and the sum of all weights equals 1.0)
Without the inverse bind matrix, the initial step cannot occur, making it impossible to determine the relative distance and orientation between the joint and the vertex in the resting pose.
Optional Omission and Default Behavior
According to the glTF 2.0 specification, the
inverseBindMatrices property is optional. If a skin does
not define an accessor for inverseBindMatrices, the
renderer must assume an identity matrix for each joint.
An identity matrix assumes that each joint's local origin and
orientation precisely match the origin and orientation of the mesh
coordinate space in the bind pose. While this is rare for complex
character skeletons, it can be useful in simplified rigs or procedural
nodes where joints are pre-aligned with mesh space. For standard
animated characters, inverseBindMatrices is required to
preserve proper geometry during playback.