glTF KHR_materials_volume Glass Light Extinction

In glTF 2.0, creating realistic colored glass requires simulating how light is absorbed as it travels through a medium, a physical process known as light extinction or attenuation. The KHR_materials_volume extension governs this behavior by implementing the Beer-Lambert law. This article breaks down the specific parameters within KHR_materials_volume—primarily attenuationColor, attenuationDistance, and thickness attributes—that dictate how light diminishes and shifts in color inside transmissive geometry.

Core Parameters for Light Extinction

The KHR_materials_volume extension relies on two primary properties to define the rate and color of light absorption, combined with geometric thickness settings to determine the total path length light travels.

1. attenuationColor

  • Type: Array of three numbers [R, G, B] (values between 0.0 and 1.0)
  • Default: [1.0, 1.0, 1.0] (white / no tint)
  • Function: Defines the resulting color of white light after it has penetrated the medium to a depth equal to the attenuationDistance. Rather than acting like a surface base color, this represents the transmission spectrum of the medium. For example, setting this to a green tint means that red and blue wavelengths are extinguished more rapidly than green wavelengths over distance.

2. attenuationDistance

  • Type: Floating-point number (must be greater than 0.0)
  • Default: +Infinity
  • Function: Specifies the distance in world units over which light must travel to reach the attenuationColor. A smaller attenuationDistance causes light to extinguish rapidly, producing dense, deeply saturated, or opaque glass over short distances. Conversely, a large attenuationDistance results in a very subtle, pale tint, as light must traverse a significant distance before noticeable absorption occurs. If left at its default (infinity), no absorption occurs, regardless of the attenuationColor.

3. thicknessFactor and thicknessTexture

  • Type: Float (thicknessFactor, default 0.0) and Texture Info (thicknessTexture)
  • Function: While attenuationColor and attenuationDistance determine the extinction coefficient, the actual extinction calculation requires a path length. For closed, manifold meshes, renderers can calculate the real physical distance between ray entry and exit points. However, for non-manifold surfaces or performance-optimized workflows, thicknessFactor (optionally modulated by thicknessTexture) defines the thickness of the volume directly below the surface, establishing the optical distance used to compute absorption.

How the Parameters Work Together

The extension calculates light extinction using the Beer-Lambert law:

\[\text{Transmittance} = \text{attenuationColor}^{(\text{distance} / \text{attenuationDistance})}\]

From this formula, the extinction coefficient (\(\mu\)) for each color channel is derived as:

\[\mu = -\frac{\ln(\text{attenuationColor})}{\text{attenuationDistance}}\]

When a ray of light traverses a thickness of glass:

  • Thin areas of the mesh exhibit minimal absorption, appearing brighter and less saturated.
  • Thick sections of the mesh absorb more light, resulting in darker values and highly saturated color.
  • If attenuationColor contains a zero value in any channel, that wavelength is completely extinguished once light travels beyond zero distance.