Animate Material Properties in glTF

In base glTF 2.0, animations are strictly limited to node transformations and morph target weights, leaving material parameters static by default. To animate arbitrary material properties—such as base color, roughness, metallic factors, emissive strength, and UV offsets—the official Khronos extension KHR_animation_pointer is required. This article explains how KHR_animation_pointer enables material property animation, how it handles complex adjustments like texture scrolling alongside KHR_texture_transform, and how it integrates into the glTF animation pipeline.

The Role of KHR_animation_pointer

The core glTF 2.0 specification restricts animation.channel.target.path to four predefined targets: translation, rotation, scale, and weights. The KHR_animation_pointer extension removes this limitation by introducing a dynamic path pointing system based on RFC 6901 JSON Pointers.

Instead of binding to fixed node transform channels, an animation channel utilizing KHR_animation_pointer targets specific properties anywhere within the glTF JSON hierarchy via the pointer property.

Animating Core Material Properties

With KHR_animation_pointer, an animation sampler's output values can directly modify any numeric or vector property defined in a material. The target path specifies the zero-indexed location of the material and the target parameter:

  • Base Color Factor: /materials/0/pbrMetallicRoughness/baseColorFactor (animates a VEC4 representing RGBA)
  • Metallic / Roughness: /materials/0/pbrMetallicRoughness/roughnessFactor (animates a SCALAR)
  • Emissive Factor: /materials/0/emissiveFactor (animates a VEC3 for RGB emissive color)
  • Alpha Cutoff: /materials/0/alphaCutoff (animates a SCALAR for masked materials)

The animation channel syntax replaces the standard target object with an extension block pointing to the property:

{
  "channels": [
    {
      "sampler": 0,
      "target": {
        "extensions": {
          "KHR_animation_pointer": {
            "pointer": "/materials/0/pbrMetallicRoughness/baseColorFactor"
          }
        }
      }
    }
  ]
}

Animating Texture Offsets and Scales

To animate UV coordinates for effects such as flowing water, conveyor belts, or flickering displays, KHR_animation_pointer must be paired with KHR_texture_transform.

The KHR_texture_transform extension defines UV properties—such as offset, scale, and rotation—directly on texture info objects. KHR_animation_pointer then references those transformed properties:

  • UV Translation (Scrolling): /materials/0/pbrMetallicRoughness/baseColorTexture/extensions/KHR_texture_transform/offset (animates a VEC2)
  • UV Tiling (Scale): /materials/0/pbrMetallicRoughness/baseColorTexture/extensions/KHR_texture_transform/scale (animates a VEC2)
  • UV Rotation: /materials/0/pbrMetallicRoughness/baseColorTexture/extensions/KHR_texture_transform/rotation (animates a SCALAR in radians)

Interpolation and Data Types

When animating material properties via KHR_animation_pointer, standard glTF interpolation algorithms apply: LINEAR, STEP, and CUBICSPLINE. The accessor defined by the animation sampler must match the data type and component count of the target property:

  • Properties accepting floating-point numbers require accessor component type 5126 (FLOAT).
  • Vector lengths must match the target (e.g., VEC3 for emissive color, VEC4 for color factors with alpha).

Declaring Extension Requirements

Any asset relying on this capability must register the extension in the document root. If the material animation is vital to the rendering of the scene, it must be listed under both extensionsUsed and extensionsRequired:

{
  "extensionsUsed": [
    "KHR_animation_pointer",
    "KHR_texture_transform"
  ],
  "extensionsRequired": [
    "KHR_animation_pointer"
  ]
}

Engines supporting KHR_animation_pointer resolve the JSON Pointer at load time, binding the timeline tracks directly to the shader uniforms or material state representations used in the runtime engine.