How to Animate Light Emission in glTF
Simulating changing light emission over time in glTF models requires
specific workarounds or extensions because the core glTF 2.0
specification natively restricts animation channels to node transforms
and morph target weights. While you cannot animate material properties
out of the box using baseline glTF, you can achieve dynamic emission by
utilizing modern extensions like KHR_animation_pointer,
implementing morph-target geometric tricks, using UV offset animations,
or driving properties at runtime using WebGL engines. This article
covers the most effective methods to create pulsing, flickering, or
transitioning emissive light effects within glTF workflows.
1. The
KHR_animation_pointer Extension
The most robust and future-proof method is the
KHR_animation_pointer extension. This extension expands
glTF's native animation capabilities beyond simple TRS (translation,
rotation, scale) and morph weights, allowing animation channels to
target almost any property in the glTF JSON hierarchy via JSON
pointers.
- Targeting Emissive Factors: You can directly bind
an animation channel to
/materials/{index}/emissiveFactorto interpolate RGB values over time. - Targeting Emissive Strength: When combined with
KHR_materials_emissive_strength, you can point the animation channel to/materials/{index}/extensions/KHR_materials_emissive_strength/emissiveStrength, allowing for high-dynamic-range (HDR) bloom and intensity changes over time. - Compatibility: Tools like Blender (via recent glTF-Blender-IO exporter updates) support exporting material animations using this extension, and major web engines like Three.js and Babylon.js provide playback support.
2. Morph Targets (Shape Keys) for Emissive Geometry
If you need your model to remain strictly compliant with core glTF 2.0 without relying on material extension support in third-party viewers, morph targets offer a reliable geometric workaround.
- Concealed Emissive Mesh: Create two states of an emissive element. In the base state, scale the emissive geometry down to zero (hidden inside an opaque outer shell or collapsed to a single point). In the target shape key, scale it outward so it becomes visible.
- Layered Occlusion: Place an opaque "shutter" or mesh over the emissive surface. Use a morph target to translate or shrink the occluding geometry, gradually exposing the glowing material beneath.
- Animation: Animate the morph target weight from
0.0to1.0within standard glTF animation tracks to simulate a light powering on or pulsating.
3. UV Translation and Texture Atlasing
Another standard-compliant approach involves animating UV coordinates to slide across an emissive texture map containing various brightness states.
- Emissive Texture Atlas: Create a single texture containing a sequence of brightness levels or animation frames side by side.
- UV Animation: By using an extension like
KHR_texture_transformpaired with runtime logic orKHR_animation_pointer, you can shift the UV coordinates across the texture atlas to display different stages of light intensity over time.
4. Runtime Driving via 3D Engine APIs
If the glTF file is being used in an interactive application (such as Three.js, Babylon.js, or Godot), driving the emission programmatically at runtime is often the simplest and most performant solution.
- Three.js Example: Inspect the loaded glTF scene,
locate the target material, and animate
material.emissiveIntensityormaterial.emissiveinside the render loop using math functions (such as a sine wave for pulsing) or a tweening library. - Custom Animation Tracks: Load standard glTF
animation clips and inject custom
NumberKeyframeTrackorColorKeyframeTrackinstances targeted at the material's emissive parameters before starting playback.
5. Simulating
Emission via KHR_lights_punctual
While surface glow comes from emissive materials, actual dynamic illumination on surrounding objects is typically handled by point or spot lights.
- The
KHR_lights_punctualextension allows placing explicit light sources directly inside a glTF scene graph. - By attaching a light node to an animated parent node, you can move the light source in and out of an occluded cavity to simulate turning it on and off.
- In conjunction with
KHR_animation_pointer, theintensityproperty of the punctual light itself can be animated directly to synchronize illumination with an emissive mesh surface.