Using glTF PBR Materials in Real-Time Path Tracing

This article explains how real-time ray tracing and path tracing engines consume glTF 2.0 material parameters to evaluate physically based shading models. It covers the pipeline from parsing metallic-roughness texture channels and numeric factors on the host to unpacking them in GPU shader storage buffers, mapping them to microfacet BSDF evaluations in closest-hit shaders, and handling advanced transmission and volume extensions.

The glTF 2.0 PBR Material Model

glTF 2.0 standardizes physically based rendering (PBR) using the Metallic-Roughness workflow. Its core specification defines a dielectric-conductor representation defined by:

  • Base Color (baseColorFactor, baseColorTexture): A linear or sRGB color value representing diffuse reflectance for dielectrics and specular reflectance (\(F_0\)) for metals.
  • Metallic-Roughness (metallicFactor, roughnessFactor, metallicRoughnessTexture): A packed linear texture where the blue channel contains the metalness scalar and the green channel contains the perceptual roughness scalar.
  • Normal Map (normalTexture): A tangent-space normal vector used to perturb surface normals.
  • Emissive (emissiveFactor, emissiveTexture): Radiance emitted directly from the surface.
  • Occlusion (occlusionTexture): Baked ambient occlusion, typically bypassed or repurposed in path tracers since indirect visibility is calculated analytically via ray queries.

Extensions under the KHR_materials_* namespace expand this foundation to support complex phenomena, including KHR_materials_ior (index of refraction), KHR_materials_transmission (thin-walled or volumetric glass), KHR_materials_volume (absorption and scattering), and KHR_materials_clearcoat.

Host-Side Ingestion and GPU Buffer Packing

Real-time ray tracers (built on APIs like DirectX Raytracing or Vulkan Ray Tracing) organize glTF assets into linear GPU buffers accessible via bindless descriptor sets or shader record tables (SRTs).

  1. Texture Loading and Color Spaces: The renderer uploads baseColorTexture and emissiveTexture as sRGB formats (e.g., VK_FORMAT_R8G8B8A8_SRGB), enabling hardware decompression to linear floating-point values upon sampling. The metallicRoughnessTexture and normalTexture are uploaded strictly as linear formats (e.g., VK_FORMAT_R8G8B8A8_UNORM).
  2. Material Data Structures: A unified Material struct is stored in a structured buffer. It packages scalar multipliers, texture array indices, UV transform matrices, and material flags:
struct MaterialData {
    float4 baseColorFactor;
    float3 emissiveFactor;
    float roughnessFactor;
    float metallicFactor;
    float ior;
    float transmissionFactor;
    
    int baseColorIndex;
    int metallicRoughnessIndex;
    int normalIndex;
    int emissiveIndex;
    int transmissionIndex;
};

When building Bottom-Level Acceleration Structures (BLAS), each geometry instance references a material index in its per-primitive or per-instance buffer.

Closest-Hit Shader Execution

When a ray intersects a surface, the ray tracing hardware executes the closest-hit shader. The shader computes the hit point, interpolates vertex attributes (UV coordinates, normals, tangents), and extracts the material parameters.

1. Texture Unpacking

The shader queries bindless texture descriptors:

  • Albedo and Metalness: The shader samples the base color and multiplies it by baseColorFactor. It then samples the metallic-roughness texture, multiplying the green channel by roughnessFactor and the blue channel by metallicFactor.
  • Normal Reconstruction: Tangent-space normals from the normal map are unpacked from \([0, 1]\) to \([-1, 1]\), scaled by normalTexture.scale, and transformed into world space using the geometric Tangent-Bitangent-Normal (TBN) matrix: \[\mathbf{N}_{world} = \text{normalize}(\mathbf{T} \cdot n_x + \mathbf{B} \cdot n_y + \mathbf{N}_{geom} \cdot n_z)\]

2. Deriving Physical BSDF Parameters

Path tracers separate the material response into diffuse and specular Bidirectional Scattering Distribution Functions (BSDFs). The glTF parameters dictate this split:

  • Linear Roughness to Microfacet Roughness: glTF roughness (\(r\)) is perceptual. Path tracers map this to the microfacet parameter \(\alpha = r^2\). For anisotropic extensions, \(\alpha\) is split into \(\alpha_x\) and \(\alpha_y\).
  • Dielectric vs. Conductor \(F_0\):
    • For pure dielectrics (\(\text{metallic} = 0\)), specular reflectance at normal incidence (\(F_0\)) is derived from the index of refraction (\(\eta\)). For glTF’s default IOR of 1.5: \[F_0 = \left(\frac{\eta - 1}{\eta + 1}\right)^2 = \left(\frac{1.5 - 1}{1.5 + 1}\right)^2 \approx 0.04\]
    • For metals (\(\text{metallic} = 1\)), the surface has no diffuse reflection, and \(F_0\) equals the base color.
    • The shader blends between dielectric and conductor states: \[\mathbf{F}_0 = \text{lerp}(0.04 \times \text{iorScalar}, \mathbf{C}_{base}, \text{metallic})\] \[\mathbf{C}_{diffuse} = \mathbf{C}_{base} \times (1.0 - \text{metallic})\]

Microfacet Evaluation and Importance Sampling

With the physical parameters established, the path tracer executes Monte Carlo integration:

  1. Lobe Selection: The shader probabilistically chooses whether to evaluate a diffuse ray (Lambertian) or a specular ray (Cook-Torrance microfacet) based on the surface's Fresnel reflection and metallic-roughness properties.
  2. Sampling the Normal Distribution Function (NDF): For specular reflections, the engine typically implements the Trowbridge-Reitz (GGX) distribution. The next ray direction is generated by importance sampling the Visible Normal Distribution Function (VNDF) parameterized by \(\alpha\).
  3. Geometry Term: Real-time implementations compute shadowing-masking using the Smith formulation with height-correlated visibility: \[G_2(\mathbf{v}, \mathbf{l}) = \frac{2 (\mathbf{n} \cdot \mathbf{v}) (\mathbf{n} \cdot \mathbf{l})}{(\mathbf{n} \cdot \mathbf{l})\sqrt{\alpha^2 + (1-\alpha^2)(\mathbf{n} \cdot \mathbf{v})^2} + (\mathbf{n} \cdot \mathbf{v})\sqrt{\alpha^2 + (1-\alpha^2)(\mathbf{n} \cdot \mathbf{l})^2}}\]
  4. Fresnel Evaluation: The Schlick approximation calculates the ratio of light reflected versus refracted: \[\mathbf{F}(\mathbf{v}, \mathbf{h}) = \mathbf{F}_0 + (1.0 - \mathbf{F}_0)(1.0 - \mathbf{v} \cdot \mathbf{h})^5\]

Handling Transmission and Volumes

When KHR_materials_transmission is present:

  • A transmission factor blends the diffuse BRDF into a specular BTDF (Bidirectional Transmittance Distribution Function).
  • Instead of terminating on a diffuse bounce, rays refract according to Snell's Law using the glTF ior value.
  • If KHR_materials_volume is defined, rays traveling inside the object's interior evaluate Beer-Lambert attenuation using the specified attenuationColor and attenuationDistance: \[T(d) = e^{-\sigma_a d} \quad \text{where} \quad \sigma_a = -\frac{\ln(\mathbf{C}_{attenuation})}{d_{attenuation}}\]

By strictly mapping glTF metallic, roughness, base color, and volume extensions to microfacet distributions and transmittance equations, real-time path tracers produce physically accurate, vendor-neutral rendering matching offline production ground truths.