How glTF Defines Baseline Morph Target Weights

This article explains how the glTF 2.0 specification defines baseline target weights for morph target animations. It covers the structural hierarchy between mesh primitives and node instances, details how default weights are declared and inherited, and outlines how these baseline states interact with runtime animation channels.

Morph Targets in glTF 2.0

In glTF, morph targets are stored inside mesh primitive objects (mesh.primitives[].targets). Each target is an object containing attribute arrays (such as POSITION, NORMAL, and TANGENT) that represent displacement vectors, or deltas, relative to the base mesh geometry. To control the influence of each morph target, the specification uses scalar weights ranging typically from 0.0 (no influence) to 1.0 (full influence), though values outside this range are technically valid for exaggerated deformations.

Declaring Mesh-Level Baseline Weights

Baseline morph target weights can be defined globally for a mesh using the mesh.weights property.

  • The mesh.weights array contains floating-point values corresponding by index to the targets defined in the mesh's primitives.
  • The length of the array must match the total number of morph targets present on the primitive.
  • Setting mesh.weights establishes the initial rest pose for any node referencing this mesh, dictating how much each displacement delta affects the base vertex attributes before any dynamic animation is applied.

Overriding Weights at the Node Level

Because multiple nodes can reference the same mesh, glTF allows individual nodes to override the mesh's default blend state using the node.weights array.

  • When a node specifies a weights array, these values take precedence over mesh.weights.
  • This mechanism allows different instances of the same 3D model to present distinct baseline facial expressions, configurations, or shapes without duplicating geometry data.
  • If a node contains both a mesh reference and a weights array, rendering engines must use the node's values as the starting blend state.

Default Fallback Behavior

If neither mesh.weights nor node.weights is defined in the glTF asset, the specification defines an implicit baseline:

  • All morph target weights default to 0.0.
  • In this state, only the base attributes of the mesh primitives are rendered, and all morph target displacement deltas are multiplied by zero.

Interaction with Morph Animation Channels

Baseline weights establish the initial state from which runtime animations operate:

  1. Animation Targeting: Morph animations target the weights path of a specific node using an animation channel (animation.channels[].target.path = "weights").
  2. Dynamic Blending: When an animation is active, the sampler outputs continuously overwrite or modulate the node's morph weights for each frame.
  3. Playback Termination: When an animation stops, or before playback begins, the rendering engine typically reverts the blend state back to the baseline defined by node.weights, mesh.weights, or the implicit 0.0 default.