Directional Lights in glTF KHR_lights_punctual

This article explains the behavior, properties, and implementation details of directional lights defined using the KHR_lights_punctual glTF 2.0 extension. Directional lights act as distant light sources with parallel rays, and understanding their default orientation, radiometric units, node hierarchy interactions, and lack of distance attenuation is essential for accurately rendering glTF assets in 3D engines.

Fundamental Concept and Definition

In the KHR_lights_punctual extension, a directional light represents an analytical light source located at an infinitely distant point. All light rays emitted by a directional light travel parallel to one another across the entire scene. Consequently, unlike point or spot lights, the position of the node hosting the directional light has no effect on illumination—only the node’s orientation dictates how light strikes objects.

In the JSON structure, the light is declared in the root extensions.KHR_lights_punctual.lights array with its type set to "directional", and then referenced by index inside a node's extensions.KHR_lights_punctual property:

{
  "extensions": {
    "KHR_lights_punctual": {
      "lights": [
        {
          "type": "directional",
          "color": [1.0, 1.0, 1.0],
          "intensity": 100000.0
        }
      ]
    }
  }
}

Orientation and Direction Vector

By default in the glTF coordinate space, a directional light points along the local negative Z-axis ([0.0, 0.0, -1.0]).

To determine the final direction of the light in world space:

  1. Start with the local direction vector \(d_{\text{local}} = [0, 0, -1]^T\).
  2. Multiply by the upper-left \(3 \times 3\) portion of the world transformation matrix of the node to which the light is attached.
  3. Normalize the resulting vector.

Translation values in the node transform have no impact on the light's direction or intensity. If a node is rotated, the direction vector rotates accordingly.

Units and Photometric Intensity

The intensity property of a directional light is defined in units of illuminance, measured in lux (lumens per square meter, or \(lm/m^2\)). This differs from point and spot lights, which define intensity in luminous intensity (candela, or \(lm/sr\)).

  • Default Intensity: If omitted, the default intensity is 1.0 lux.
  • Color Multiplication: The color property defines the linear RGB color of the light (defaulting to [1.0, 1.0, 1.0]).
  • Irradiance Calculation: When computing surface lighting, the illuminance \(E\) received by a surface perpendicular to the light rays is:

\[E = \text{intensity} \times \text{color}\]

When accounting for the surface normal \(N\) and the unit vector pointing toward the light source \(L\) (where \(L = -d_{\text{world}}\)), the incident illuminance is attenuated by the cosine factor:

\[E_{\text{surface}} = E \max(N \cdot L, 0)\]

Attenuation and Range Behavior

Directional lights do not attenuate over distance. The inverse-square decay law used for point and spot lights does not apply here.

The range property defined in the KHR_lights_punctual specification is not applicable to directional lights. If a range value is defined on a light entry whose type is "directional", conforming runtime engines must ignore it and treat the light's reach as infinite.