Dynamic Vertex AO in glTF Procedural Grass
This article explains how the glTF (GL Transmission Format) standard facilitates dynamic vertex ambient occlusion (AO) in procedural grass systems. Although glTF is fundamentally a static transmission format rather than a runtime execution engine, it provides standardized structures—including vertex color attributes, custom vertex attributes, GPU instancing extensions, and morph targets—that serve as the foundational data pipelines required for real-time, dynamic vertex occlusion calculations on procedural foliage.
1. Base Gradient Storage via Vertex Color Attributes
The primary method for storing ambient occlusion data at the vertex
level in standard glTF 2.0 is the COLOR_0 attribute. In
procedural grass systems, grass blades naturally experience more
occlusion at their roots than at their tips.
Because glTF does not compute real-time physics or ray-traced ambient occlusion natively, the asset exporter bakes normalized baseline occlusion weights directly into the vertex attributes:
- Format:
COLOR_0is stored as either normalized 8-bit or 16-bit unsigned integers, or 32-bit floating-point values (typicallyVEC3orVEC4). - Implementation: The root vertices are typically
assigned low values (approaching
0.0for full occlusion), while the tip vertices are assigned higher values (approaching1.0for fully exposed areas). Runtime shaders sample this vertex color channel to determine static ground shadowing.
2. Custom Application-Specific Attributes
When standard material properties and color channels are reserved for
visual texturing, glTF allows application-specific custom attributes
designated with an underscore prefix, such as _AO,
_GROUND_OCCLUSION, or _BENDING_OCCLUSION.
- Accessory Data: These custom accessors store scalar
floats (
SCALAR) mapped per vertex. - Separation of Concerns: This approach decouples ambient occlusion from surface albedo color, allowing procedural grass shaders to dynamically scale the vertex occlusion without modifying the base diffuse tint.
3. Combining with
EXT_mesh_gpu_instancing
Procedural grass fields rely heavily on instancing to render
thousands of blades efficiently. The official glTF extension
EXT_mesh_gpu_instancing enables dynamic ambient occlusion
across instances rather than just individual vertices:
- Per-Instance Attributes: The extension permits
custom per-instance accessors, such as
_INSTANCE_AOor dynamic spatial transforms. - Interaction Occlusion: When an external object
(such as a character or vehicle) bends the grass, the runtime passes
dynamic proximity data into the instancing buffers. The vertex shader
combines the static per-vertex gradient (stored in
COLOR_0) with the dynamic per-instance attenuation defined via the instancing extension.
4. Morph Targets for Non-Linear Occlusion
For systems requiring precomputed deformation states with shifting ambient shadows (such as grass flattened by high winds or trampling), glTF represents dynamic states using Morph Targets.
- Target Arrays: A glTF primitive defines
targets, which can include alternativeCOLOR_0or custom attribute arrays corresponding to different flattened configurations. - Dynamic Blending: At runtime, the host engine
dynamically updates the
weightsarray of the mesh node. As the grass blade bends toward the ground, the ambient occlusion channel interpolates between the upright state (bright tip, dark base) and the flattened state (overall darker values to simulate being trapped beneath other foliage).
5. Runtime Shader Consumption
Within a dynamic rendering pipeline, glTF acts as the data layout blueprint. The runtime vertex shader reads the glTF buffer data and evaluates dynamic vertex ambient occlusion through an equation similar to:
\[\text{Final AO} = \text{glTF.COLOR\_0} \times \text{DynamicEnvironmentOcclusion} \times \text{InstanceShadowWeight}\]
By providing strict binary accessor definitions and flexible attribute extensions, glTF standardizes the delivery of root-to-tip occlusion factors, morph weights, and instance transforms to the GPU, enabling procedural grass rendering engines to simulate dynamic, reactive shading seamlessly.