From ef790aac108c4d2f94aed1eda36b9d9342851a66 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 3 Jun 2026 16:24:23 -0700 Subject: [PATCH 1/5] Initial scattering equations for the PBR specification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changelist expands the MaterialX PBR specification with the formal mathematical foundations of its shading nodes, so that the behavior of each BSDF, EDF, and VDF can be reproduced directly from the document rather than from the cited references or shading code implementations. The following specific changes are included: - Add a Scattering Framework section defining the formal notation, the BSDF and EDF distributions, and the descriptive terminology shared by the per-node equations. - Add Reflectance Models and Light Transport sections covering the shared microfacet model, energy conservation, and the governing light transport and volume transfer equations. - Add inline equation sections to each shading node, mapping its artist-facing inputs to the symbols used in its defining equations. - Add an appendix with the extended derivations for the EON, Zeltner sheen, Chiang hair, and thin-film iridescence models. This work was developed as a collaboration betweeen the AOUSD Materials Working Group and the ASWF. The first iteration of the Scattering Framework was written by Anders Langlands, and early review and feedback were provided by André Mazzone, Stephen Hill, and Arnon Marcus. --- documents/Specification/MaterialX.PBRSpec.md | 1233 +++++++++++++++++- 1 file changed, 1212 insertions(+), 21 deletions(-) diff --git a/documents/Specification/MaterialX.PBRSpec.md b/documents/Specification/MaterialX.PBRSpec.md index d748dabb96..131f9fa499 100644 --- a/documents/Specification/MaterialX.PBRSpec.md +++ b/documents/Specification/MaterialX.PBRSpec.md @@ -9,7 +9,7 @@ MaterialX Physically Based Shading Nodes v1.39 Niklas Harrysson - Lumiere Software Doug Smythe - Industrial Light & Magic Jonathan Stone - Lucasfilm Advanced Development Group -December 22, 2025 +June 5, 2026 # Introduction @@ -28,9 +28,22 @@ This document describes a number of shader-semantic nodes implementing widely-us  [Surfaces](#surfaces)   [Layering](#layering)   [Bump and Normal Mapping](#bump-and-normal-mapping) -  [Surface Thickness](#surface-thickness)  [Volumes](#volumes)  [Lights](#lights) + [Scattering Framework](#scattering-framework) +  [Symbols](#symbols) +  [Media, Interfaces, and Scattering Events](#media-interfaces-and-scattering-events) +  [Bidirectional Scattering Distribution Function](#bidirectional-scattering-distribution-function) +  [Emission Distribution Function](#emission-distribution-function) +  [Reflection and Transmission](#reflection-and-transmission) +  [Diffuse, Glossy, and Specular](#diffuse-glossy-and-specular) + [Reflectance Models](#reflectance-models) +  [Microfacet Model](#microfacet-model) +  [Directional Albedo and Energy Conservation](#directional-albedo-and-energy-conservation) +  [Thin-Film Iridescence](#thin-film-iridescence) + [Light Transport](#light-transport) +  [The Light Transport Equation](#the-light-transport-equation) +  [The Equation of Transfer](#the-equation-of-transfer) **[MaterialX PBS Library](#materialx-pbs-library)**  [Data Types](#data-types) @@ -46,6 +59,13 @@ This document describes a number of shader-semantic nodes implementing widely-us  [Khronos glTF PBR](#khronos-gltf-pbr)  [OpenPBR Surface](#openpbr-surface) +**[Appendix: Extended Reflectance Models](#appendix-extended-reflectance-models)** + [EON Reflectance Model](#eon-reflectance-model) + [Subsurface Scattering Model](#subsurface-scattering-model) + [Zeltner Sheen Model](#zeltner-sheen-model) + [Chiang Hair Model](#chiang-hair-model) + [Thin-Film Iridescence Model](#thin-film-iridescence-model) + **[References](#references)**
@@ -70,7 +90,9 @@ The initial requirements for a physically-plausible material are that it 1) shou ## Quantities and Units -Radiometric quantities are used by the material model for interactions with the renderer. The fundamental radiometric quantity is **radiance** (measured in _Wm−2sr−1_) and gives the intensity of light arriving at, or leaving from, a given point in a given direction. If incident radiance is integrated over all directions we get **irradiance** (measured in _Wm−2_), and if we integrate this over surface area we get **power** (measured in _W_). Input parameters for materials and lights specified in photometric units can be suitably converted to their radiometric counterparts before being submitted to the renderer. +Radiometric quantities are used by the material model for interactions with the renderer. The fundamental radiometric quantity is **radiance** (measured in $W\\,m^{-2}\\,sr^{-1}$) and gives the intensity of light arriving at, or leaving from, a given point in a given direction. If incident radiance is integrated over all directions we get **irradiance** (measured in $W\\,m^{-2}$), and if we integrate this over surface area we get **power** (measured in $W$). Input parameters for materials and lights specified in photometric units can be suitably converted to their radiometric counterparts before being submitted to the renderer. + +When the renderer operates in RGB rather than on a full spectrum, each of the red, green, and blue channels carries the convolution of a spectral radiance distribution with a sensor response function, so the quantity actually transported is neither spectral radiance nor luminance, but an _integrated radiance_, also called a _tristimulus weight_. The radiometric units used throughout this document should therefore be understood as nominal: they identify the physical quantity that each value represents in an idealized spectral sense, and fix the relative scaling between quantities, while the absolute scale of emission and the mapping to displayed pixel values are governed by the renderer's exposure and color-management conventions. The interpretation of the data types returned by surface and volume shaders are unspecified, and left to the renderer and the shader generator for that renderer to decide. For an OpenGL-type renderer they will be tuples of floats containing radiance calculated directly by the shader node, but for an OSL-type renderer they may be closure primitives that are used by the renderer in the light transport simulation. @@ -119,9 +141,9 @@ The surface normal used for shading calculations is supplied as input to each BS ## Volumes -In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function, _describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate of absorption for light traveling through the medium, and the **scattering coefficient** sets the rate of which the light is scattered from its current direction. The unit for these are _m−1_. +In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function, _describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate of absorption for light traveling through the medium, and the **scattering coefficient** sets the rate of which the light is scattered from its current direction. The unit for these are $m^{-1}$. -Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is _Wm−3sr−1_. The emission distribution is oriented along the current direction. +Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $W\\,m^{-3}\\,sr^{-1}$. The emission distribution is oriented along the current direction. The [<volume>](#node-volume) node in the PBS library constructs a volume shader from individual VDF and EDF components. There are also nodes to construct various VDFs, as well as nodes to combine them to build more complex ones. @@ -136,6 +158,244 @@ Local lights are specified as light shaders assigned to a locator, modeling an e Light contributions coming from far away are handled by environment lights. These are typically photographically-captured or procedurally-generated images that surround the whole scene. This category of lights also includes sources like the sun, where the long distance traveled makes the light essentially directional and without falloff. For all shading points, an environment is seen as being infinitely far away. + +## Scattering Framework + +The [Surfaces](#surfaces) and [Volumes](#volumes) sections above introduce the BSDF, EDF, and VDF informally. This section defines the formal notation, the scattering and emission distribution functions, and the descriptive terminology used by the per-node equations in the [MaterialX PBS Library](#materialx-pbs-library) chapter below. + +### Symbols + +In scattering equations, the subscript $_i$ denotes a quantity related to the *incoming* direction, and the subscript $_o$ denotes a quantity related to the *outgoing* direction. Depending on the rendering algorithm in use, these notions may be reversed or not well-defined. For the purposes of this document, we assume a unidirectional path-tracing algorithm: the outgoing direction $\omega_o$ points along the path toward the eye, and the incoming direction $\omega_i$ points along the path away from the eye. Both vectors are defined at a position $p$ and both point away from that position. + +|Symbol|Description| +|------|-----------| +|$L_i$|Incident radiance at $p$ along direction $\omega_i$| +|$L_o$|Exitant radiance at $p$ along direction $\omega_o$| +|$L_e$|Emitted radiance at $p$ along direction $\omega_o$| +|$p$|Position of a scattering event on a surface or in a volume| +|$n$|Unit surface normal vector at $p$| +|$\omega_i$|Direction from $p$ along which incident radiance arrives| +|$\omega_o$|Direction from $p$ along which exitant radiance leaves| +|$\omega_h = \dfrac{\omega_i + \omega_o}{\lVert \omega_i + \omega_o \rVert}$|Half-vector between $\omega_i$ and $\omega_o$| +|$\theta$|Elevation angle of a direction from the surface normal| +|$\theta_i$|Elevation angle of the incident direction| +|$\theta_o$|Elevation angle of the exitant direction| +|$\theta_t$|Elevation angle of the exitant transmitted direction, measured from the inverted surface normal| +|$\phi$|Azimuthal angle of a direction around the surface normal| +|$\phi_i$|Azimuthal angle of the incident direction| +|$\phi_o$|Azimuthal angle of the exitant direction| +|$\Omega_i$|Hemisphere of incident directions around the surface normal| +|$\mathbb{S}^2$|Unit sphere of directions around $p$| +|$\eta_i$|Absolute index of refraction of the medium on the incident side of an interface| +|$\eta_t$|Absolute index of refraction of the medium on the transmitted side of an interface| +|$\eta = \eta_t / \eta_i$|Relative index of refraction across an interface| + + +### Media, Interfaces, and Scattering Events + +A **medium** is a distribution of matter contained in some (possibly infinite or semi-infinite) region of space; its properties dictate how it interacts with electromagnetic radiation such as visible light. An **interface** is a boundary between two media of different properties. A **volume** is a three-dimensional region of space containing a medium, and a **surface** is a geometric representation of an interface. + +A **scattering event** occurs when radiance arriving at a position $p$ from direction $\omega_i$ is redirected along a new direction $\omega_o$. The energy arriving along $\omega_i$ need not be fully redirected along $\omega_o$ — the remainder is absorbed or scattered in other directions. + + +### Bidirectional Scattering Distribution Function + +The **bidirectional scattering distribution function** (BSDF) describes the proportion of radiance scattered at a surface from an incoming direction $\omega_i$ to an outgoing direction $\omega_o$: + +```math +f(\omega_i, \omega_o) = \frac{dL_o}{L_i \cos\theta_i \; d\omega_i} +``` +

