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_0 is stored as either normalized 8-bit or 16-bit unsigned integers, or 32-bit floating-point values (typically VEC3 or VEC4).
  • Implementation: The root vertices are typically assigned low values (approaching 0.0 for full occlusion), while the tip vertices are assigned higher values (approaching 1.0 for 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_AO or 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 alternative COLOR_0 or custom attribute arrays corresponding to different flattened configurations.
  • Dynamic Blending: At runtime, the host engine dynamically updates the weights array 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.