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).
- Texture Loading and Color Spaces: The renderer
uploads
baseColorTextureandemissiveTextureas sRGB formats (e.g.,VK_FORMAT_R8G8B8A8_SRGB), enabling hardware decompression to linear floating-point values upon sampling. ThemetallicRoughnessTextureandnormalTextureare uploaded strictly as linear formats (e.g.,VK_FORMAT_R8G8B8A8_UNORM). - Material Data Structures: A unified
Materialstruct 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 byroughnessFactorand the blue channel bymetallicFactor. - 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:
- 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.
- 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\).
- 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}}\]
- 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
iorvalue. - If
KHR_materials_volumeis defined, rays traveling inside the object's interior evaluate Beer-Lambert attenuation using the specifiedattenuationColorandattenuationDistance: \[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.