+ +The **bidirectional reflectance distribution function** $f_r(\omega_i, \omega_o)$ (BRDF) and **bidirectional transmittance distribution function** $f_t(\omega_i, \omega_o)$ (BTDF) are specializations of the BSDF. For the BRDF, $\omega_i$ and $\omega_o$ lie in the same hemisphere; for the BTDF, they lie in opposite hemispheres. + +Further specializations include the **bidirectional curve-scattering distribution function** $f_c$ (BCSDF), which defines scattering between directions from an infinitesimally thin cylinder as used by [<chiang_hair_bsdf>](#node-chiang-hair-bsdf), and the **bidirectional subsurface-scattering distribution function** $f_{\text{sss}}(\omega_i, \omega_o, p_i, p_o)$, which defines scattering between directions and between positions on a surface as used by [<subsurface_bsdf>](#node-subsurface-bsdf). + + +### Emission Distribution Function + +The **emission distribution function** (EDF) describes the radiance emitted at a position $p$ along an outgoing direction $\omega_o$. For a surface emitting radiant flux $\Phi_e$, the emitted radiance is: + +```math +L_e(\omega_o) = \frac{d^2\Phi_e}{dA \, \cos\theta_o \; d\omega_o} +``` +

+ +where $dA$ is the differential area around $p$. Unlike the BSDF, the EDF is a function of a single direction and carries no dependence on an incident direction or cosine factor. For surface EDFs, $L_e$ has units of $W\\,m^{-2}\\,sr^{-1}$; for volume EDFs, $W\\,m^{-3}\\,sr^{-1}$. + + +### Reflection and Transmission + +**Reflection** is a scattering event where the exitant direction $\omega_o$ lies in the same hemisphere as the incident direction $\omega_i$, that is: + +```math +\mathrm{sgn}(\omega_i \cdot n) = \mathrm{sgn}(\omega_o \cdot n) +``` +

+ +**Transmission** is a scattering event where $\omega_o$ lies in the opposite hemisphere from $\omega_i$, that is: + +```math +\mathrm{sgn}(\omega_i \cdot n) \ne \mathrm{sgn}(\omega_o \cdot n) +``` +

+ +The **reflectance** and **transmittance** are the fractions of incident energy leaving a scattering event via reflection and transmission, respectively. + +The **reflection direction** $\omega_r$ of $\omega_i$ about a surface or microfacet normal is: + +```math +\omega_r = 2(\omega_i \cdot n) n - \omega_i +``` +

+ +The **refraction direction** $\omega_t$ of $\omega_i$ about a surface or microfacet normal, for media with incident and transmitted indices of refraction $\eta_i$ and $\eta_t$, is: + +```math +\cos\theta_t = \sqrt{1 - \left(\frac{\eta_i}{\eta_t}\right)^2 \sin^2\theta_i} +``` +

+ +```math +\omega_t = -\frac{\eta_i}{\eta_t} \omega_i + \left(\frac{\eta_i}{\eta_t}\cos\theta_i - \cos\theta_t\right) n +``` +

+ + +### Diffuse, Glossy, and Specular + +The terms **diffuse**, **glossy**, and **specular** offer a perceptual classification of scattering distributions. They are not precisely defined, but are useful when describing and comparing BSDFs. The distinction concerns how broadly or narrowly the scattered energy is distributed across exitant directions, rather than which directions receive energy: + +* **Diffuse**: scattered energy is spread broadly across a hemisphere (either upper or lower) around the surface normal, varying only gradually with exitant direction. +* **Specular**: scattered energy is concentrated entirely, or almost entirely, along the reflection or refraction direction. The idealized perfectly specular case is a Dirac delta distribution that carries all of its energy in that single direction. +* **Glossy**: scattered energy is concentrated about the reflection or refraction direction but spread more broadly than in the specular case, forming the intermediate regime between diffuse and specular. + + +## Reflectance Models + +This section defines the shared reflectance models referenced by multiple BSDF nodes in the [MaterialX PBS Library](#materialx-pbs-library) below. + +### Microfacet Model + +The [<dielectric_bsdf>](#node-dielectric-bsdf), [<conductor_bsdf>](#node-conductor-bsdf), and [<generalized_schlick_bsdf>](#node-generalized-schlick-bsdf) nodes share a microfacet model[^Walter2007] in which a surface is treated as a collection of infinitesimal, perfectly specular mirrors (**microfacets**) whose orientations are distributed around the macroscopic surface normal. All three nodes use the microfacet BRDF for reflection. The [<dielectric_bsdf>](#node-dielectric-bsdf) and [<generalized_schlick_bsdf>](#node-generalized-schlick-bsdf) nodes additionally use the microfacet BTDF for transmission when `scatter_mode` is set to T or RT. + +Both the BRDF and BTDF share a common normal distribution function $D$ and masking-shadowing function $G_2$, and differ in their geometric and Fresnel terms. The Fresnel reflectance $F$ is defined per node. + +#### Microfacet BRDF + +```math +f_r(\omega_i, \omega_o) = \frac{D(\omega_h) F(\omega_i, \omega_h) G_2(\omega_i, \omega_o)}{4 \cos\theta_i \cos\theta_o} +``` +

+ +where $\omega_h$ is the half-vector between $\omega_i$ and $\omega_o$ as defined in the [Symbols](#symbols) table. + +#### Microfacet BTDF + +The microfacet BTDF uses a transmission half-vector that accounts for the change in index of refraction across the interface: + +```math +\omega_{ht} = -\frac{\eta_i \omega_i + \eta_t \omega_o}{\lVert \eta_i \omega_i + \eta_t \omega_o \rVert} +``` +

+ +where $\eta_i$ and $\eta_t$ are the absolute indices of refraction of the incident and transmitted media, whose ratio $\eta_t/\eta_i$ is the relative index $\eta$ of the [Symbols](#symbols) table. The BTDF is: + +```math +f_t(\omega_i, \omega_o) = \frac{|\omega_i \cdot \omega_{ht}| \cdot |\omega_o \cdot \omega_{ht}|}{\cos\theta_i \cos\theta_t} \cdot \frac{\eta_t^2 (1 - F(\omega_i, \omega_{ht})) D(\omega_{ht}) G_2(\omega_i, \omega_o)}{(\eta_i (\omega_i \cdot \omega_{ht}) + \eta_t (\omega_o \cdot \omega_{ht}))^2} +``` +

+ +where $1 - F$ is the Fresnel transmittance, the complement of the Fresnel reflectance defined per node. + +#### GGX Normal Distribution Function + +The microfacet normal distribution is the anisotropic GGX (Trowbridge-Reitz) function[^Walter2007]: + +```math +D(\omega_h) = \frac{1}{\pi \alpha_x \alpha_y\left(\left(\dfrac{h_x}{\alpha_x}\right)^2 + \left(\dfrac{h_y}{\alpha_y}\right)^2 + h_z^2\right)^2} +``` +

+ +where $\alpha_x$ and $\alpha_y$ are the roughness values along the surface tangent and bitangent, and $h_x$, $h_y$, $h_z$ are the components of $\omega_h$ (or $\omega_{ht}$ for transmission) in the local tangent frame. + +The pair $(\alpha_x, \alpha_y)$ is supplied directly by the `roughness` input of each microfacet node, with no internal remapping. These low-level values may be computed from perceptual roughness and glossiness parameterizations using the [<roughness_anisotropy>](#node-roughness-anisotropy), [<roughness_dual>](#node-roughness-dual), and [<glossiness_anisotropy>](#node-glossiness-anisotropy) utility nodes. + +#### Height-Correlated Smith Masking-Shadowing + +The joint masking-shadowing function is the height-correlated form of the Smith function[^Heitz2014]: + +```math +G_2(\omega_i, \omega_o) = \frac{2 \cos\theta_i \cos\theta_o}{\lambda_o \cos\theta_i + \lambda_i \cos\theta_o} +``` +

+ +where $\lambda_i = \lambda(\cos\theta_i)$, $\lambda_o = \lambda(\cos\theta_o)$, $\lambda(\cos\theta) = \sqrt{\alpha^2 + (1 - \alpha^2) \cos^2\theta}$, and $\alpha = \sqrt{\alpha_x \alpha_y}$ when the roughness is anisotropic. + + +### Directional Albedo and Energy Conservation + +The **directional albedo** $E_o$ of a BSDF is its integral over all incident directions, for a fixed exitant direction $\omega_o$: + +```math +E_o = \int_{\Omega_i} f(\omega_i, \omega_o) \cos\theta_i \; d\omega_i +``` +

+ +The directional albedo is the quantity referenced by the [<layer>](#node-layer) node when performing albedo-scaled vertical layering of a top BSDF over a base. + +#### Energy Compensation + +The single-scattering microfacet BRDF does not account for light that scatters multiple times between microfacets before leaving the surface. As roughness increases, the energy lost to these unmodeled paths becomes significant, and is compensated using a multiplicative correction factor[^Turquin2019]: + +```math +f_r^{\text{comp}}(\omega_i, \omega_o) = f_r(\omega_i, \omega_o)\left(1 + F_{\text{ss}} \frac{1 - E_{\text{ss}}}{E_{\text{ss}}}\right) +``` +

+ +where $E_{\text{ss}}$ is the directional albedo of the microfacet BRDF evaluated with unit Fresnel ($F = 1$), and $F_{\text{ss}}$ is the cosine-weighted hemispherical average of the Fresnel reflectance of the BSDF being compensated. + + +### Thin-Film Iridescence + +The [<dielectric_bsdf>](#node-dielectric-bsdf), [<conductor_bsdf>](#node-conductor-bsdf), and [<generalized_schlick_bsdf>](#node-generalized-schlick-bsdf) nodes support an optional thin-film interference effect[^Belcour2017]. A thin dielectric film of thickness $d$ (in nanometers) and index of refraction $\eta_2$ is placed between the outer medium ($\eta_1$, assumed to be vacuum with $\eta_1 = 1$) and the node's substrate. The substrate is characterized by its own optical properties: a real-valued IOR $\eta_3$ for dielectrics, a complex IOR $(\eta_3, \kappa_3)$ for conductors, or Schlick reflectance values mapped to an effective $\eta_3$. + +When `thinfilm_thickness` is set to a non-zero value, the standard Fresnel reflectance $F$ defined by each node is replaced by the Airy reflectance $F_{\text{airy}}$, computed by summing the contributions of successive reflections between the two interfaces of the film. The reflectance is evaluated independently for the parallel (p) and perpendicular (s) polarization states and averaged: + +```math +F_{\text{airy}} = \tfrac{1}{2} \sum_{\text{pol} \in \{p,s\}} \left[ R_{12} + \frac{T_{12}^2 R_{23}}{1 - R_{12} R_{23}} + \sum_{m=1}^{M} C_m S_m \right] +``` +

+ +where $R_{12}$ and $R_{23}$ are the polarized Fresnel reflectances at the first (air–film) and second (film–substrate) interfaces, $T_{12} = 1 - R_{12}$ is the transmittance through the first interface, $C_m$ are amplitude coefficients that account for successive bounces within the film, and $S_m$ encodes the spectral interference pattern for bounce order $m$ as a function of the optical path difference and accumulated phase shifts. The result is converted from a spectral representation to RGB. The full derivation, including polarized phase shifts and spectral-to-RGB conversion, is given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix. + + +## Light Transport + +The [BSDF](#bidirectional-scattering-distribution-function) and [EDF](#emission-distribution-function) describe scattering and emission at a single point. The equations in this section describe how those local distributions, together with the radiance arriving from the rest of the scene, determine the radiance leaving a point, following the formulation of Pharr et al.[^Pharr2023]. The [<surface>](#node-surface), [<volume>](#node-volume), and [<light>](#node-light) shader nodes assemble per-node BSDFs, EDFs, and VDFs into these equations. + +### The Light Transport Equation + +For a surface, the exitant radiance $L_o$ leaving a point $p$ along direction $\omega_o$ is the sum of the radiance emitted at $p$ and the radiance scattered toward $\omega_o$ from all incident directions: + +```math +L_o(\omega_o) = L_e(\omega_o) + \int_{\mathbb{S}^2} f(\omega_i, \omega_o)\, L_i(\omega_i)\, |\omega_i \cdot n|\; d\omega_i +``` +

+ +where $f$ is the surface BSDF, $L_e$ is the surface EDF, and $L_i(\omega_i)$ is the radiance incident at $p$ from direction $\omega_i$. The integral is taken over the entire sphere of directions $\mathbb{S}^2$ rather than a single hemisphere, so that transmissive BSDFs — whose incident and exitant directions lie in opposite hemispheres — are included. The factor $|\omega_i \cdot n| = |\cos\theta_i|$ accounts for the projected solid angle of the incident direction. + +### The Equation of Transfer + +For a participating medium, radiance is continuously attenuated by absorption and out-scattering and augmented by emission and in-scattering. The change in radiance $L$ per unit distance traveled along $\omega_o$ is given by the equation of transfer: + +```math +(\omega_o \cdot \nabla)\, L(p, \omega_o) = -\sigma_t\, L(p, \omega_o) + \sigma_s \int_{\mathbb{S}^2} f_p(\omega_i, \omega_o)\, L(p, \omega_i)\; d\omega_i + L_e(p, \omega_o) +``` +

+ +The first term attenuates radiance by the extinction coefficient $\sigma_t = \sigma_a + \sigma_s$. The second adds radiance scattered into $\omega_o$ from all directions, weighted by the scattering coefficient $\sigma_s$ and the phase function $f_p$. The final term $L_e$ is the volume emission, stated in $W\\,m^{-3}\\,sr^{-1}$; it corresponds to the product $\sigma_a L_e$ of an absorption coefficient and an emitted radiance in the formulation of Pharr et al.[^Pharr2023]. The coefficients $\sigma_a$, $\sigma_s$ and the phase function $f_p$ are supplied by the medium's [VDF](#vdf-nodes), and $L_e$ by its [EDF](#edf-nodes). +
@@ -160,6 +420,8 @@ The PBS nodes also make use of the following standard MaterialX types: ## BSDF Nodes +The equations below use the symbols and notation defined in the [Scattering Framework](#scattering-framework), together with the shared reflectance models defined in [Reflectance Models](#reflectance-models). + ### `oren_nayar_diffuse_bsdf` @@ -178,6 +440,34 @@ An `energy_compensation` boolean selects between the Qualitative Oren-Nayar[^Ore |`energy_compensation`|Enable energy compensation for the BSDF|boolean|false | | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `color` input corresponds to $\rho$, the diffuse albedo, and the `roughness` input corresponds to $\sigma$, where $\sigma \in [0, 1]$. + +#### Qualitative Oren-Nayar Reflectance Equations + +```math +A = 1 - 0.5\left(\frac{\sigma^2}{\sigma^2 + 0.33}\right) +``` +

+ +```math +B = 0.45\left(\frac{\sigma^2}{\sigma^2 + 0.09}\right) +``` +

+ +```math +g(\omega_i,\omega_o) = \max\left(0, \cos(\phi_i - \phi_o)\right)\sin\alpha \tan\beta,\quad \alpha = \max(\theta_i,\theta_o),\quad \beta = \min(\theta_i,\theta_o) +``` +

+ +```math +f_r(\omega_i,\omega_o) = \frac{\rho}{\pi}\bigl(A + B g(\omega_i,\omega_o)\bigr) +``` +

+ +#### Energy-Preserving Oren-Nayar (EON) Reflectance Equations + +When `energy_compensation` is enabled, the EON model[^Portsmouth2025] decomposes the BRDF into a single-scatter lobe based on Fujii's improved Oren-Nayar formulation[^Fujii2020] and a multi-scatter lobe that compensates for inter-reflection energy lost at higher roughness values. The full derivation is given in the [EON Reflectance Model](#eon-reflectance-model) appendix. + ### `burley_diffuse_bsdf` @@ -191,6 +481,27 @@ Constructs a diffuse reflection BSDF based on the corresponding component of the |`normal` |Normal vector of the surface |vector3 |Nworld | | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `color` input corresponds to $\rho$, the diffuse albedo, and the `roughness` input corresponds to $\sigma$, a perceptual roughness controlling the transition from Fresnel darkening at grazing angles for smooth surfaces to retroreflection for rough surfaces. + +#### Burley Diffuse Reflectance Equations + +The model uses a modified Schlick Fresnel factor with $F_0 = 1$ (no modification at normal incidence) and a roughness-dependent grazing term $F_{D90}$: + +```math +F_{D90} = \tfrac{1}{2} + 2\sigma (\omega_i \cdot \omega_h)^2 +``` +

+ +```math +F_D(\theta) = 1 + (F_{D90} - 1)(1 - \cos\theta)^5 +``` +

+ +```math +f_r(\omega_i, \omega_o) = \frac{\rho}{\pi} F_D(\theta_i) F_D(\theta_o) +``` +

+ ### `dielectric_bsdf` @@ -200,7 +511,7 @@ Implementations are expected to preserve energy as the roughness of the surface The `tint` input colors the reflected and transmitted light but should be left at white (1,1,1) for physically correct results. Setting the `ior` input to zero disables the Fresnel curve, allowing reflectivity to be controlled purely by weight and tint. -Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Raab2025]. +Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Portsmouth2026]. Thin-film iridescence effects[^Belcour2017] may be enabled by setting `thinfilm_thickness` to a non-zero value. @@ -221,6 +532,35 @@ The `scatter_mode` controls whether the surface reflects light (`R`), transmits |`scatter_mode` |Surface Scatter mode, specifying reflection and/or transmission|string |R |R, T, RT | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `tint` input corresponds to $t$ and the `ior` input corresponds to $\eta$, the real-valued index of refraction of the surface *relative to the exterior medium*. The Fresnel formulation below assumes the exterior medium is air/vacuum ($\eta_i \approx 1$), so $\eta$ is equivalently the ratio of the surface IOR to that of the medium on the incident side of the interface. + +The tint $t$ scales the node's reflection and transmission lobes directly, multiplying the [microfacet BRDF and BTDF](#microfacet-model) as $t f_r$ and $t f_t$. It does not modify the Fresnel reflectance $F$ itself, so the Fresnel transmittance $1 - F$ used by the BTDF remains untinted. + +#### Dielectric Fresnel Equations + +The Fresnel reflectance $F$ is computed from the standard Fresnel equations for unpolarized light[^Walter2007], using the optimized formulation given by Lagarde[^Lagarde2013]: + +```math +c = \cos\theta +``` +

+ +```math +g = \sqrt{\eta^2 + c^2 - 1} +``` +

+ +```math +F = \frac{1}{2}\cdot\frac{(g - c)^2}{(g + c)^2}\left(1 + \frac{\bigl(c(g + c) - 1\bigr)^2}{\bigl(c(g - c) + 1\bigr)^2}\right) +``` +

+ +When $\eta^2 + c^2 < 1$, the quantity $g$ is imaginary and total internal reflection occurs, in which case $F = 1$. + +#### Thin-Film Iridescence + +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is set to the node's `ior` input $\eta$, with $\kappa_3 = 0$ (lossless dielectric). + ### `conductor_bsdf` @@ -230,7 +570,7 @@ Implementations are expected to preserve energy as the roughness of the surface The default values for `ior` and `extinction` represent approximate values for gold. -Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Raab2025]. +Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Portsmouth2026]. Thin-film iridescence effects[^Belcour2017] may be enabled by setting `thinfilm_thickness` to a non-zero value. @@ -248,6 +588,41 @@ Thin-film iridescence effects[^Belcour2017] may be enabled by setting `thinfilm_ |`distribution` |Microfacet distribution type |string |ggx |ggx | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `ior` input corresponds to $\eta$, the index of refraction per color channel, and the `extinction` input corresponds to $\kappa$, the extinction coefficient per color channel. Together, these define the complex index of refraction $\eta + i\kappa$ of the conductor. + +#### Conductor Fresnel Equations + +The reflectance $F$ is the average of the s-polarized ($R_s$) and p-polarized ($R_p$) Fresnel reflectances at a conductor interface[^Lagarde2013]: + +```math +a^2 + b^2 = \sqrt{(\eta^2 - \kappa^2 - \sin^2\theta)^2 + 4\eta^2 \kappa^2} +``` +

+ +```math +a = \sqrt{\max\left(0, \tfrac{1}{2}(a^2 + b^2 + \eta^2 - \kappa^2 - \sin^2\theta)\right)} +``` +

+ +```math +R_s = \frac{a^2 + b^2 - 2a \cdot \cos\theta + \cos^2\theta}{a^2 + b^2 + 2a \cdot \cos\theta + \cos^2\theta} +``` +

+ +```math +R_p = R_s \cdot \frac{\cos^2\theta (a^2 + b^2) - 2a \cdot \cos\theta\sin^2\theta + \sin^4\theta}{\cos^2\theta (a^2 + b^2) + 2a \cdot \cos\theta\sin^2\theta + \sin^4\theta} +``` +

+ +```math +F = \tfrac{1}{2}(R_s + R_p) +``` +

+ +#### Thin-Film Iridescence + +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate is defined by the node's complex index of refraction, with $\eta_3 = \eta$ and $\kappa_3 = \kappa$. The polarized phase shifts at the film–substrate interface are computed using the conductor phase formula given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix. + ### `generalized_schlick_bsdf` @@ -257,7 +632,7 @@ Implementations are expected to preserve energy as the roughness of the surface The `color82` input provides a multiplier on reflectivity at 82 degrees, useful for capturing the characteristic "dip" in the reflectance curve of metallic surfaces. Setting it to (1,1,1) effectively disables this feature for backward compatibility. -Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Raab2025]. +Setting `retroreflective` to true switches the BSDF to retroreflection mode, where light is reflected back toward the incoming direction rather than the mirror reflection direction[^Portsmouth2026]. Thin-film iridescence effects[^Belcour2017] may be enabled by setting `thinfilm_thickness` to a non-zero value. @@ -280,6 +655,31 @@ The `scatter_mode` behavior matches that of `dielectric_bsdf`: in `RT` mode, ref |`scatter_mode` |Surface Scatter mode, specifying reflection and/or transmission|string |R |R, T, RT | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `color0` and `color90` inputs correspond to $r_0$ and $r_{90}$, the `color82` input corresponds to $t$, and the `exponent` input corresponds to $q$ in the generalized Schlick model. + +#### Generalized Schlick Equations + +The Hoffman[^Hoffman2023] generalization of the Schlick Fresnel curve adds a controllable dip in the reflectance at $\theta_{\max} = \arccos(1/7) \approx 81.79°$, whose depth is set by the `color82` multiplier $t$: + +```math +\cos\theta_{\max} = \frac{1}{7} +``` +

+ +```math +a = \frac{\bigl[r_0 + (r_{90} - r_0)(1 - \cos\theta_{\max})^{q}\bigr](1 - t)}{\cos\theta_{\max}(1 - \cos\theta_{\max})^{6}} +``` +

+ +```math +F_{\theta} = r_0 + (r_{90} - r_0)(1 - \cos\theta)^{q} - a \cdot \cos\theta (1 - \cos\theta)^{6} +``` +

+ +#### Thin-Film Iridescence + +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F_{\theta}$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is derived from the `color0` input $r_0$ using the standard Schlick-to-IOR inversion, with $\kappa_3 = 0$. + ### `translucent_bsdf` @@ -292,10 +692,21 @@ Constructs a translucent (diffuse transmission) BSDF based on the Lambert reflec |`normal` |Normal vector of the surface |vector3|Nworld | | |`out` |Output: the computed BSDF |BSDF | | | +In the equation below, the `color` input corresponds to $\rho$, the diffuse transmittance. + +#### Lambertian Transmittance Equation + +The node implements a Lambertian BTDF, the transmission analog of the Lambertian BRDF. Incident light is scattered uniformly over the lower hemisphere (the opposite side of the surface from the incident direction): + +```math +f_t(\omega_i, \omega_o) = \frac{\rho}{\pi} +``` +

+ ### `subsurface_bsdf` -Constructs a subsurface scattering BSDF for subsurface scattering within a homogeneous medium. The parameterization is chosen to match random walk Monte Carlo methods as well as approximate empirical methods[^Christensen2015]. Note that this category of subsurface scattering can be defined more rigorously as a BSDF vertically layered over an [](#node-anisotropic-vdf), and we expect these two descriptions of the scattering-surface distribution function to be unified in future versions of MaterialX. +Constructs a subsurface scattering BSDF for subsurface scattering within a homogeneous medium. The parameterization is chosen to match random walk Monte Carlo methods[^Kulla2017] as well as approximate empirical methods[^Christensen2015]. This node is defined compositionally as a BSDF vertically layered over an [<anisotropic_vdf>](#node-anisotropic-vdf), as detailed below. The `radius` input sets the average distance (mean free path) that light propagates below the surface before scattering back out, and can be set independently for each color channel. @@ -310,6 +721,12 @@ The `anisotropy` input controls the scattering direction: negative values produc |`normal` |Normal vector of the surface |vector3|Nworld | | |`out` |Output: the computed BSDF |BSDF | | | +#### Compositional Structure + +The node's scattering behavior is equivalent to an untinted Lambertian transmission surface — [<translucent_bsdf>](#node-translucent-bsdf) with unit color — vertically layered over a participating medium described by [<anisotropic_vdf>](#node-anisotropic-vdf). Incident light enters the medium through the surface, scatters with phase function asymmetry $g$ (the `anisotropy` input), and exits at a potentially different surface position; its coloring is determined entirely by the volumetric absorption, not by the surface transmission. The resulting distribution function therefore depends on both the incident and exitant surface positions ($p_i$ and $p_o$), as introduced in the [Bidirectional Scattering Distribution Function](#bidirectional-scattering-distribution-function) section. + +The artist-facing `color` and `radius` inputs are converted to the volume's physical absorption and scattering coefficients by an albedo inversion, and a renderer may evaluate the result either directly via random-walk volumetric transport or through an equivalent normalized diffusion approximation. These conversions and the diffusion profile are given in the [Subsurface Scattering Model](#subsurface-scattering-model) appendix. + ### `sheen_bsdf` @@ -324,12 +741,30 @@ Constructs a microfacet BSDF for the back-scattering properties of cloth-like ma |`mode` |Selects between `conty_kulla` and `zeltner` sheen models|string |conty_kulla |conty_kulla, zeltner| |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `color` input corresponds to $c$, a non-physical color tint on the sheen lobe, and the `roughness` input corresponds to $r$, the degree to which the microfibers diverge from the surface normal. + +#### Conty-Kulla Sheen Equations + +```math +D(\theta_h) = \frac{\left(2 + \dfrac{1}{r}\right)\left(1 - \cos^2\theta_h\right)^{\frac{1}{2r}}}{2\pi} +``` +

+ +```math +f_r(\omega_i,\omega_o,\omega_h) = \frac{c D(\theta_h)}{4(\cos\theta_i + \cos\theta_o - \cos\theta_i\cos\theta_o)} +``` +

+ +#### Zeltner Sheen Equations + +When `mode` is set to `zeltner`, the Zeltner sheen model[^Zeltner2022] approximates multi-scattering cloth reflectance using a Linearly Transformed Cosine (LTC) lobe. The full derivation and fitted coefficients are given in the [Zeltner Sheen Model](#zeltner-sheen-model) appendix. + ### `chiang_hair_bsdf` Constructs a hair BSDF based on the Chiang hair shading model[^Chiang2016]. This node does not support vertical layering. -The roughness inputs control longitudinal (ν) and azimuthal (s) roughness for each lobe, with (0,0) specifying pure specular scattering. The default `ior` of 1.55 represents the index of refraction for keratin. The `cuticle_angle` is in radians, with 0.5 representing no tilt, and values above 0.5 tilting the scales toward the root of the fiber. +The roughness inputs provide a longitudinal variance $v$ and an azimuthal logistic scale $s$ for each lobe, with (0,0) specifying pure specular scattering. These low-level parameters may be computed from artist-facing longitudinal and azimuthal roughness values using the [<chiang_hair_roughness>](#node-chiang-hair-roughness) utility node. The default `ior` of 1.55 represents the index of refraction for keratin. The `cuticle_angle` is a normalized value in $[0, 1]$, with 0.5 representing no tilt, and values above 0.5 tilting the scales toward the root of the fiber. |Port |Description |Type |Default |Accepted Values| |------------------------|--------------------------------------------------------|-------|-------------|---------------| @@ -337,34 +772,60 @@ The roughness inputs control longitudinal (ν) and azimuthal (s) roughness for e |`tint_TT` |Color multiplier for the first TT-lobe |color3 |1.0, 1.0, 1.0| | |`tint_TRT` |Color multiplier for the first TRT-lobe |color3 |1.0, 1.0, 1.0| | |`ior` |Index of refraction |float |1.55 | | -|`roughness_R` |Longitudinal and azimuthal roughness for R-lobe |vector2|0.1, 0.1 |[0, ∞) | -|`roughness_TT` |Longitudinal and azimuthal roughness for TT-lobe |vector2|0.05, 0.05 |[0, ∞) | -|`roughness_TRT` |Longitudinal and azimuthal roughness for TRT-lobe |vector2|0.2, 0.2 |[0, ∞) | -|`cuticle_angle` |Cuticle angle in radians |float |0.5 |[0, 1] | +|`roughness_R` |Longitudinal variance and azimuthal scale for R-lobe |vector2|0.1, 0.1 |[0, ∞) | +|`roughness_TT` |Longitudinal variance and azimuthal scale for TT-lobe |vector2|0.05, 0.05 |[0, ∞) | +|`roughness_TRT` |Longitudinal variance and azimuthal scale for TRT-lobe |vector2|0.2, 0.2 |[0, ∞) | +|`cuticle_angle` |Normalized cuticle angle |float |0.5 |[0, 1] | |`absorption_coefficient`|Absorption coefficient normalized to hair fiber diameter|vector3|0.0, 0.0, 0.0| | |`normal` |Normal vector of the surface |vector3|Nworld | | |`curve_direction` |Direction of the hair geometry |vector3|Tworld | | |`out` |Output: the computed BSDF |BSDF | | | +In the equations below, the `tint_R`, `tint_TT`, and `tint_TRT` inputs correspond to per-lobe color tints $t_R$, $t_{TT}$, $t_{TRT}$; the `ior` input corresponds to $\eta$, the index of refraction of the hair fiber; the `roughness_R`, `roughness_TT`, and `roughness_TRT` inputs each provide a pair $(v, s)$ of longitudinal variance and azimuthal logistic scale values; the `cuticle_angle` input corresponds to $\alpha$; and the `absorption_coefficient` input corresponds to $\sigma_a$. + +#### Chiang Hair Scattering Equations + +The Chiang hair model[^Chiang2016] treats a hair fiber as a dielectric cylinder with tilted cuticle scales. Directions at a point on the fiber are parameterized by inclination $\theta$ from the fiber's normal plane and azimuth $\phi$ around the fiber, differing from the surface-normal angles used by planar BSDF nodes. The BCSDF is a sum over four scattering lobes — R (surface reflection), TT (double transmission), TRT (internal reflection), and TRRT+ (higher-order paths): + +```math +f_c(\omega_i, \omega_o) = \frac{1}{\pi} \sum_{p \in \{R,TT,TRT,TRRT+\}} t_p A_p M_p N_p +``` +

+ +where $M_p$ is the longitudinal scattering function, $N_p$ is the azimuthal scattering function, and $A_p$ is the attenuation factor combining Fresnel reflectance and volumetric absorption. The higher-order TRRT+ lobe shares the tint $t_{TRT}$ and the roughness values of the TRT lobe. The full definitions of these components are given in the [Chiang Hair Model](#chiang-hair-model) appendix. + ## EDF Nodes +The equations below use the symbols, notation, and emission conventions defined in the [Scattering Framework](#scattering-framework). + ### `uniform_edf` -Constructs an EDF emitting light uniformly in all directions. +Constructs an EDF emitting light uniformly across the hemisphere around the surface normal. |Port |Description |Type |Default | |--------|----------------------------------------------|-------|-------------| |`color` |Radiant emittance of light leaving the surface|color3 |1.0, 1.0, 1.0| |`out` |Output: the computed EDF |EDF | | +In the equation below, the `color` input corresponds to $c$, the emitted radiance. + +#### Uniform Emission Equation + +```math +L_e(\omega_o) = c +``` +

+ +For a Lambertian emitter such as this, the equivalent radiant exitance (power per unit area integrated over the hemisphere) is $M = \pi c$. + ### `conical_edf` Constructs an EDF emitting light inside a cone around the normal direction. -Light intensity begins to fall off at the `inner_angle` and reaches zero at the `outer_angle` (both specified in degrees). If the `outer_angle` is smaller than the `inner_angle`, no falloff occurs within the cone. +Light intensity begins to fall off at the `inner_angle` and reaches zero at the `outer_angle` (both specified in degrees as **full cone angles**). If the `outer_angle` is smaller than the `inner_angle`, no falloff occurs within the cone. |Port |Description |Type |Default | |-------------|--------------------------------------------------|-------|-------------| @@ -374,6 +835,38 @@ Light intensity begins to fall off at the `inner_angle` and reaches zero at the |`outer_angle`|Angle of outer cone where intensity goes to zero |float |0.0 | |`out` |Output: the computed EDF |EDF | | +In the equations below, the `color` input corresponds to $c$, the peak emitted radiance along the cone axis. The `inner_angle` and `outer_angle` inputs are full cone angles in degrees and are halved to obtain the angle from the cone axis. + +#### Conical Falloff Equations + +Define: + +```math +\cos\theta_o = \max(0, \omega_o \cdot n) +``` +

+ +```math +c_{\text{in}} = \cos\!\left(\tfrac{\pi}{360}\cdot\text{inner\_angle}\right), \quad c_{\text{out}} = \cos\!\left(\tfrac{\pi}{360}\cdot\text{outer\_angle}\right) +``` +

+ +**Case 1 — no falloff** (`outer_angle` $\le$ `inner_angle`): a hard cutoff at the inner cone boundary. + +```math +L_e(\omega_o) = \begin{cases} c & \text{if } \cos\theta_o \ge c_{\text{in}} \\ 0 & \text{otherwise} \end{cases} +``` +

+ +**Case 2 — smooth falloff** (`outer_angle` $>$ `inner_angle`): Hermite-smoothstep interpolation in cosine space between the outer and inner cone boundaries. + +```math +L_e(\omega_o) = c\cdot\mathrm{smoothstep}(c_{\text{out}},\, c_{\text{in}},\, \cos\theta_o) +``` +

+ +where $\mathrm{smoothstep}(a, b, x) = t^2(3 - 2t)$ with $t = \mathrm{clamp}\\!\left(\dfrac{x - a}{b - a},\\, 0,\\, 1\right)$. + ### `measured_edf` @@ -399,6 +892,22 @@ Adds a directionally varying factor to an EDF. Scales the emission distribution |`base` |The base EDF to be modified |EDF |__zero__ | |`out` |Output: the computed EDF |EDF | | +In the equations below, the `color0` and `color90` inputs correspond to $r_0$ and $r_{90}$, the `exponent` input corresponds to $q$, and the `base` input corresponds to $L_e^{\text{base}}$. + +#### Generalized Schlick Emission Equations + +The emission scaling factor follows the two-parameter Schlick curve[^Schlick1994] evaluated at $\cos\theta_o = \omega_o \cdot n$: + +```math +F(\cos\theta_o) = r_0 + (r_{90} - r_0)(1 - \cos\theta_o)^{q} +``` +

+ +```math +L_e(\omega_o) = F(\cos\theta_o) \cdot L_e^{\text{base}}(\omega_o) +``` +

+ ## VDF Nodes @@ -407,19 +916,32 @@ Adds a directionally varying factor to an EDF. Scales the emission distribution ### `absorption_vdf` Constructs a VDF for pure light absorption. -The `absorption` input represents the absorption rate per distance traveled in the medium, stated in _m−1_, with independent control for each wavelength. +The `absorption` input represents the absorption rate per distance traveled in the medium, stated in $m^{-1}$, with independent control for each wavelength. |Port |Description |Type |Default | |------------|------------------------------|-------|-------------| |`absorption`|Absorption rate for the medium|vector3|0.0, 0.0, 0.0| |`out` |Output: the computed VDF |VDF | | +In the equation below, the `absorption` input corresponds to $\sigma_a$, the absorption coefficient per color channel, stated in $m^{-1}$. + +#### Beer-Lambert Absorption + +As light travels a distance $t$ through a purely absorbing medium, its radiance is attenuated exponentially according to Beer's law: + +```math +T(t) = e^{-\sigma_a t} +``` +

+ +where $T$ is the fraction of radiance transmitted. + ### `anisotropic_vdf` Constructs a VDF scattering light for a participating medium, based on the Henyey-Greenstein phase function[^Pharr2023]. Forward, backward and uniform scattering is supported and controlled by the anisotropy input. -The `absorption` input represents the absorption rate per distance traveled in the medium, stated in _m−1_, with independent control for each wavelength. +The `absorption` input represents the absorption rate per distance traveled in the medium, stated in $m^{-1}$, with independent control for each wavelength. The `anisotropy` input controls the scattering direction: negative values produce backwards scattering, positive values produce forward scattering, and 0.0 produces uniform scattering. Both absorption and scattering rates are specified per wavelength. @@ -430,13 +952,49 @@ The `anisotropy` input controls the scattering direction: negative values produc |`anisotropy`|Anisotropy factor for scattering direction|float |0.0 |[-1, 1] | |`out` |Output: the computed VDF |VDF | | | +In the equations below, the `absorption` input corresponds to $\sigma_a$, the absorption coefficient per color channel; the `scattering` input corresponds to $\sigma_s$, the scattering coefficient per color channel; and the `anisotropy` input corresponds to $g$, the phase function asymmetry parameter. All coefficients are stated in $m^{-1}$. + +#### Extinction + +The **extinction coefficient** is the combined rate of absorption and scattering: + +```math +\sigma_t = \sigma_a + \sigma_s +``` +

+ +As light travels a distance $t$ through the medium, its radiance is attenuated by absorption and out-scattering: + +```math +T(t) = e^{-\sigma_t t} +``` +

+ +At each scattering event, a fraction of the extinguished energy is scattered into a new direction rather than absorbed. This fraction is the **single-scattering albedo**: + +```math +\varpi = \frac{\sigma_s}{\sigma_t} +``` +

+ +#### Henyey-Greenstein Phase Function + +The phase function $f_p$ describes the angular distribution of scattered light at each scattering event. This node uses the Henyey-Greenstein phase function[^Pharr2023], parameterized by the asymmetry parameter $g \in [-1, 1]$: + +```math +f_p(\cos\theta, g) = \frac{1}{4\pi} \cdot \frac{1 - g^2}{(1 + g^2 - 2g\cos\theta)^{3/2}} +``` +

+ +where $\theta$ is the deflection angle between the incident and scattered directions of propagation. Because $\omega_i$ and $\omega_o$ both point away from $p$, this is $\cos\theta = -(\omega_i \cdot \omega_o)$. For $g = 0$ the distribution is uniform (isotropic scattering), positive values of $g$ produce forward scattering, and negative values produce backward scattering. + ## PBR Shader Nodes ### `surface` -Constructs a surface shader describing light scattering and emission for surfaces. By default the node will construct a shader for a closed surface, representing an interface to a solid volume. In this mode refraction and scattering is enabled for any transmissive BSDFs connected to this surface. By setting thin_walled to "true" the node will instead construct a thin-walled surface, representing a surface with an infinitely thin volume. In thin-walled mode refraction and scattering will be disabled. Thin-walled mode must be enabled to construct a double-sided material with different surface shaders on the front and back side of geometry (using [<surfacematerial>](./MaterialX.Specification.md#node-surfacematerial) in the standard library). +Constructs a surface shader describing light scattering and emission for surfaces. The `thin_walled` input selects between closed and thin-walled interpretations of the surface, as described in [Closed and Thin-Walled Surfaces](#closed-and-thin-walled-surfaces) below. If the `edf` input is left unconnected, no emission will occur from the surface. @@ -448,6 +1006,23 @@ If the `edf` input is left unconnected, no emission will occur from the surface. |`thin_walled`|Set to true to make the surface thin-walled |boolean |false | |`out` |Output: the computed surface shader |surfaceshader| | +In the equations below, the `bsdf` input corresponds to $f$, the `edf` input corresponds to $L_e$, and the `opacity` input corresponds to $O$. + +#### Surface Shading Equation + +The surface shader evaluates the [Light Transport Equation](#the-light-transport-equation) at the shading point, scaled by the cutout opacity $O \in [0, 1]$: + +```math +L_o(\omega_o) = O \left[ L_e(\omega_o) + \int_{\mathbb{S}^2} f(\omega_i, \omega_o)\, L_i(\omega_i)\, |\omega_i \cdot n|\; d\omega_i \right] +``` +

+ +The opacity $O$ is the fraction of the surface footprint covered by the material; the remaining uncovered fraction $1 - O$ lets radiance from geometry behind the surface pass through unoccluded, allowing the surface to act as a cutout mask. + +#### Closed and Thin-Walled Surfaces + +By default (`thin_walled` = false) the surface bounds a solid interior: transmissive BSDFs refract incident light according to their index of refraction, and any medium layered beneath the surface attenuates the transmitted radiance. When `thin_walled` is true the surface represents an infinitely thin shell with matching media on both sides: transmission passes straight through without refraction or interior scattering. Distinct surface shaders may be assigned to the front and back faces of geometry using [<surfacematerial>](./MaterialX.Specification.md#node-surfacematerial) in the standard library, with the rules for sidedness and thin-walled status given in the [Surfaces](#surfaces) section above. + ### `volume` @@ -461,6 +1036,12 @@ If the `edf` input is left unconnected, no emission will occur from the medium. |`edf` |Emission distribution function for the medium|EDF |__zero__| |`out` |Output: the computed volume shader |volumeshader| | +In the equations below, the `vdf` input supplies the absorption coefficient $\sigma_a$, scattering coefficient $\sigma_s$, and phase function $f_p$, and the `edf` input corresponds to the volume emission $L_e$. + +#### Volume Shading Equation + +The volume shader evaluates the [Equation of Transfer](#the-equation-of-transfer) within the participating medium. + ### `light` @@ -473,6 +1054,17 @@ Constructs a light shader describing an explicit light source. The light shader |`exposure` |Exposure control for the EDF's emittance |float |0.0 | |`out` |Output: the computed light shader |lightshader | | +In the equation below, the `edf` input corresponds to the base emission $L_e^{\text{edf}}$, the `intensity` input corresponds to $I$, and the `exposure` input corresponds to $E$. + +#### Light Emission Equation + +The light shader scales the emission of the connected EDF by a linear intensity multiplier and a photographic exposure control in stops: + +```math +L_e(\omega_o) = I \cdot 2^{E} \cdot L_e^{\text{edf}}(\omega_o) +``` +

+ Note that the standard library includes definitions for [**`displacement`**](./MaterialX.Specification.md#node-displacement) and [**`surface_unlit`**](./MaterialX.Specification.md#node-surfaceunlit) shader nodes. @@ -490,6 +1082,17 @@ Mix two same-type distribution functions according to a weight. Performs horizon |`mix` |The mixing weight |float |0.0 |[0, 1] | |`out` |Output: the mixed distribution function |Same as `bg` | | | +In the equation below, the `bg` input corresponds to $f_{\text{bg}}$, the `fg` input corresponds to $f_{\text{fg}}$, and the `mix` input corresponds to the weight $w$. + +#### Mix Equation + +```math +f = (1 - w) f_{\text{bg}} + w f_{\text{fg}} +``` +

+ +Because $w \in [0, 1]$, the mix of two individually energy-conserving distribution functions is also energy conserving. + ### `layer` @@ -501,6 +1104,17 @@ Vertically layer a layerable BSDF such as [<dielectric_bsdf>](#node-dielectri |`base`|The base BSDF or VDF |BSDF or VDF|__zero__| |`out` |Output: the layered distribution|BSDF | | +In the equation below, the `top` input corresponds to $f_{\text{top}}$ and the `base` input corresponds to $f_{\text{base}}$. The quantity $E_{\text{top}}$ is the directional albedo of $f_{\text{top}}$, as defined in the [Directional Albedo and Energy Conservation](#directional-albedo-and-energy-conservation) section. + +#### Layer Equation + +```math +f = f_{\text{top}} + (1 - E_{\text{top}}) f_{\text{base}} +``` +

+ +The base is attenuated by exactly the energy not reflected by the top layer. If both $f_{\text{top}}$ and $f_{\text{base}}$ are individually energy conserving, the layered result is also energy conserving. + ### `add` @@ -512,6 +1126,17 @@ Additively blend two distribution functions of the same type. |`in2` |The second distribution function |Same as `in1` |__zero__| |`out` |Output: the added distribution functions |Same as `in1` | | +In the equation below, the `in1` input corresponds to $f_1$ and the `in2` input corresponds to $f_2$. + +#### Add Equation + +```math +f = f_1 + f_2 +``` +

+ +Note that unlike [<mix>](#node-mix) and [<layer>](#node-layer), the add node does **not** guarantee energy conservation. The sum of two energy-conserving distribution functions may reflect more energy than is incident, so the author is responsible for ensuring that the combined result remains physically plausible. + ### `multiply` @@ -523,6 +1148,17 @@ Multiply the contribution of a distribution function by a scaling weight. The we |`in2` |The scaling weight |float or color3 |1.0 | |`out` |Output: the scaled distribution function |Same as `in1` | | +In the equation below, the `in1` input corresponds to $f_1$ and the `in2` input corresponds to the scaling weight $s$. + +#### Multiply Equation + +```math +f = s f_1 +``` +

+ +When $s$ is a `color3`, each color channel of the distribution function is scaled independently. + ### `roughness_anisotropy` @@ -592,6 +1228,29 @@ Converts the artistic parameterization hair roughness to roughness for R, TT and |`roughness_TT` |Output: Roughness for TT lobe |vector2 | | | |`roughness_TRT` |Output: Roughness for TRT lobe |vector2 | | | +In the equations below, the `longitudinal` input corresponds to $\ell$, the artist-facing longitudinal roughness; the `azimuthal` input corresponds to $a$, the artist-facing azimuthal roughness; and the `scale_TT` and `scale_TRT` inputs correspond to the per-lobe roughness scales $k_{TT}$ and $k_{TRT}$[^Marschner2003]. + +#### Hair Roughness Conversion Equations + +The artist-facing roughness values are converted to the longitudinal variance $v$ and azimuthal logistic scale $s$ consumed by [<chiang_hair_bsdf>](#node-chiang-hair-bsdf) using empirical fits[^Chiang2016]: + +```math +v = \left(0.726\ell + 0.812\ell^2 + 3.7\ell^{20}\right)^2 +``` +

+ +```math +s = 0.265 a + 1.194 a^2 + 5.372 a^{22} +``` +

+ +The per-lobe outputs apply the squared roughness scales to the longitudinal variance: + +```math +\text{roughness\_R} = (v,\; s), \quad \text{roughness\_TT} = (k_{TT}^2\, v,\; s), \quad \text{roughness\_TRT} = (k_{TRT}^2\, v,\; s) +``` +

+ ### `deon_hair_absorption_from_melanin` @@ -676,6 +1335,528 @@ The MaterialX PBS Library includes a number of nodegraphs that can be used to ap
+# Appendix: Extended Reflectance Models + +This appendix contains extended equation sets for BSDF nodes whose full derivations would otherwise interrupt the flow of the node catalog. + + +## EON Reflectance Model + +The EON model[^Portsmouth2025] decomposes the BRDF into a single-scatter lobe based on Fujii's improved Oren-Nayar formulation[^Fujii2020] and a multi-scatter lobe that compensates for inter-reflection energy lost at higher roughness values. Two constants are shared across the model: + +```math +c_1 = \frac{1}{2} - \frac{2}{3\pi}, \quad c_2 = \frac{2}{3} - \frac{28}{15\pi} +``` +

+ +In the equations below, the `color` input corresponds to $\rho$, the diffuse albedo, and the `roughness` input corresponds to $\sigma$, the surface roughness, where $\sigma \in [0, 1]$. + +### Single-Scatter Lobe + +```math +A = \frac{1}{1 + c_1 \sigma} +``` +

+ +```math +s = \omega_i \cdot \omega_o - \cos\theta_i \cos\theta_o +``` +

+ +```math +\frac{s}{t} = \begin{cases} s / \max(\cos\theta_i, \cos\theta_o) & \text{if } s > 0 \\ s & \text{otherwise}\end{cases} +``` +

+ +```math +f_{\text{ss}}(\omega_i, \omega_o) = \frac{\rho}{\pi} A \left(1 + \sigma \frac{s}{t}\right) +``` +

+ +### Directional Albedo and Average Albedo + +The directional albedo $\hat{E}$ is the hemispherical integral of the single-scatter lobe with unit albedo, and the average albedo $\bar{E}$ is its cosine-weighted average over the hemisphere. Both have closed-form expressions[^Fujii2020]: + +```math +G(\theta) = \sin\theta\left(\theta - \sin\theta\cos\theta\right) + \frac{2}{3}\left(\frac{\sin\theta(1 - \sin^3\theta)}{\cos\theta} - \sin\theta\right) +``` +

+ +```math +\hat{E}(\theta, \sigma) = A + \frac{\sigma A}{\pi} G(\theta) +``` +

+ +```math +\bar{E}(\sigma) = \frac{1 + c_2 \sigma}{1 + c_1 \sigma} +``` +

+ +### Multi-Scatter Lobe + +The multi-scatter lobe recovers the energy that the single-scatter lobe loses to unmodeled inter-reflections between microfacets. Because each diffuse bounce is tinted by the albedo, the effective multi-scatter color is: + +```math +\rho_{\text{ms}} = \frac{\rho^2 \bar{E}}{1 - \rho(1 - \bar{E})} +``` +

+ +```math +f_{\text{ms}}(\omega_i, \omega_o) = \frac{\rho_{\text{ms}}}{\pi} \cdot \frac{(1 - \hat{E}(\theta_o, \sigma))(1 - \hat{E}(\theta_i, \sigma))}{1 - \bar{E}(\sigma)} +``` +

+ +### Combined BRDF + +```math +f_r(\omega_i, \omega_o) = f_{\text{ss}}(\omega_i, \omega_o) + f_{\text{ms}}(\omega_i, \omega_o) +``` +

+ + +## Subsurface Scattering Model + +The [<subsurface_bsdf>](#node-subsurface-bsdf) node is defined compositionally as a Lambertian transmission surface over an [<anisotropic_vdf>](#node-anisotropic-vdf) medium, with a parameterization chosen to match random walk Monte Carlo methods[^Kulla2017] as well as approximate empirical methods[^Christensen2015]. This section defines the conversion from the node's artist-facing inputs to the volume's physical coefficients, and the normalized diffusion profile used by diffusion-based renderers. + +In the equations below, the `color` input corresponds to $\rho$, the observed diffuse reflectance per color channel; the `radius` input corresponds to $\ell$, the mean free path per color channel; and the `anisotropy` input corresponds to $g$, the phase function asymmetry parameter. + +### Albedo Inversion + +The conversion inverts the diffusion-theory relationship between single-scattering albedo and observed diffuse reflectance[^Kulla2017]. + +An intermediate quantity $d$ is first computed from the observed diffuse reflectance $\rho$: + +```math +d = 4.09712 + 4.20863\rho - \sqrt{9.59217 + 41.6808\rho + 17.7126\rho^2} +``` +

+ +The single-scattering albedo for isotropic scattering ($g = 0$) is: + +```math +\varpi_0 = 1 - d^2 +``` +

+ +When the phase function is anisotropic ($g \ne 0$), the single-scattering albedo is adjusted using the similarity relation[^Christensen2015] to account for the directional bias of scattering: + +```math +\varpi = \frac{\varpi_0}{1 - g(1 - \varpi_0)} +``` +

+ +The absorption and scattering coefficients are then: + +```math +\sigma_s = \frac{\varpi}{\ell}, \quad \sigma_a = \frac{1 - \varpi}{\ell} +``` +

+ +These coefficients, together with $g$, parameterize the [<anisotropic_vdf>](#node-anisotropic-vdf) volume. + +### Normalized Diffusion Profile + +In highly scattering, optically thick media[^Pharr2023], the volumetric transport defined above produces a radially symmetric reflectance profile. Christensen and Burley[^Christensen2015] propose the following empirical approximation to this profile, parameterized by the mean free path $\ell$ (the `radius` input): + +```math +R(r) = \frac{e^{-r/\ell} + e^{-r/(3\ell)}}{8\pi \ell r} +``` +

+ +where $r$ is measured in the same world-space units as $\ell$. The profile integrates to unity over the plane and is scaled by the observed diffuse reflectance $\rho$. Here $r$ denotes the distance between the entry and exit points on the surface; locating such point pairs depends on the mesh geometry and is part of the renderer's sampling strategy. + +A renderer may evaluate this model either directly via random-walk volumetric transport, or with the normalized diffusion profile $R(r)$ above; the two approaches are expected to converge to the same result under the assumptions of diffusion theory. + + +## Zeltner Sheen Model + +The Zeltner sheen model[^Zeltner2022] approximates multi-scattering cloth reflectance using a Linearly Transformed Cosine (LTC) lobe. A clamped cosine distribution $D_o(\omega) = \max(\cos\theta, 0) / \pi$ is warped by an inverse transformation matrix $M^{-1}$ to match the shape of the target sheen BRDF. The lobe shape is determined by the exitant direction $\omega_o$ and distributes energy across incident directions $\omega_i$, making the LTC approximation non-reciprocal. Note that the exitant direction of this document is labeled $\omega_i$ in the notation of Zeltner et al[^Zeltner2022]. The roughness is clamped to $r \in [0.01, 1]$, and the directions $\omega_i$ and $\omega_o$ are expressed in a tangent frame aligned to the view-normal plane. + +In the equations below, the `color` input corresponds to $c$, the sheen color tint, and the `roughness` input corresponds to $r$, the surface roughness. + +### LTC Inverse Matrix + +The inverse matrix has two fitted coefficients $a$ and $b$, each a function of $\cos\theta_o$ and $r$: + +```math +M^{-1} = \begin{pmatrix} +a & 0 & b \\ +0 & a & 0 \\ +0 & 0 & 1 +\end{pmatrix} +``` +

+ +### Cosine-Weighted BRDF + +```math +f_r(\omega_i, \omega_o)\cos\theta_i = c \hat{E}(\theta_o, r) D_o\left(\frac{M^{-1}\omega_i}{\lVert M^{-1}\omega_i \rVert}\right) \frac{a^2}{\lVert M^{-1}\omega_i \rVert^3} +``` +

+ +where $\hat{E}(\theta_o, r)$ is the directional albedo of the sheen lobe. + +### Fitted Coefficients + +The coefficients $a$, $b$, and $\hat{E}$ are closed-form fits to precomputed reference data[^Zeltner2022], expressed in terms of $x = \cos\theta_o$ and $y = r$: + +```math +a(x, y) = \frac{(2.58126 x + 0.813703 y) y}{1 + 0.310327 x^2 + 2.60994 x y} +``` +

+ +```math +b(x, y) = \frac{\sqrt{1 - x}(y - 1) y^3}{0.0000254053 + 1.71228 x - 1.71506 x y + 1.34174 y^2} +``` +

+ +### Directional Albedo + +The directional albedo $\hat{E}$ uses a Gaussian fit with rational sub-expressions for its standard deviation $s$, mean $m$, and offset $o$: + +```math +s = \frac{y(0.0206607 + 1.58491 y)}{0.0379424 + y(1.32227 + y)} +``` +

+ +```math +m = \frac{y(-0.193854 + y(-1.14885 + y(1.7932 - 0.95943 y^2)))}{0.046391 + y} +``` +

+ +```math +o = \frac{y(0.000654023 + (-0.0207818 + 0.119681 y) y)}{1.26264 + y(-1.92021 + y)} +``` +

+ +```math +\hat{E}(x, y) = \frac{1}{s\sqrt{2\pi}} \exp\left(-\tfrac{1}{2}\left(\frac{x - m}{s}\right)^2\right) + o +``` +

+ + +## Chiang Hair Model + +The Chiang hair model[^Chiang2016] describes scattering from a hair fiber modeled as a rough dielectric cylinder with tilted cuticle scales, building on the foundational work of Marschner et al.[^Marschner2003] and d'Eon et al.[^d'Eon2011]. This section defines the components of the BCSDF introduced in [<chiang_hair_bsdf>](#node-chiang-hair-bsdf). + +In the equations below, the `ior` input corresponds to $\eta$, the index of refraction; the `absorption_coefficient` input corresponds to $\sigma_a$, the absorption coefficient; the `cuticle_angle` input corresponds to $\alpha$, the cuticle angle (remapped from the input range $[0, 1]$ to $[-\pi/2, \pi/2]$); and the `roughness_R`, `roughness_TT`, and `roughness_TRT` inputs provide the longitudinal variance $v$ and azimuthal logistic scale $s$ for their respective lobes. + +### Hair Fiber Geometry + +Directions at a point on the fiber are parameterized by inclination $\theta$ from the normal plane (where $\sin\theta = \omega \cdot u$ and $u$ is the fiber tangent) and azimuthal angle $\phi$ around the fiber. The relative azimuth between the incident and outgoing directions is $\phi = \phi_i - \phi_o$. + +A ray intersecting the fiber is further parameterized by its normalized offset $h \in [-1, 1]$ from the fiber axis within the cross-sectional plane, which determines the azimuthal incidence angle $\gamma_o$ through $\sin\gamma_o = h$. Computing $h$ for a given intersection depends on the curve geometry representation and is part of the renderer's intersection and sampling strategy. + +### Cuticle Tilt + +The cuticle scales tilt the effective surface of the fiber, shifting the incidence angle for each lobe. The modified incidence angle for lobe $p$ is: + +```math +\theta_i^p = \theta_i + (2 - 3p)\alpha +``` +

+ +where $p = 0$ for R, $p = 1$ for TT, and $p = 2$ for TRT. The TRRT+ lobe uses the unmodified $\theta_i$. + +### Longitudinal Scattering + +The longitudinal scattering function $M_p$ uses the modified Bessel function of the first kind $I_0$: + +```math +M_p = \frac{\exp\left(-\dfrac{\sin\theta_i^p \sin\theta_o}{v}\right) I_0\left(\dfrac{\cos\theta_i^p \cos\theta_o}{v}\right)}{2v\sinh(1/v)} +``` +

+ +### Azimuthal Scattering + +For lobes R, TT, and TRT, the azimuthal scattering function $N_p$ is a trimmed logistic distribution centered at the azimuthal exit angle $\Phi_p$. The exit angle for lobe $p$ is: + +```math +\Phi_p = 2p\gamma_t - 2\gamma_o + p\pi +``` +

+ +where $\gamma_o$ is the azimuthal incidence angle on the fiber cross-section and $\gamma_t$ is the refracted angle satisfying $\sin\gamma_o = \eta'\sin\gamma_t$. Here $\eta'$ is the *effective* index of refraction, corrected for the cylindrical geometry of the fiber, and is the value that must be used for the azimuthal refraction: + +```math +\eta' = \frac{\sqrt{\eta^2 - \sin^2\theta_o}}{\cos\theta_o} +``` +

+ +The logistic distribution with scale parameter $s$ has the PDF and CDF: + +```math +\ell(x, s) = \frac{e^{-x/s}}{s(1 + e^{-x/s})^2}, \quad L(x, s) = \frac{1}{1 + e^{-x/s}} +``` +

+ +The azimuthal scattering is the logistic PDF trimmed to $[-\pi, \pi]$, with the scale adjusted by a factor of $\sqrt{\pi/8}$[^Chiang2016]: + +```math +s' = s\sqrt{\pi/8} +``` +

+ +```math +N_p(\phi) = \frac{\ell(\phi - \Phi_p,\; s')}{L(\pi,\; s') - L(-\pi,\; s')} +``` +

+ +For the TRRT+ lobe, the azimuthal scattering is uniform: $N_{TRRT+} = 1/(2\pi)$. + +### Attenuation Factors + +The attenuation factors $A_p$ combine Fresnel reflectance with volumetric absorption inside the fiber, using the effective index of refraction $\eta'$ defined under [Azimuthal Scattering](#azimuthal-scattering). Let $F$ denote the dielectric Fresnel reflectance evaluated at $\cos\theta_o \cos\gamma_o$. The absorption for a single transverse crossing of the fiber follows from Beer's law: + +```math +T = \exp\left(-\sigma_a \cdot \frac{2\cos\gamma_t}{\cos\theta_t}\right) +``` +

+ +where $\theta_t$ is the refracted longitudinal angle ($\sin\theta_t = \sin\theta_o / \eta$). The per-lobe attenuation factors are: + +```math +A_R = F +``` +

+ +```math +A_{TT} = (1 - F)^2 T +``` +

+ +```math +A_{TRT} = (1 - F)^2 F T^2 +``` +

+ +```math +A_{TRRT+} = \frac{(1 - F)^2 F^2 T^3}{1 - FT} +``` +

+ + +## Thin-Film Iridescence Model + +The thin-film iridescence model[^Belcour2017] computes spectrally resolved Fresnel reflectance for a three-layer system — outer medium, thin dielectric film, substrate — using the Airy equations. This section defines the components of the Airy reflectance $F_{\text{airy}}$ introduced in [Thin-Film Iridescence](#thin-film-iridescence). + +In the equations below, the `thinfilm_thickness` input corresponds to $d$, the film thickness in nanometers, and the `thinfilm_ior` input corresponds to $\eta_2$, the index of refraction of the film. The substrate optical properties $\eta_3$ (and $\kappa_3$ for conductors) are supplied by the host node as described in its inline thin-film section. + + +### Three-Layer Geometry + +The system consists of three media separated by two parallel interfaces: + +| Layer | Medium | IOR | +|-------|--------|-----| +| 1 (outer) | Vacuum | $\eta_1 = 1$ | +| 2 (film) | Thin dielectric film | $\eta_2$ = `thinfilm_ior` | +| 3 (substrate) | Node surface | $\eta_3$ (and $\kappa_3$ for conductors) | + +Light arriving at angle $\theta$ from the outer medium refracts into the film at angle $\theta_t$ according to Snell's law: + +```math +\cos\theta_t = \sqrt{1 - \left(\frac{\eta_1}{\eta_2}\right)^2 \sin^2\theta} +``` +

+ + +### Interface Reflectances + +The polarized Fresnel reflectances at each interface are computed separately for the parallel (p) and perpendicular (s) polarization states. + +#### First Interface (Air–Film) + +The first interface is a dielectric–dielectric boundary with IOR ratio $\eta_2 / \eta_1$. The polarized reflectances $R_{12}^p$ and $R_{12}^s$ are computed using the standard dielectric Fresnel equations evaluated at $\cos\theta$. The transmittance through the first interface is: + +```math +T_{12} = 1 - R_{12} +``` +

+ +computed per polarization state. If $\cos\theta_t \leq 0$, total internal reflection occurs and $R_{12} = 1$. + +#### Second Interface (Film–Substrate) + +The second interface is evaluated at the refracted angle $\theta_t$. The computation depends on the substrate type of the host node: + +* **Dielectric substrate** ([<dielectric_bsdf>](#node-dielectric-bsdf)): The polarized reflectances $R_{23}^p$ and $R_{23}^s$ are computed using the dielectric Fresnel equations with IOR ratio $\eta_3 / \eta_2$. +* **Conductor substrate** ([<conductor_bsdf>](#node-conductor-bsdf)): The polarized reflectances are computed using the conductor Fresnel equations with $(\eta_3 / \eta_2, \kappa_3 / \eta_2)$. +* **Schlick substrate** ([<generalized_schlick_bsdf>](#node-generalized-schlick-bsdf)): The reflectance is computed using the generalized Schlick Fresnel curve at $\cos\theta_t$, applied equally to both polarization states. + + +### Phase Shifts + +Each reflection at an interface introduces a phase shift that depends on the relative indices of refraction. The total phase accumulated per polarization state determines the interference pattern. + +#### First Interface Phase + +The phase shift $\phi_{21}$ at the air–film interface depends on the incidence angle relative to the Brewster angle $\theta_B = \arctan(\eta_2 / \eta_1)$: + +```math +\phi_{21}^p = \begin{cases} \pi & \text{if } \theta < \theta_B \\ 0 & \text{otherwise} \end{cases} +``` +

+ +```math +\phi_{21}^s = \pi +``` +

+ +#### Second Interface Phase (Dielectric Substrate) + +For a dielectric or Schlick substrate, the phase shift at the film–substrate interface is: + +```math +\phi_{23} = \begin{cases} \pi & \text{if } \eta_3 < \eta_2 \\ 0 & \text{otherwise} \end{cases} +``` +

+ +applied equally to both polarization states. + +#### Second Interface Phase (Conductor Substrate) + +For a conductor substrate with complex IOR $(\eta_3, \kappa_3)$, the phase shifts are computed from the complex Fresnel coefficients. Defining the intermediate quantities: + +```math +\bar{k} = \kappa_3 / \eta_3 +``` +

+ +```math +A = \eta_3^2 (1 - \bar{k}^2) - \eta_2^2 \sin^2\theta_t +``` +

+ +```math +B = \sqrt{A^2 + (2\eta_3^2 \bar{k})^2} +``` +

+ +```math +U = \sqrt{(A + B) / 2} +``` +

+ +```math +V = \max\left(0, \sqrt{(B - A) / 2}\right) +``` +

+ +The polarized phase shifts are: + +```math +\phi_{23}^s = \arctan\frac{2\eta_2 V \cos\theta_t}{U^2 + V^2 - (\eta_2 \cos\theta_t)^2} +``` +

+ +```math +\phi_{23}^p = \arctan\frac{2\eta_2 \eta_3^2 \cos\theta_t \left(2\bar{k}U - (1 - \bar{k}^2)V\right)}{(\eta_3^2 (1 + \bar{k}^2) \cos\theta_t)^2 - \eta_2^2 (U^2 + V^2)} +``` +

+ + +### Optical Path Difference + +The optical path difference (OPD) between successive reflected beams within the film is: + +```math +\Delta = 2\eta_2 \cos\theta_t \cdot d \times 10^{-9} +``` +

+ +where the factor $10^{-9}$ converts the film thickness $d$ from nanometers to meters, matching the wavelength units used by the spectral sensitivity function. + + +### Airy Summation + +The reflected intensity $I$ is accumulated over $M$ bounce orders per polarization state. For each polarization (shown here for p; the s computation is analogous with $R_{12}^s$, $R_{23}^s$, $\phi_{21}^s$, $\phi_{23}^s$): + +**DC term** ($m = 0$): the incoherent reflectance from the geometric series of internal bounces: + +```math +R_{\text{dc}} = \frac{(T_{12}^p)^2 R_{23}^p}{1 - R_{12}^p R_{23}^p} +``` +

+ +```math +I^p \mathrel{+}= R_{12}^p + R_{\text{dc}} +``` +

+ +**Higher-order terms** ($m = 1, \ldots, M$): each successive bounce attenuates the amplitude by the geometric mean reflectance $r_{123} = \sqrt{R_{12} R_{23}}$ and introduces a spectral modulation: + +```math +C_m = C_{m-1} \cdot r_{123}^p, \quad C_0 = R_{\text{dc}} - T_{12}^p +``` +

+ +```math +S_m = 2\; \mathcal{S}(m\Delta,\; m(\phi_{23}^p + \phi_{21}^p)) +``` +

+ +```math +I^p \mathrel{+}= C_m S_m +``` +

+ +where $\mathcal{S}$ is the spectral sensitivity function defined below. The final Airy reflectance averages the two polarization states: + +```math +F_{\text{airy}} = \tfrac{1}{2}(I^p + I^s) +``` +

+ + +### Spectral Sensitivity and Color Conversion + +The spectral sensitivity function $\mathcal{S}$ evaluates the interference pattern at a given OPD and phase shift, returning an XYZ tristimulus value. It uses Gaussian fits to the CIE color matching functions[^Belcour2017], parameterized by amplitude $v_k$, center frequency $\mu_k$, and variance $\sigma_k^2$: + +```math +\varphi = 2\pi\Delta +``` +

+ +```math +\mathcal{S}_k(\Delta, \phi) = v_k \sqrt{2\pi\sigma_k^2} \cos(\mu_k\varphi + \phi) \exp\left(-\sigma_k^2 \varphi^2\right) +``` +

+ +The fitted parameters for the three XYZ channels are: + +| Channel | $v_k$ | $\mu_k$ | $\sigma_k^2$ | +|---------|--------|---------|------------| +| X | $5.4856 \times 10^{-13}$ | $1.6810 \times 10^{6}$ | $4.3278 \times 10^{9}$ | +| Y | $4.4201 \times 10^{-13}$ | $1.7953 \times 10^{6}$ | $9.3046 \times 10^{9}$ | +| Z | $5.2481 \times 10^{-13}$ | $2.2084 \times 10^{6}$ | $6.6121 \times 10^{9}$ | + +The X channel uses a second Gaussian lobe to better fit the bimodal shape of the CIE $\bar{x}$ function: + +```math +\mathcal{S}_X \mathrel{+}= 9.7470 \times 10^{-14} \sqrt{2\pi \cdot 4.5282 \times 10^{9}} \cos(2.2399 \times 10^{6} \cdot \varphi + \phi) \exp\left(-4.5282 \times 10^{9}\; \varphi^2\right) +``` +

+ +The resulting XYZ value is normalized by $1.0685 \times 10^{-7}$ and converted to the renderer's linear working color space: + +```math +\begin{pmatrix} R \\ G \\ B \end{pmatrix} = M_{\text{XYZ} \to \text{working}} \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} +``` +

+ +where $M_{\text{XYZ} \to \text{working}}$ is a $3 \times 3$ matrix transforming from CIE XYZ to the working color space. Implementations should allow this matrix to be configured to match the linear working color space of the rendering environment. As an example, the matrix for the `lin_rec709` working color space is: + +```math +M_{\text{XYZ} \to \text{lin\_rec709}} = \begin{pmatrix} 3.2404542 & -1.5371385 & -0.4985314 \\ -0.9692660 & 1.8760108 & 0.0415560 \\ 0.0556434 & -0.2040259 & 1.0572252 \end{pmatrix} +``` +

+ +The result is clamped to $[0, 1]$ per channel. + +
+ + # References [^Andersson2024]: Andersson et al., **OpenPBR Surface Specification**, , 2024. @@ -689,18 +1870,26 @@ The MaterialX PBS Library includes a number of nodegraphs that can be used to ap [^Chiang2016]: Matt Jen-Yuan Chiang et al., **A Practical and Controllable Hair and Fur Model for Production Path Tracing**, , 2016 -[^Christensen2015]: Per H. Christensen, Brent Burley, **Approximate Reflectance Profiles for Efficient Subsurface Scattering**, 2015 +[^Christensen2015]: Per H. Christensen, Brent Burley, **Approximate Reflectance Profiles for Efficient Subsurface Scattering**, , 2015 [^Conty2017]: Alejandro Conty, Christopher Kulla, **Production Friendly Microfacet Sheen BRDF**, , 2017 [^d'Eon2011]: Eugene d'Eon et al., **An Energy-Conserving Hair Reflectance Model**, , 2011 +[^Fujii2020]: Yasuhiro Fujii, **Improving the Oren-Nayar Diffuse Model**, , 2020 + [^Georgiev2019]: Iliyan Georgiev et al., **Autodesk Standard Surface**, , 2019. [^Gulbrandsen2014]: Ole Gulbrandsen, **Artist Friendly Metallic Fresnel**, , 2014 +[^Heitz2014]: Eric Heitz, **Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs**, , 2014 + [^Hoffman2023]: Naty Hoffman, **Generalization of Adobe's Fresnel Model**, 2023 +[^Kulla2017]: Christopher Kulla, Alejandro Conty, **Revisiting Physically Based Shading at Imageworks**, , 2017 + +[^Lagarde2013]: Sébastien Lagarde, **Memo on Fresnel equations**, , 2013 + [^Marschner2003]: Stephen R. Marschner et al., **Light Scattering from Human Hair Fibers**, , 2003 [^Oren1994]: Michael Oren, Shree K. Nayar, **Generalization of Lambert’s Reflectance Model**, , 1994 @@ -711,7 +1900,9 @@ Path Tracing**, , 2025. -[^Raab2025]: Matthias Raab et al., **The Minimal Retroreflective Microfacet Model**, to appear, 2025 +[^Portsmouth2026]: Portsmouth et al., **The Minimal Retroreflective Microfacet Model**, , 2026. + +[^Schlick1994]: Christophe Schlick, **An Inexpensive BRDF Model for Physically-based Rendering**, Computer Graphics Forum, , 1994 [^Turquin2019]: Emmanuel Turquin, **Practical multiple scattering compensation for microfacet models**, , 2019. From 6f400ebb19ee1792bcad59ad935396847dc0bf41 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 7 Jun 2026 12:57:09 -0700 Subject: [PATCH 2/5] Fix dielectric phase shifts in thin-film equations This changelist addresses an issue caught by Arnon Marcus in review, where the step-function phase shift at the film-substrate interface was incorrectly attributed to both dielectric and generalized Schlick substrates. Existing implementations of thin-film iridescence for MaterialX, including MaterialX GLSL and the NVIDIA MDL SDK, evaluate dielectric substrates with the complex phase formulas at kappa3 = 0, capturing the parallel-polarization phase flip at the film-substrate Brewster angle and the continuous phase shifts under total internal reflection, neither of which the step function can represent. --- documents/Specification/MaterialX.PBRSpec.md | 40 ++++++++++---------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/documents/Specification/MaterialX.PBRSpec.md b/documents/Specification/MaterialX.PBRSpec.md index 131f9fa499..6cfbe14700 100644 --- a/documents/Specification/MaterialX.PBRSpec.md +++ b/documents/Specification/MaterialX.PBRSpec.md @@ -559,7 +559,7 @@ When $\eta^2 + c^2 < 1$, the quantity $g$ is imaginary and total internal reflec #### Thin-Film Iridescence -When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is set to the node's `ior` input $\eta$, with $\kappa_3 = 0$ (lossless dielectric). +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is set to the node's `ior` input $\eta$, with $\kappa_3 = 0$ (lossless dielectric). The polarized phase shifts at the film–substrate interface are computed using the complex phase formulas given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix, evaluated with $\kappa_3 = 0$; these capture the phase flip of the parallel polarization at the film–substrate Brewster angle, as well as the continuous phase shifts arising from total internal reflection within the film. @@ -621,7 +621,7 @@ F = \tfrac{1}{2}(R_s + R_p) #### Thin-Film Iridescence -When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate is defined by the node's complex index of refraction, with $\eta_3 = \eta$ and $\kappa_3 = \kappa$. The polarized phase shifts at the film–substrate interface are computed using the conductor phase formula given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix. +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate is defined by the node's complex index of refraction, with $\eta_3 = \eta$ and $\kappa_3 = \kappa$. The polarized phase shifts at the film–substrate interface are computed using the complex phase formulas given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix. @@ -678,7 +678,7 @@ F_{\theta} = r_0 + (r_{90} - r_0)(1 - \cos\theta)^{q} - a \cdot \cos\theta (1 - #### Thin-Film Iridescence -When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F_{\theta}$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is derived from the `color0` input $r_0$ using the standard Schlick-to-IOR inversion, with $\kappa_3 = 0$. +When `thinfilm_thickness` is non-zero, the Fresnel reflectance $F_{\theta}$ above is replaced by the Airy reflectance $F_{\text{airy}}$ defined in [Thin-Film Iridescence](#thin-film-iridescence). The substrate IOR $\eta_3$ is derived from the `color0` input $r_0$ using the standard Schlick-to-IOR inversion, with $\kappa_3 = 0$. The phase shift at the film–substrate interface uses the step-function approximation given in the [Thin-Film Iridescence Model](#thin-film-iridescence-model) appendix, applied equally to both polarization states. @@ -1703,20 +1703,9 @@ The phase shift $\phi_{21}$ at the air–film interface depends on the incidence ```

-#### Second Interface Phase (Dielectric Substrate) +#### Second Interface Phase (Dielectric and Conductor Substrates) -For a dielectric or Schlick substrate, the phase shift at the film–substrate interface is: - -```math -\phi_{23} = \begin{cases} \pi & \text{if } \eta_3 < \eta_2 \\ 0 & \text{otherwise} \end{cases} -``` -

- -applied equally to both polarization states. - -#### Second Interface Phase (Conductor Substrate) - -For a conductor substrate with complex IOR $(\eta_3, \kappa_3)$, the phase shifts are computed from the complex Fresnel coefficients. Defining the intermediate quantities: +For a dielectric or conductor substrate with complex IOR $(\eta_3, \kappa_3)$, where $\kappa_3 = 0$ for a lossless dielectric, the phase shifts are computed from the complex Fresnel coefficients. Defining the intermediate quantities: ```math \bar{k} = \kappa_3 / \eta_3 @@ -1743,18 +1732,31 @@ V = \max\left(0, \sqrt{(B - A) / 2}\right) ```

-The polarized phase shifts are: +The polarized phase shifts are computed with the two-argument arctangent $\operatorname{atan2}(y, x)$, which is required to resolve the correct quadrant: ```math -\phi_{23}^s = \arctan\frac{2\eta_2 V \cos\theta_t}{U^2 + V^2 - (\eta_2 \cos\theta_t)^2} +\phi_{23}^s = \operatorname{atan2}\left(2\eta_2 V \cos\theta_t,\; U^2 + V^2 - (\eta_2 \cos\theta_t)^2\right) ```

```math -\phi_{23}^p = \arctan\frac{2\eta_2 \eta_3^2 \cos\theta_t \left(2\bar{k}U - (1 - \bar{k}^2)V\right)}{(\eta_3^2 (1 + \bar{k}^2) \cos\theta_t)^2 - \eta_2^2 (U^2 + V^2)} +\phi_{23}^p = \operatorname{atan2}\left(2\eta_2 \eta_3^2 \cos\theta_t \left(2\bar{k}U - (1 - \bar{k}^2)V\right),\; \left(\eta_3^2 (1 + \bar{k}^2) \cos\theta_t\right)^2 - \eta_2^2 (U^2 + V^2)\right) ```

+In the dielectric case ($\kappa_3 = 0$), these expressions reduce below the critical angle to step functions of $0$ and $\pi$: the perpendicular phase $\phi_{23}^s$ is $\pi$ when $\eta_3 < \eta_2$ and $0$ otherwise, while the parallel phase $\phi_{23}^p$ additionally flips by $\pi$ at the film–substrate Brewster angle $\arctan(\eta_3 / \eta_2)$. Beyond the critical angle, total internal reflection at the film–substrate interface produces continuously varying phase shifts in both polarization states, which the expressions above handle directly. + +#### Second Interface Phase (Schlick Substrate) + +For a Schlick substrate, the phase shift at the film–substrate interface is approximated by the step function: + +```math +\phi_{23} = \begin{cases} \pi & \text{if } \eta_3 < \eta_2 \\ 0 & \text{otherwise} \end{cases} +``` +

+ +applied equally to both polarization states, where $\eta_3$ is the effective substrate IOR derived from the `color0` input. + ### Optical Path Difference From a1f334f7fd2c297deb9d6c918072d8dbf555479c Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 8 Jun 2026 09:41:24 -0700 Subject: [PATCH 3/5] Fix Markdown and math rendering issues This changelist fixes Markdown and math rendering issues in the PBR specification, including formatting notes raised by Doug Smythe in review: - Replace `\operatorname` with `\mathrm` for more reliable rendering in GitHub's math engine. - Fix a misplaced italic emphasis around "phase function". - Replace double-backslash escapes in inline math with backtick-wrapped delimiters, preempting related issues in the future. --- documents/Specification/MaterialX.PBRSpec.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/documents/Specification/MaterialX.PBRSpec.md b/documents/Specification/MaterialX.PBRSpec.md index 6cfbe14700..491f8aae19 100644 --- a/documents/Specification/MaterialX.PBRSpec.md +++ b/documents/Specification/MaterialX.PBRSpec.md @@ -90,7 +90,7 @@ The initial requirements for a physically-plausible material are that it 1) shou ## Quantities and Units -Radiometric quantities are used by the material model for interactions with the renderer. The fundamental radiometric quantity is **radiance** (measured in $W\\,m^{-2}\\,sr^{-1}$) and gives the intensity of light arriving at, or leaving from, a given point in a given direction. If incident radiance is integrated over all directions we get **irradiance** (measured in $W\\,m^{-2}$), and if we integrate this over surface area we get **power** (measured in $W$). Input parameters for materials and lights specified in photometric units can be suitably converted to their radiometric counterparts before being submitted to the renderer. +Radiometric quantities are used by the material model for interactions with the renderer. The fundamental radiometric quantity is **radiance** (measured in $`W\,m^{-2}\,sr^{-1}`$) and gives the intensity of light arriving at, or leaving from, a given point in a given direction. If incident radiance is integrated over all directions we get **irradiance** (measured in $`W\,m^{-2}`$), and if we integrate this over surface area we get **power** (measured in $W$). Input parameters for materials and lights specified in photometric units can be suitably converted to their radiometric counterparts before being submitted to the renderer. When the renderer operates in RGB rather than on a full spectrum, each of the red, green, and blue channels carries the convolution of a spectral radiance distribution with a sensor response function, so the quantity actually transported is neither spectral radiance nor luminance, but an _integrated radiance_, also called a _tristimulus weight_. The radiometric units used throughout this document should therefore be understood as nominal: they identify the physical quantity that each value represents in an idealized spectral sense, and fix the relative scaling between quantities, while the absolute scale of emission and the mapping to displayed pixel values are governed by the renderer's exposure and color-management conventions. @@ -141,9 +141,9 @@ The surface normal used for shading calculations is supplied as input to each BS ## Volumes -In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function, _describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate of absorption for light traveling through the medium, and the **scattering coefficient** sets the rate of which the light is scattered from its current direction. The unit for these are $m^{-1}$. +In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function_, describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate of absorption for light traveling through the medium, and the **scattering coefficient** sets the rate of which the light is scattered from its current direction. The unit for these are $m^{-1}$. -Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $W\\,m^{-3}\\,sr^{-1}$. The emission distribution is oriented along the current direction. +Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $`W\,m^{-3}\,sr^{-1}`$. The emission distribution is oriented along the current direction. The [<volume>](#node-volume) node in the PBS library constructs a volume shader from individual VDF and EDF components. There are also nodes to construct various VDFs, as well as nodes to combine them to build more complex ones. @@ -221,7 +221,7 @@ L_e(\omega_o) = \frac{d^2\Phi_e}{dA \, \cos\theta_o \; d\omega_o} ```

-where $dA$ is the differential area around $p$. Unlike the BSDF, the EDF is a function of a single direction and carries no dependence on an incident direction or cosine factor. For surface EDFs, $L_e$ has units of $W\\,m^{-2}\\,sr^{-1}$; for volume EDFs, $W\\,m^{-3}\\,sr^{-1}$. +where $dA$ is the differential area around $p$. Unlike the BSDF, the EDF is a function of a single direction and carries no dependence on an incident direction or cosine factor. For surface EDFs, $L_e$ has units of $`W\,m^{-2}\,sr^{-1}`$; for volume EDFs, $`W\,m^{-3}\,sr^{-1}`$. ### Reflection and Transmission @@ -394,7 +394,7 @@ For a participating medium, radiance is continuously attenuated by absorption an ```

-The first term attenuates radiance by the extinction coefficient $\sigma_t = \sigma_a + \sigma_s$. The second adds radiance scattered into $\omega_o$ from all directions, weighted by the scattering coefficient $\sigma_s$ and the phase function $f_p$. The final term $L_e$ is the volume emission, stated in $W\\,m^{-3}\\,sr^{-1}$; it corresponds to the product $\sigma_a L_e$ of an absorption coefficient and an emitted radiance in the formulation of Pharr et al.[^Pharr2023]. The coefficients $\sigma_a$, $\sigma_s$ and the phase function $f_p$ are supplied by the medium's [VDF](#vdf-nodes), and $L_e$ by its [EDF](#edf-nodes). +The first term attenuates radiance by the extinction coefficient $\sigma_t = \sigma_a + \sigma_s$. The second adds radiance scattered into $\omega_o$ from all directions, weighted by the scattering coefficient $\sigma_s$ and the phase function $f_p$. The final term $L_e$ is the volume emission, stated in $`W\,m^{-3}\,sr^{-1}`$; it corresponds to the product $\sigma_a L_e$ of an absorption coefficient and an emitted radiance in the formulation of Pharr et al.[^Pharr2023]. The coefficients $\sigma_a$, $\sigma_s$ and the phase function $f_p$ are supplied by the medium's [VDF](#vdf-nodes), and $L_e$ by its [EDF](#edf-nodes).
@@ -865,7 +865,7 @@ L_e(\omega_o) = c\cdot\mathrm{smoothstep}(c_{\text{out}},\, c_{\text{in}},\, \co ```

-where $\mathrm{smoothstep}(a, b, x) = t^2(3 - 2t)$ with $t = \mathrm{clamp}\\!\left(\dfrac{x - a}{b - a},\\, 0,\\, 1\right)$. +where $\mathrm{smoothstep}(a, b, x) = t^2(3 - 2t)$ with $`t = \mathrm{clamp}\!\left(\dfrac{x - a}{b - a},\, 0,\, 1\right)`$. @@ -1732,15 +1732,15 @@ V = \max\left(0, \sqrt{(B - A) / 2}\right) ```

-The polarized phase shifts are computed with the two-argument arctangent $\operatorname{atan2}(y, x)$, which is required to resolve the correct quadrant: +The polarized phase shifts are computed with the two-argument arctangent $\mathrm{atan2}(y, x)$, which is required to resolve the correct quadrant: ```math -\phi_{23}^s = \operatorname{atan2}\left(2\eta_2 V \cos\theta_t,\; U^2 + V^2 - (\eta_2 \cos\theta_t)^2\right) +\phi_{23}^s = \mathrm{atan2}\left(2\eta_2 V \cos\theta_t,\; U^2 + V^2 - (\eta_2 \cos\theta_t)^2\right) ```

```math -\phi_{23}^p = \operatorname{atan2}\left(2\eta_2 \eta_3^2 \cos\theta_t \left(2\bar{k}U - (1 - \bar{k}^2)V\right),\; \left(\eta_3^2 (1 + \bar{k}^2) \cos\theta_t\right)^2 - \eta_2^2 (U^2 + V^2)\right) +\phi_{23}^p = \mathrm{atan2}\left(2\eta_2 \eta_3^2 \cos\theta_t \left(2\bar{k}U - (1 - \bar{k}^2)V\right),\; \left(\eta_3^2 (1 + \bar{k}^2) \cos\theta_t\right)^2 - \eta_2^2 (U^2 + V^2)\right) ```

From 64d99b9899cb1bcd82de0371d897884c8d7c6192 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 10 Jun 2026 14:11:48 -0700 Subject: [PATCH 4/5] Merge suggestions from Jamie Co-authored-by: Jamie Signed-off-by: Jonathan Stone --- documents/Specification/MaterialX.PBRSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documents/Specification/MaterialX.PBRSpec.md b/documents/Specification/MaterialX.PBRSpec.md index 491f8aae19..eabc790e09 100644 --- a/documents/Specification/MaterialX.PBRSpec.md +++ b/documents/Specification/MaterialX.PBRSpec.md @@ -141,7 +141,7 @@ The surface normal used for shading calculations is supplied as input to each BS ## Volumes -In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function_, describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate of absorption for light traveling through the medium, and the **scattering coefficient** sets the rate of which the light is scattered from its current direction. The unit for these are $m^{-1}$. +In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function_, describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate (per unit-length) of absorption of light energy traveling through the medium, and the **scattering coefficient** sets the rate (per unit-length) at which the light is scattered from its current direction. The units for these are $m^{-1}$. Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $`W\,m^{-3}\,sr^{-1}`$. The emission distribution is oriented along the current direction. From 7ee11bc46075092de42fc8fe503baddb0e67456a Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 10 Jun 2026 15:21:19 -0700 Subject: [PATCH 5/5] Clarify volume emission as isotropic This changelist clarifies the orientation of volume emission in the PBR specification, addressing a question raised by Jamie Portsmouth in review. --- documents/Specification/MaterialX.PBRSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documents/Specification/MaterialX.PBRSpec.md b/documents/Specification/MaterialX.PBRSpec.md index eabc790e09..dbbad43b4c 100644 --- a/documents/Specification/MaterialX.PBRSpec.md +++ b/documents/Specification/MaterialX.PBRSpec.md @@ -143,7 +143,7 @@ The surface normal used for shading calculations is supplied as input to each BS In our volume shader model the scattering of light in a participating medium is controlled by a volume distribution function (VDF), with coefficients controlling the rate of absorption and scattering. The VDF represents what physicists call a _phase function_, describing how the light is distributed from its current direction when it is scattered in the medium. This is analogous to how a BSDF describes scattering at a surface, but with one important difference: a VDF is normalized, summing to 1.0 if all directions are considered. Additionally, the amount of absorption and scattering is controlled by coefficients that gives the rate (probability) per distance traveled in world space. The **absorption coefficient** sets the rate (per unit-length) of absorption of light energy traveling through the medium, and the **scattering coefficient** sets the rate (per unit-length) at which the light is scattered from its current direction. The units for these are $m^{-1}$. -Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $`W\,m^{-3}\,sr^{-1}`$. The emission distribution is oriented along the current direction. +Light can also be emitted from a volume. This is represented by an EDF analog to emission from surfaces, but in this context the emission is given as radiance per distance traveled through the medium. The unit for this is $`W\,m^{-3}\,sr^{-1}`$. Because a participating medium has no surface normal to orient the distribution, volume emission is assumed to be isotropic. The [<volume>](#node-volume) node in the PBS library constructs a volume shader from individual VDF and EDF components. There are also nodes to construct various VDFs, as well as nodes to combine them to build more complex ones.