How Morph Targets and Skinning Work Together in glTF

In the glTF 2.0 standard, morph targets (blend shapes) and skeletal animation (skinning) operate concurrently on a single mesh by following a strictly ordered vertex processing pipeline. Rather than conflicting, these two animation techniques occupy sequential stages in the vertex shader: relative morph displacements are accumulated first in the mesh’s local object space, and the resulting morphed vertex data is subsequently transformed by the joint matrices of the skeletal hierarchy.

The Standardized Vertex Processing Order

The glTF specification mandates that vertex positions, normals, and tangents must undergo morphing prior to skinning. Mathematically, morphing is an additive operation executed in local space, whereas skinning is an affine coordinate transformation that maps vertices from local bind space into animated pose space. Inverting this order would cause skinning deformations to misalign with morph offsets, producing unnatural shearing or distortion.

Stage 1: Morph Target Accumulation

A glTF primitive supporting morph targets stores base vertex attributes alongside a list of target deltas defined in mesh.primitive.targets. These deltas represent localized displacements for attributes such as POSITION, NORMAL, and TANGENT.

During this stage:

  1. Each morph target has an assigned scalar weight (defined in mesh.weights or animated via glTF animation channels).
  2. The vertex shader computes a linear combination of these displacements relative to the base attribute.
  3. The morphed position (\(P_{morphed}\)) is calculated as: \[P_{morphed} = P_{base} + \sum_{i=0}^{n} (w_i \cdot \Delta P_i)\] where \(w_i\) represents the weight of target \(i\), and \(\Delta P_i\) is the corresponding positional delta.
  4. Normals and tangents are accumulated identically and then re-normalized to maintain unit length in local space.

Because this computation takes place entirely within object space, facial expressions, corrective deformations, and muscle bulges retain their intended shape regardless of the model’s orientation or posture.

Stage 2: Linear Blend Skinning (LBS)

Once morph target resolution yields the final deformed local-space vertex data, skeletal skinning transforms the geometry. Skinning metadata is provided by the skin object and the primitive’s JOINTS_0 and WEIGHTS_0 vertex attributes.

During skinning:

  1. Each vertex references up to four joints per attribute set, along with corresponding normalized scalar weights that sum to 1.0.
  2. The runtime engine calculates a skinning matrix (\(M_{skin}\)) for the vertex by blending the transformation matrices of its associated joints: \[M_{skin} = \sum_{j=0}^{3} \left( W_j \cdot G_j \cdot IBM_j \right)\] where \(W_j\) is the bone weight, \(G_j\) is the global transform of the joint node, and \(IBM_j\) is the joint’s inverse bind matrix.
  3. The morphed vertex position is multiplied by this blended skinning matrix: \[P_{final} = M_{skin} \cdot P_{morphed}\]
  4. Morphed normals and tangents are similarly transformed using the rotational components of the skinning matrices.

glTF Scene Graph Binding

The glTF architecture enables this concurrent execution by decoupling mesh data from scene-instance transforms. A single node in the glTF hierarchy can simultaneously reference both a mesh (which contains geometry primitives and morph targets) and a skin (which lists the skeletal joints and inverse bind matrices). When a renderer encounters a node featuring both definitions, it supplies the morph target textures or buffers and the joint matrix palette to the active vertex shader, executing the morph-then-skin pipeline in a single rendering pass.