diff --git a/README.md b/README.md index c81cc8bc..ccdc3d97 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ -# OpenPBR Surface + +
+

+homepage   +homepage +

+

- + +
Shader Playground, rendered in Arnold for Maya, using OpenPBR Surface. Artwork by Nikie Monteleone.


diff --git a/examples/open_pbr_lightbulb.mtlx b/examples/open_pbr_lightbulb.mtlx index 39fa490b..284d7eec 100644 --- a/examples/open_pbr_lightbulb.mtlx +++ b/examples/open_pbr_lightbulb.mtlx @@ -4,6 +4,7 @@ + diff --git a/images/logo/openpbr-logo-favicon.png b/images/logo/openpbr-logo-favicon.png new file mode 100644 index 00000000..557d6c0a Binary files /dev/null and b/images/logo/openpbr-logo-favicon.png differ diff --git a/images/logo/openpbr-logo-glyph.png b/images/logo/openpbr-logo-glyph.png new file mode 100644 index 00000000..b3cf3a23 Binary files /dev/null and b/images/logo/openpbr-logo-glyph.png differ diff --git a/images/logo/openpbr-logo-glyph.svg b/images/logo/openpbr-logo-glyph.svg new file mode 100644 index 00000000..3907200c --- /dev/null +++ b/images/logo/openpbr-logo-glyph.svg @@ -0,0 +1,38 @@ + + + + diff --git a/images/logo/openpbr-logo-icon-minimal.png b/images/logo/openpbr-logo-icon-minimal.png new file mode 100644 index 00000000..8452c516 Binary files /dev/null and b/images/logo/openpbr-logo-icon-minimal.png differ diff --git a/images/logo/openpbr-logo-icon-minimal.svg b/images/logo/openpbr-logo-icon-minimal.svg new file mode 100644 index 00000000..0bbe647a --- /dev/null +++ b/images/logo/openpbr-logo-icon-minimal.svg @@ -0,0 +1,28 @@ + + + + diff --git a/images/logo/openpbr-logo-icon.png b/images/logo/openpbr-logo-icon.png new file mode 100644 index 00000000..9b0238b0 Binary files /dev/null and b/images/logo/openpbr-logo-icon.png differ diff --git a/images/logo/openpbr-logo-icon.svg b/images/logo/openpbr-logo-icon.svg new file mode 100644 index 00000000..d6789926 --- /dev/null +++ b/images/logo/openpbr-logo-icon.svg @@ -0,0 +1,35 @@ + + + + diff --git a/images/logo/openpbr-logo-text.png b/images/logo/openpbr-logo-text.png new file mode 100644 index 00000000..e80433b8 Binary files /dev/null and b/images/logo/openpbr-logo-text.png differ diff --git a/images/logo/openpbr-logo-text.svg b/images/logo/openpbr-logo-text.svg new file mode 100644 index 00000000..a22d42d4 --- /dev/null +++ b/images/logo/openpbr-logo-text.svg @@ -0,0 +1,25 @@ + + + + diff --git a/images/logo/openpbr-logo.png b/images/logo/openpbr-logo.png new file mode 100644 index 00000000..6bc5ba95 Binary files /dev/null and b/images/logo/openpbr-logo.png differ diff --git a/images/logo/openpbr-logo.svg b/images/logo/openpbr-logo.svg new file mode 100644 index 00000000..c66798ce --- /dev/null +++ b/images/logo/openpbr-logo.svg @@ -0,0 +1,42 @@ + + + + diff --git a/index.html b/index.html index eba523b1..d88d1df5 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,13 @@ + -**OpenPBR Surface** +
+ homepage +   + homepage +
*Specification v1.1, 2024-06-28.     homepage *
@@ -30,10 +35,10 @@ OpenPBR is intended to be a common interface between products, as well as something practical that works well and looks plausible for most day-to-day use cases. For the more specialized use cases it does not cover (for example very high-end skin, hair, cloth or volume shading), one may need to use a renderer-specific shader, or build a bespoke shading network. We aim for the overall behavior to be simple, logical, intuitive, and understandable, so that users can become comfortable and familiar with it, while also being grounded in physically-based rendering. We thus adopt a specific form of material structure that has proved useful as a general purpose model in media and entertainment (Figure [diagram_model]). In outline the structure consists of: - - A [base substrate](index.html#model/basesubstrate) made of a mixture of [metal](index.html#model/metal) or [dielectric](index.html#model/dielectricbase). The interface (dielectric or metal) of this base layer produces the primary specular reflection lobe. The dielectric base represents either of three components, that can be statistically mixed: - 1. [Glossy-diffuse](index.html#model/dielectricbase/glossy-diffuse): dielectric with opaque internal media, e.g. wood, granite, concrete, cardboard, and wall-paint. - 2. [Subsurface](index.html#model/dielectricbase/subsurface): dielectric with dense highly scattering internal media, e.g. plastic, marble, skin, vegetation, and food. - 3. [Translucent-base](index.html#model/dielectricbase/translucentbase): dielectric with translucent internal media, e.g. glass, crystals, and liquids. + - A [base substrate](index.html#model/basesubstrate) made of a mixture of [metal](index.html#model/basesubstrate/metal) or dielectric. The interface (dielectric or metal) of this base layer produces the primary specular reflection lobe. The dielectric base represents either of three components, that can be statistically mixed: + 1. [Glossy-diffuse](index.html#model/basesubstrate/glossy-diffuse): dielectric with opaque internal media, e.g. wood, granite, concrete, cardboard, and wall-paint. + 2. [Subsurface](index.html#model/basesubstrate/subsurface): dielectric with dense highly scattering internal media, e.g. plastic, marble, skin, vegetation, and food. + 3. [Translucent-base](index.html#model/basesubstrate/translucentbase): dielectric with translucent internal media, e.g. glass, crystals, and liquids. - [Coat](index.html#model/coat): An optional layer of dielectric, which may have an absorbing medium, acting as a coating on top of the base substrate. The dielectric interface of this coat layer provides a secondary specular lobe. - [Fuzz](index.html#model/fuzz): An optional layer representing the reflection from micro-fibers (such as fine hair, peach fuzz, textile strands, and dust grains) on top of everything else. @@ -190,11 +195,11 @@ It also ensures that if the substrate BSDF perfectly preserves energy, i.e. $E_\mathrm{sub}(\omega_o) = 1$, then the layer BSDF does also, ensuring that a "white furnace" test would pass. The Autodesk Standard Surface model [#Georgiev2019] uses this formulation for its layering. Note though that this albedo-scaling approximation does not correctly take into account the effect of multiple light bounces back and forth between the interfaces, or absorption and scattering in the volumetric medium of the coat $V_\mathrm{coat}$. In general the resulting BSDF lobe shape will not be a simple linear combination of the interface BSDFs. -To some extent these effects can be put back into the albedo-scaling model by making various approximations. For example the effect of the volumetric transmittance through the coat in the incident and output directions could be approximately modeled as +To some extent these effects can be put back into the albedo-scaling model by making various approximations. For example the effect of the volumetric absorption through the coat in the incident and output directions could be approximately modeled as \begin{equation} \label{non-reciprocal-albedo-scaling-with-T} -f_\mathrm{layer}(\omega_i, \omega_o) = f_\mathrm{coat}(\omega_i, \omega_o) + T_\mathrm{coat}(\omega_i, \omega_o) \bigl(1 - E_\mathrm{coat}(\omega_o)\bigr) \,f_\mathrm{sub}(\omega_i, \omega_o) +f_\mathrm{layer}(\omega_i, \omega_o) = f_\mathrm{coat}(\omega_i, \omega_o) + T_\mathrm{coat}(\omega_i, \omega_o) \bigl(1 - E_\mathrm{coat}(\omega_o)\bigr) \,f_\mathrm{sub}(\omega_i, \omega_o) \end{equation} -where $T_\mathrm{coat}(\omega_i, \omega_o)$ accounts for the total volumetric absorption of the coat along the input and output rays. Similarly if the coat is rough this will effectively roughen the substrate BSDF lobe also, which can be accounted for approximately via various heuristics. +where $T_\mathrm{coat}(\omega_i, \omega_o)$ accounts for the total volumetric transmittance of the coat along the input and output rays. Similarly if the coat is rough this will effectively roughen the substrate BSDF lobe also, which can be accounted for approximately via various heuristics. Mixing @@ -259,7 +264,7 @@ \begin{equation} f_\mathrm{layer} = f_\mathrm{coat} + T_\mathrm{coat} \left(1 - E_\mathrm{coat}\right) \,f_\mathrm{sub} \end{equation} -where $f_\mathrm{coat}$ is the BSDF of the coat and $T_\mathrm{coat}$ is its transmittance. Thus combining these [^lerp], +where $f_\mathrm{coat}$ is the BSDF of the coat and $T_\mathrm{coat}$ is the volumetric transmittance along the path of the input and output rays. Thus combining these [^lerp], \begin{equation} \label{coat_layering_formula_with_albedo_scaling} f_\mathrm{weighted-layer} = w_\mathrm{coat} f_\mathrm{coat} + \mathrm{lerp}\bigl(1, T_\mathrm{coat} (1 - E_\mathrm{coat}), w_\mathrm{coat}\bigr) f_\mathrm{sub} \ , \end{equation} @@ -286,7 +291,7 @@ However the parameters of the physical model that we describe do not specify all of the assumptions that would be needed to obtain a good visual match. We recommend therefore, for the purposes of asset exchange, that the parameters be packaged with certain metadata that provides the following missing information: - The version of the specification implemented. - - The assumed color space of all the color parameters. If unspecified, following MaterialX [#Smythe2016], by default this color space is assumed to be [ACEScg](https://docs.acescentral.com/specifications/acescg/). + - The assumed color space of all the color parameters. If unspecified, following MaterialX [#Smythe2016], by default this color space is assumed to be [ACEScg](https://docs.acescentral.com/specifications/acescg/). [^ingamut] - The floating-point conversion factor from the parameters given in world space length units to meters. @@ -303,7 +308,7 @@ ============================================ Using the operator formalism and parametrization described, we now specify the structure of the OpenPBR surface model. -We describe first the non-thin-walled case (in the [thin-walled case](index.html#model/thin-walledcase) the structure differs), where the material structure looks informally like the following diagram: +We describe first the non-thin-walled mode (in the [thin-walled mode](index.html#model/thin-walledmode) the structure differs), where the material structure looks informally like the following diagram: ************************************************************************************************************ * emission * * ^ * @@ -371,7 +376,7 @@ We give here some general assumptions about the form and parametrization of the BSDFs which describe the interfaces in the model outlined in the previous section. -The BSDFs $f_\mathrm{conductor}$, $f_\mathrm{dielectric}$, $f_\mathrm{coat}$ and $f_\mathrm{diffuse}$ of the [metal](index.html#model/metal), [dielectric](index.html#model/dielectricbase), [coat](index.html#model/coat) and [glossy-diffuse](index.html#model/dielectricbase/glossy-diffuse) slabs respectively, are each assumed to be described by a standard _microfacet model_. This is a widely used approximation ([#Pharr2023]) in which the surface is assumed to be composed of a heightfield consisting of smooth microfacets of either metal, dielectric or Lambertian material, where the statistical distribution of the normal of these facets, termed the _micronormal_, determines the surface roughness characteristics at the macroscopic scale. (The [fuzz](index.html#model/fuzz) model is distinct and based on a volumetric "microflake" model [#Heitz2015]). +The BSDFs $f_\mathrm{conductor}$, $f_\mathrm{dielectric}$, $f_\mathrm{coat}$ and $f_\mathrm{diffuse}$ of the [metal](index.html#model/basesubstrate/metal), [dielectric](index.html#model/basesubstrate), [coat](index.html#model/coat) and [glossy-diffuse](index.html#model/basesubstrate/glossy-diffuse) slabs respectively, are each assumed to be described by a standard _microfacet model_. This is a widely used approximation ([#Pharr2023]) in which the surface is assumed to be composed of a heightfield consisting of smooth microfacets of either metal, dielectric or Lambertian material, where the statistical distribution of the normal of these facets, termed the _micronormal_, determines the surface roughness characteristics at the macroscopic scale. (The [fuzz](index.html#model/fuzz) model is distinct and based on a volumetric "microflake" model [#Heitz2015]). A microfacet BRDF has the standard form [^Jacobian] ([#Walter2007], [#Pharr2023]) in the single-scattering approximation: \begin{equation} @@ -384,8 +389,7 @@ The _masking-shadowing function_ $G(\omega_i, \omega_o)$ accounts for the probability that the input and output directions are occluded by the microsurface. It is usually derived using the Smith model which determines $G$ given the NDF, and for the GGX NDF equation [GGX] the masking-shadowing function then has a well-known form [#Heitz2014]. -The _Normal Distribution Function_ (NDF) $D(m)$ describes the relative probability of occurrence of micronormal $m$ on the surface, and thus the roughness characteristics. -A popular form of NDF which well-approximates the roughness of real materials is the so-called GGX distribution (this name derives from "ground glass", but the formula was originally due to Trowbridge and Reitz [#Walter2007], [#Burley2012], [#Heitz2014], [#Pharr2023]), which has the basic [^normalization] form: +The _Normal Distribution Function_ (NDF) $D(m)$ describes the relative probability of occurrence of micronormal $m$ on the surface, and thus the roughness characteristics. We assume that the NDF is the so-called GGX distribution which well-approximates the roughness of real materials (the name GGX derives from "ground glass", but the formula was originally due to Trowbridge and Reitz [#Walter2007], [#Burley2012], [#Heitz2014], [#Pharr2023]), which has the basic [^normalization] form: \begin{equation} \label{GGX} D_\mathrm{GGX}(m) \propto \left( 1 + \frac{\tan^2\theta_m}{\alpha^2} \right)^{-2} \end{equation} @@ -461,7 +465,7 @@ This mirrors the usual workflow of artists where they are typically either modelling an opaque surface potentially with some specularity and dense subsurface scattering (such as rock, plastic, skin etc.), or a translucent material with some limited amount of volumetric absorption and scattering (such as glass, liquids, organic matter etc.). These use cases require different parametrizations to effectively control, so are convenient to split into separate slabs. -The translucent-base is described in the Translucent base section, while the opaque-base is further broken down below (into [Glossy-diffuse](index.html#model/dielectricbase/glossy-diffuse) and [Subsurface](index.html#model/dielectricbase/subsurface)). The **`transmission_weight`** parameter selects between these models. Note that technically a mix weight between 0 and 1 produces a physically ambiguous state (since there are then superimposed bulk media with different properties), so we expect that normally this weight acts as a Boolean selector. +The translucent-base is described in the Translucent base section, while the opaque-base is further broken down below (into [Glossy-diffuse](index.html#model/basesubstrate/glossy-diffuse) and [Subsurface](index.html#model/basesubstrate/subsurface)). The **`transmission_weight`** parameter selects between these models. Note that technically a mix weight between 0 and 1 produces a physically ambiguous state (since there are then superimposed bulk media with different properties), so we expect that normally this weight acts as a Boolean selector. The opaque-base substrate is assumed to be a dielectric with dense subsurface volumetric absorption and scattering, which tends to an idealized "glossy-diffuse" BSDF in the limit of infinite density medium. In some cases a blend of subsurface and completely opaque glossy-diffuse scattering is desired, for example in skin rendering where the diffuse component provides the surface details of the skin (freckles, blemishes, makeup, etc.) and the subsurface component provides the color detail of the underlying veins and tissue. To support this, we make the opaque-base substrate be a statistical mix of glossy-diffuse and subsurface models (described in the Glossy-diffuse section and the Subsurface section respectively): \begin{eqnarray} @@ -513,7 +517,6 @@ ![Figure [specular]: Varying the **`specular_ior`** from (left to right): 1.1, 1.3, 1.5 (default)](dummy) - ### Metal Metals are completely opaque and have a characteristic and familiar form of specularity due to the Fresnel factor for conductors differing from that for dielectrics. @@ -543,21 +546,22 @@ \begin{equation} \mathbf{F}(\bar{\mu}) = \mathtt{specular\_color} * \mathbf{F}_\mathrm{Schlick}(\bar{\mu}) \ . \end{equation} -The final metallic Fresnel term we employ is then given by an overall multiplication by **`specular_weight`**, ensuring that entire metallic lobe is suppressed as the weight goes to zero: + +The final metallic Fresnel term we employ is then given by an overall multiplication by $\xi_s = \mathtt{specular\_weight}$, ensuring that the entire metallic lobe is suppressed as the weight goes to zero. Similarly to the dielectric, the weight may also exceed one in order to linearly boost the Fresnel, with a clamp put in place to ensure that it remains bounded in $[0,1]$ as $\xi_s \rightarrow \infty$: [^component_wise] \begin{equation} -\mathbf{F}_{\mathrm{metal}}(\mu) = \mathtt{specular\_weight} * \mathbf{F}_{82}(\mu) \ . +\mathbf{F}_{\mathrm{metal}}(\mu) = \mathrm{min}\bigl(1, \,\xi_s \mathbf{F}_{82}(\mu)\bigr) \ . \end{equation} This formulation has the useful property that it reduces to the regular Schlick reflectivity at the default values of **`specular_weight`** and **`specular_color`**. Note that the edge cannot be brighter than the standard Schlick term, but this is generally true in real metals. We consider this a benefit of this parametrization, as it makes it impossible to produce physically implausible metals with excessively bright edges. -Metal params | Label | Type | Range | Default | Description -------------------------------------|------------|----------|:------------:|:-------------------:|---------------------------------------------- -**`base_weight`** | Weight | `float` | $ [0, 1] $ | $ 1 $ | Scalar multiplier to **`base_color`** -**`base_color`** | Color | `color3` | $ [0, 1]^3 $ | $ (0.8, 0.8, 0.8) $ | Color of Fresnel reflection albedo at normal incidence, $\mathbf{F}_0$ -**`specular_weight`** | Weight | `float` | $ [0, 1] $ | $ 1 $ | Overall multiplier of the metallic Fresnel -**`specular_color`** | Color | `color3` | $ [0, 1]^3 $ | $ (1, 1, 1) $ | Tint color of metallic Fresnel reflection albedo at near-grazing incidence (i.e. around silhouettes) -**`specular_roughness`** | Roughness | `float` | $ [0, 1] $ | $ 0.3 $ | Roughness of NDF of conductor BRDF $f_\mathrm{conductor}$ -**`specular_roughness_anisotropy`** | Anisotropy | `float` | $ [0, 1] $ | $ 0 $ | Anisotropy of NDF of conductor BRDF $f_\mathrm{conductor}$ +Metal params | Label | Type | Range | Norm | Default | Description +------------------------------------|------------|----------|:---------------:|:-------------:|:-------------------:|---------------------------------------------- +**`base_weight`** | Weight | `float` | $ [0, 1] $ | | $ 1 $ | Scalar multiplier to **`base_color`** +**`base_color`** | Color | `color3` | $ [0, 1]^3 $ | | $ (0.8, 0.8, 0.8) $ | Color of Fresnel reflection albedo at normal incidence, $\mathbf{F}_0$ +**`specular_weight`** | Weight | `float` | $ [0, \infty) $ | $ [0, 1] $ | $ 1 $ | Overall multiplier of the metal Fresnel +**`specular_color`** | Color | `color3` | $ [0, 1]^3 $ | | $ (1, 1, 1) $ | Tint color of metallic Fresnel reflection albedo at near-grazing incidence (i.e. around silhouettes) +**`specular_roughness`** | Roughness | `float` | $ [0, 1] $ | | $ 0.3 $ | Roughness of NDF of BRDF $f_\mathrm{conductor}$ +**`specular_roughness_anisotropy`** | Anisotropy | `float` | $ [0, 1] $ | | $ 0 $ | Anisotropy of NDF of BRDF $f_\mathrm{conductor}$ ![](images/metal_with_default_edge_tint.png width=90% align=right) ![](images/metal_with_correct_edge_tint.png width=90% align=left) @@ -606,7 +610,7 @@ \begin{eqnarray} \label{EON_brdf} f_\mathrm{diffuse}(\omega_i, \omega_o) = f_\mathrm{ON}(\omega_i, \omega_o) + f^\mathrm{comp}_\mathrm{ON}(\omega_i, \omega_o) \ . \end{eqnarray} -This form of the Oren-Nayar model is termed "energy-preserving Oren-Nayar" or $\textbf{EON}$. +This form of the Oren-Nayar model is termed "energy-preserving Oren-Nayar" or $\textbf{EON}$ [#Portsmouth2024]. The Oren-Nayar term $f_\mathrm{ON}$ is given by the [#Fujii2012] form [^Oren_Nayar_formula] \begin{eqnarray} \label{FON_brdf} f_\mathrm{ON}(\omega_i, \omega_o) = \frac{w_\mathrm{d} \boldsymbol{\rho}}{\pi} \Bigl( A(\sigma) + B(\sigma) \frac{s}{t} @@ -618,7 +622,7 @@ The directional albedo $E_\mathrm{ON}(\omega) = w_\mathrm{d} \boldsymbol{\rho}\,\hat{E}_\mathrm{ON}(\omega)$, and corresponding _average albedo_ $\langle\hat{E}_\mathrm{ON}\rangle$, of the Oren-Nayar term can be determined -analytically [^Oren_Nayar_albedo]. The energy compensation term $f^{\mathrm{comp}}_\mathrm{ON}$ is given in terms of the +analytically [#Portsmouth2024]. The energy compensation term $f^{\mathrm{comp}}_\mathrm{ON}$ is given in terms of the albedo $\langle\hat{E}_\mathrm{ON}\rangle$ by \begin{equation} \label{EON_comp} f^\mathrm{comp}_\mathrm{ON}(\omega_i, \omega_o) = \frac{w_\mathrm{d} \boldsymbol{\rho}_\mathrm{ms}}{\pi} @@ -699,7 +703,7 @@ S_\mathrm{subsurface} = \mathrm{Slab}(f_\mathrm{dielectric}, V^\infty_\mathrm{subsurface}) \ . \end{equation} -As in the cases of the [glossy-diffuse](index.html#model/dielectricbase/glossy-diffuse) slab and the [translucent-base](index.html#model/dielectricbase/translucentbase), the subsurface is bounded by a dielectric interface with BSDF $f_\mathrm{dielectric}$, which generates the primary specular reflection lobe parametrized via the "specular" parameters as described in the Dielectric base section. Combined with this is the reflection generated by light which is transmitted through the dielectric interface into the underlying embedded subsurface medium, where it scatters around and eventually transmits back out. In this case the subsurface medium $V^\infty_\mathrm{subsurface}$ is given a parametrization which is particularly convenient for controlling the volumetric effect of dense subsurface scattering: +As in the cases of the [glossy-diffuse](index.html#model/basesubstrate/glossy-diffuse) slab and the [translucent-base](index.html#model/basesubstrate/translucentbase), the subsurface is bounded by a dielectric interface with BSDF $f_\mathrm{dielectric}$, which generates the primary specular reflection lobe parametrized via the "specular" parameters as described in the Dielectric base section. Combined with this is the reflection generated by light which is transmitted through the dielectric interface into the underlying embedded subsurface medium, where it scatters around and eventually transmits back out. In this case the subsurface medium $V^\infty_\mathrm{subsurface}$ is given a parametrization which is particularly convenient for controlling the volumetric effect of dense subsurface scattering: - **`subsurface_radius`** * **`subsurface_radius_scale`**: the _mean free path_ (MFP) per RGB channel, $\mathbf{r}$, i.e. the average distance that a ray of light travels through the medium before being absorbed or scattered. This thus controls the apparent density of the medium. In the limit of zero MFP, the medium tends towards infinite density, and approaches the look of an opaque diffuse surface. Being a length, **`subsurface_radius`** can be any value greater than or equal to zero. For convenience, we make the soft range $[0, 1]$, thus covering common cases such as skin where the MFP is lower than the scene length units. The **`subsurface_radius_scale`** controls the color channel dependence of the MFP, and thus this color is visible in the light transmitted through thinner regions of the subsurface volume. - **`subsurface_color`**: the observed RGB reflection albedo color taking into account all orders of multiple scattering, $\mathbf{C}$ (where the sense in which this parametrizes the observed color is discussed in detail below). @@ -783,7 +787,7 @@ \begin{equation} \boldsymbol{\mu}_a = \boldsymbol{\mu}_t - \boldsymbol{\mu}_s \ . \end{equation} -If any component of $\boldsymbol{\mu}_a$ is negative, then $\boldsymbol{\mu}_a$ is shifted by enough gray to make all the components positive, i.e. (in an obvious notation): +If any component of $\boldsymbol{\mu}_a$ is negative, then $\boldsymbol{\mu}_a$ is shifted by enough gray to make all the components positive, i.e.: [^component_wise] \begin{eqnarray} && \mathrm{if \;\; min(\boldsymbol{\mu}_a)} < 0 \nonumber \\ && \quad\quad \boldsymbol{\mu}_a \leftarrow \boldsymbol{\mu}_a - \mathrm{min}(\boldsymbol{\mu}_a) \ . @@ -848,11 +852,13 @@ The coverage weight functions as a blend between the BSDF with and without the presence of the film, and thus allows one to dial the effect without altering the shape and saturation of the color fringes. - The currently recommended thin-film model is that of Belcour and Barla [#Belcour2017]. The shape and color of the fringe patterns in the reflection from the film will be affected (as described by Belcour and Barla) by the complex IOR of the adjacent media above and below the film, which in general are a statistical mix of metal and dielectric below and coat and ambient medium above (which the fuzz is index-matched to). Figure [ior_configs] illustrates the eight possible different structures depending on the presence of both the film and coat, each of which leads to different Fresnel effects due to the differing IORs at the interfaces. + The currently recommended thin-film model is that of Belcour and Barla [#Belcour2017], in which the thin-film thickness is smaller than the scale of the microfacets and assumed to be smooth. With this assumption, in practice the effect is most easily incorporated directly into the Fresnel factor of the microfacet BSDFs of both the metal and dielectric-base layers (thus it is *not* represented by incorporating an explicit thin-film Slab into the model). + + The shape and color of the fringe patterns in the reflection from the film will be affected (as described by Belcour and Barla) by the complex IOR of the adjacent media above and below the film, which in general are a statistical mix of metal and dielectric below and coat and ambient medium above (which the fuzz is index-matched to). Figure [ior_configs] illustrates the eight possible different structures depending on the presence of both the film and coat, each of which leads to different Fresnel effects due to the differing IORs at the interfaces. ![Figure [ior_configs]: Schematic of all 8 possible IOR configurations, including those involving the thin-film.](images/IOR_configs.svg width="95%" align="center") -In principle the implementation should deal with all these physical configurations correctly, though modeling of the precise effect is implementation-dependent. In practice, this wave-optics effect is most easily incorporated directly into the Fresnel factor of the microfacet BSDFs of both the metal and dielectric-base layers. (For this reason, this effect is not represented by incorporating an explicit thin-film Slab into the model). +In principle the implementation should deal with all these physical configurations correctly, though modeling of the precise effect is implementation-dependent. Note that in the case of the dielectric base, the thin-film should also generate color fringes in the transmission lobe. This is important for example when rendering soap bubbles (see [#Belcour2017]). @@ -894,8 +900,6 @@ * +-------------------------------------------------+ * ******************************************************* -The absorption of the medium $V_\mathrm{coat}$ is parametrized by **`coat_color`**, which is assumed to specify the _square_ of the transmittance $T_\mathrm{coat}$ of the coat at normal incidence (i.e. $T^2_\mathrm{coat}$ = **`coat_color`**). Thus at normal incidence, the observed tint color of the underlying base due to absorption in the coat is approximately given by **`coat_color`** due to the absorption along the incident and outgoing rays (note that the specular reflection from the coat itself is _not_ tinted). - The IOR $n_c = \mathtt{coat\_ior}$ of the coat medium $V_\mathrm{coat}$ will alter the Fresnel factor of both the coat top interface and the underlying metal or dielectric. If there is a fractional $\mathtt{coat\_weight}$ $\mathtt{C}$, then the surrounding IOR of the base dielectric or metal varies statistically across the surface depending on whether the coat is locally present (and the fuzz layer can be assumed to have the ambient IOR $n_a$). The ratio between the specular IOR $n_b = \mathtt{specular\_ior}$ and the surrounding medium can thus reasonably be approximated as \begin{equation} \label{specular_ior_ratio} \eta_s = \mathrm{lerp}(n_b/n_a, n_b/n_c, \mathtt{C}) \ . @@ -903,6 +907,19 @@ This ratio then determines the specular Fresnel factor, as in equation [modulated_ior]. (Note that as discussed in the coat [TIR](index.html#model/coat/totalinternalreflection) section, evaluation of the specular Fresnel factor may need to be further modified to model the refraction of the ray inside the coat). +The absorption of the medium $V_\mathrm{coat}$ is parametrized by **`coat_color`**, which is assumed to specify the _square_ of the transmittance of the coat at normal incidence (i.e. $T_\mathrm{coat}$ = **`coat_color`** in the notation of equation [non-reciprocal-albedo-scaling-with-T]). Thus the observed tint color of the underlying base due to absorption in the coat is approximately given by **`coat_color`** due to the absorption along the incident and outgoing rays (note that the specular reflection from the coat itself is _not_ tinted). + +In the full light transport within the coat, various physical effects [^porosity] occur which we assume are accounted for in the ground truth appearance. + + - The observed color of the coated base is darkened and saturated due to multiple internal reflections from the inside of the coat, which causes light to strike the underlying material multiple times and undergo more absorption. This effect is controlled via the **`coat_darkening`** parameter, as described in the coat Darkening section. + + - The observed **`coat_color`** tint also darkens as the incidence angle changes due to the change in path length in the medium, as described in the View-dependent absorption section. + + - The presence of a rough coat will increase the apparent roughness of the BSDF lobes of the underlying base. A recommendation for implementation of this effect is given in the coat Roughening section. + + - Care needs to be taken in the implementation to account for the refraction of the ray direction inside the coat. This is discussed in the Total internal reflection section. + +
Coat params | Label | Type | Range | Norm | Default | Description --------------------------------|------------|----------|:---------------:|:----------:|:-------------:|---------------------------------------------- @@ -918,22 +935,6 @@ ![Figure [coat]: Coat adds a secondary specular highlight and optional absorption tint](dummy) -In the full light transport, the observed color of the coated base is darkened and saturated due to multiple internal reflections from the inside of the coat, which causes light to strike the underlying material multiple times and undergo more absorption, and the observed **`coat_color`** tint also darkens as the incidence angle changes due to the change in path length in the medium. Also, the presence of a rough coat will increase the apparent roughness of the BSDF lobes of the underlying base. - -We assume that in the ground truth appearance, all these physical effects are accounted for [^porosity]. In the following sub-sections, we detail recommendations for implementation of them. - - -### Roughening - -If the coat is rough, the microfacet BSDF lobes of the underlying base substrate (metal and dielectric) are also effectively roughened. If this is not otherwise accounted for by the light transport, it can instead be reasonably approximated by directly altering the NDF of the base BSDFs. - -A formula we recommend for this is obtained by identifying the NDF of each microfacet lobe as corresponding approximately to a Gaussian in slope-space with variance given by $\alpha_t^2 + \alpha_b^2 = r^4$ (in the notation of the [Microfacet model](index.html#model/microfacetmodel) section). Modeling the effect of the roughening as the convolution of these Gaussian NDFs (and double counting the coat variance since the reflection passes through the coat boundary twice), the resulting modified roughness of the base, $r'_\mathrm{B}$, (taking into account the presence weight of the coat, $\mathtt{C}=$ **`coat_weight`**) is given by -\begin{equation} -r'_\mathrm{B} = \mathrm{lerp}\Bigl( r_\mathrm{B}, \mathrm{min} \bigl(1, r^4_\mathrm{B} + 2 r^4_\mathrm{C} \bigr)^\frac{1}{4}, \mathtt{C} \Bigr) -\end{equation} -where $r_\mathrm{B}=$ **`specular_roughness`** and $r_\mathrm{C}=$ **`coat_roughness`**. - - ### Darkening Figure [coat_darkening_grid] shows the physically-correct change in appearance (at normal incidence) of a textured diffuse base with a wood texture and smooth clear-coat as the IOR of the clear-coat is varied, exhibiting darkening of the base -- due to the internal reflections in the coat -- which increases as IOR increases. @@ -986,7 +987,7 @@ \begin{equation} \label{dielectric_roughness_estimate} r_d = \mathrm{lerp}(1, r, \xi_s F_s) \end{equation} -while the metallic roughness can be taken to be $r_m = r$. +while the metallic roughness can be taken to be $r_m = r$. (Note that in this formula for $r_d$, a clamp must be applied to ensure that $\xi_s F_s \in [0, 1]$). Given the general formula equation [general_darkening_formula] for the darkening, a reasonable approximate scheme -- assuming no other compensation is made to approximate the effect -- is to multiply the base BSDF by the uniform _modulated darkening factor_ (taking into account the presence weight $\mathtt{C}$ = **`coat_weight`** and the darkening parameter $\delta$ = **`coat_darkening`**): \begin{equation} \label{modulated_darkening_factor} @@ -1012,6 +1013,18 @@ ![Figure [coat_view_dependent_absorption_color]: The color of an absorbing coat becomes darker and more saturated at grazing angles.](images/coat_view_dependent_absorption_color.png width="75%") +### Roughening + +If the coat is rough, the microfacet BSDF lobes of the underlying base substrate (metal and dielectric) are also effectively roughened. If this is not otherwise accounted for by the light transport, it can instead be reasonably approximated by directly altering the NDF of the base BSDFs. + +A formula we recommend for this is obtained by identifying the NDF of each microfacet lobe as corresponding approximately to a Gaussian in slope-space with variance given by $\alpha_t^2 + \alpha_b^2 = r^4$ (in the notation of the [Microfacet model](index.html#model/microfacetmodel) section). Modeling the effect of the roughening as the convolution of these Gaussian NDFs (and double counting the coat variance since the reflection passes through the coat boundary twice), the resulting modified roughness of the base, $r'_\mathrm{B}$, (taking into account the presence weight of the coat, $\mathtt{C}=$ **`coat_weight`**) is given by +\begin{equation} +r'_\mathrm{B} = \mathrm{lerp}\Bigl( r_\mathrm{B}, \mathrm{min} \bigl(1, r^4_\mathrm{B} + 2 r^4_\mathrm{C} \bigr)^\frac{1}{4}, \mathtt{C} \Bigr) +\end{equation} +where $r_\mathrm{B}=$ **`specular_roughness`** and $r_\mathrm{C}=$ **`coat_roughness`**. + + + ### Total internal reflection A technical issue which can cause difficulties in the implementation of the BRDF of the coated dielectric base should also be mentioned. @@ -1087,7 +1100,7 @@ where the albedo-scaling is explicitly modified to not tint the base since the tint $\mathbf{F}$ appears only in the first term via $f_\mathrm{fuzz}$. Then accounting for the coverage weight of the fuzz layer, $\mathtt{F}$ = **`fuzz_weight`**, gives: \begin{eqnarray} -\mathrm{\mathbf{layer}}(M_\textrm{coated-base}, S_\mathrm{fuzz}, \mathtt{F}) &\rightarrow& \mathtt{F} \,f_\mathrm{fuzz} + \mathrm{lerp}\bigl(1, 1 - E_\mathrm{fuzz}, \mathtt{F}\bigr) \,f_\textrm{coated-base} \ . \label{fuzz-layering-approx} +\mathrm{\mathbf{layer}}(M_\textrm{coated-base}, S_\mathrm{fuzz}, \mathtt{F}) &\rightarrow& \mathtt{F} \,f_\mathrm{fuzz} + \bigl(1 - \mathtt{F}\,E_\mathrm{fuzz}\bigr) \,f_\textrm{coated-base} \ . \label{fuzz-layering-approx} \end{eqnarray} The fuzz shading normal is assumed to inherit from that of the substrate layer, the physical picture being that the fuzz volume settles and conforms to the geometry of the substrate. The substrate is generally a mixture of coat and uncoated base. Thus physically the fuzz model should be evaluated with each of the **`geometry_coat_normal`** and **`geometry_normal`** separately (if they differ), and the final result blended according to the **`coat_weight`**. As a practical approximation, it may be more convenient and efficient to instead approximate the fuzz normal by interpolating the coat and base normal according to **`coat_weight`**. @@ -1124,17 +1137,17 @@ * +-------------------------------------------------+ * ******************************************************* -The intensity of the EDF is controlled by a luminance and a color multiplier. The **`emission_luminance`** parameter controls the luminance the emissive layer would have when **`emission_color`** is set to (1, 1, 1) and in the absence of coat and fuzz. The **`emission_color`** acts as a multiplier, i.e. the HDR emission in the model color space is defined to have a color given by **`emission_color`** * **`emission_luminance`**, thus the resulting luminance may be less than the input parameter, or even zero if the **`emission_color`** is set to (0, 0, 0). +The intensity of the EDF is controlled by a luminance value with color and weight multipliers. The color and weight act as multipliers, i.e. the HDR emission in the model color space is defined to have a color given by **`emission_weight`** * **`emission_color`** * **`emission_luminance`**. The **`emission_luminance`** parameter thus refers to the luminance the emissive layer would have when the color is white and weight is 1, and in the absence of coat and fuzz. Thus the final resulting luminance may be less than the input parameter, or even zero if the color or weight are zeroed. Note that the **`emission_color`** components may exceed 1, in order to be able to plug in an HDR texture. [^ingamut] Moreover, the overall material luminance may be further reduced in the presence of coat or fuzz, as they can absorb light coming from the emissive layer before it exits the surface. The emission from the top surface should in principle gain a directional dependence due to the combined effects of absorption, total internal reflection (TIR) and multiple bounces in the coat layer, and absorption in the fuzz layer. The combined effect should result mostly in darkening and saturation at grazing angles. -Being an intensity, **`emission_luminance`** can be any value greater than or equal to zero. For convenience, we make the soft range $[0, 1000]$, corresponding to the typical range of home appliances. +Being an intensity, **`emission_luminance`** can be any value greater than or equal to zero. For convenience, we make the soft range $[0, 1000]$, corresponding to the typical range of home appliances. (Note that if the renderer does not deal with photometric units internally, a scale factor may need to be applied to bring the emission into a sensible range). - -Emission params | Label | Type | Range | Norm | Default | Description --------------------------|-----------|----------|:---------------:|:-------------:|:-------------:|---------------------------------------------- -**`emission_luminance`** | Luminance | `float` | $ [0, \infty) $ | $ [0, 1000] $ | $ 0 $ | Emission luminance, in cd/m^2 (aka. nits) -**`emission_color`** | Color | `color3` | $ [0, 1]^3 $ | | $ (1, 1, 1) $ | Emission color multiplier +Emission params | Label | Type | Range | Norm | Default | Description +-------------------------|-----------|----------|:-----------------:|:-------------:|:-------------:|---------------------------------------------- +**`emission_weight`** | Weight | `float` | $ [0, 1] $ | | $ 0 $ | Emission weight luminance multiplier +**`emission_luminance`** | Luminance | `float` | $ [0, \infty) $ | $ [0, 1000] $ | $ 1000 $ | Emission luminance, in cd/m^2 (aka. nits) +**`emission_color`** | Color | `color3` | $ [0, \infty)^3 $ | | $ (1, 1, 1) $ | Emission color luminance multiplier ![](images/emitting_lava.png width=90% align=left) ![](images/emission_under_coat.png width=90% align=right)
@@ -1160,7 +1173,7 @@ * +- - - - - - - - - - - - - - - - - -+ +- - - - - - - - - - - - + - - - - - - - - - - - -+ * **************************************************************************************************** -Note that in the case of a non-thin-walled material, $\mathtt{\alpha} < 1$ doesn't make strict physical sense unless the entire surface is removed, whereas in the [thin-walled case](index.html#thin-walledcase) the opacity has a clear physical interpretation as the presence weight of the wall (or "cutout" areas where $\mathtt{\alpha} = 0$) like in the leaf render below. +Note that in the case of a non-thin-walled material, $\mathtt{\alpha} < 1$ doesn't make strict physical sense unless the entire surface is removed, whereas in the [thin-walled mode](index.html#thin-walledmode) the opacity has a clear physical interpretation as the presence weight of the wall (or "cutout" areas where $\mathtt{\alpha} = 0$) like in the leaf render below. We generally leave it as an implementation detail for a renderer to determine how connections to light sources be made through the surface. However a very common approximation used by many renderers is "transparent shadows", where a straight-line connection is made to lights and the contribution of the light determined by the total transmittance along the ray, ignoring any refraction events. We give here a suggested form for this shadow ray transmittance. @@ -1198,7 +1211,7 @@ The normal and tangent are assumed to be unit vectors. Reconstruction filtering techniques such as texture filtering may cause the interpolated value to not be normalized, which can be corrected with a renormalization to reduce visible artifacts caused by this filtering. -Thin-walled case +Thin-walled mode ------------------------------------- If the **`geometry_thin_walled`** Boolean is enabled, then the surface is assumed to be in a "thin-walled" mode. @@ -1261,9 +1274,9 @@ As an example, we give here a brief derivation of a mixture model representation analogous to Autodesk Standard Surface, from the stated material structure of OpenPBR. Following Autodesk Standard Surface, we assume here that layering is implemented via the non-reciprocal albedo-scaling of equation [non-reciprocal-albedo-scaling]. This derivation also informs how we implement our MaterialX [reference implementation](reference/open_pbr_surface.mtlx). -### Non-thin-walled case +### Non-thin-walled mode -Consider first the non-thin-walled case (i.e. **`geometry_thin_walled`** is false). +Consider first the default non-thin-walled mode (i.e. **`geometry_thin_walled`** is false). For brevity, in the following we suppress all the direction arguments, and use the notation of the tree diagram in the Model section for the weight factors i.e.: \begin{eqnarray} \mathtt{\alpha} &=& \mathtt{geometry\_opacity} \nonumber \\ @@ -1298,7 +1311,7 @@ Here the substrate lobes $\color{darkblue}{f^T_\textrm{specular}}$ and $\color{darkblue}{f_\textrm{SSS}}$ are technically BSSRDFs, which model the entry into the internal medium via the dielectric interface, transport of light from entry point to exit points including absorption and scattering processes, and exit from the medium back though the interface, generating both a reflection and transmission component. [^BSDF_BSSRDF_sum] The "specular" BTDF/BSSRDF $\color{darkblue}{f^T_\textrm{specular}}$ corresponds to transmission into the medium parametrized in the Translucent base section, and BSSRDF $\color{darkblue}{f_\textrm{SSS}}$ corresponds to transmission into the medium parametrized in the Subsurface section. In the case of $f_\textrm{glossy-diffuse}$, the BSSRDF degenerates into the BRDF $\color{darkblue}{f_\mathrm{diffuse}}$ as described in the Glossy-diffuse section. -Note that in this albedo-scaling approximation, the transmission Fresnel factor associated with $\color{darkblue}{f^T_\textrm{specular}}$ and $f_\textrm{SSS}$ can be *omitted* as the energy conservation of the dielectric BSDF as a whole is maintained automatically, even without explicit multiple scattering compensation or in the presence of modifications to the reflection Fresnel factor via **`specular_color`**. +Note that in this albedo-scaling approximation, the transmission Fresnel factor associated with $\color{darkblue}{f^T_\textrm{specular}}$ and $\color{darkblue}{f_\textrm{SSS}}$ can be *omitted* as the energy conservation of the dielectric BSDF as a whole is maintained automatically, even without explicit multiple scattering compensation or in the presence of modifications to the reflection Fresnel factor via **`specular_color`**. Since $\color{darkblue}{f^R_\textrm{specular}}$ appears in each of the three component slabs of the dielectric base, it follows that on collecting terms, $f_\textrm{dielectric-base}$ reduces to: @@ -1369,9 +1382,9 @@ | Diffuse reflection | $\color{darkblue}{f_\mathrm{diffuse}}$ | diffuse BRDF | as in the Glossy-diffuse section | -### Thin-walled case +### Thin-walled mode -In the thin walled case (i.e. when **`geometry_thin_walled`** is true), we will assume the approximation described in the Thin-walled case section where the coat and fuzz are ignored on the underside, and the surface always flipped to so that incident rays enter top-down. Then the derivation is the same as above except the translucent-base and subsurface slabs behave differently: +In the [thin-walled mode](index.html#model/thin-walledmode) (i.e. when **`geometry_thin_walled`** is true), the simplest approximation is to assume the coat and fuzz are ignored on the underside, and the surface always flipped so that incident rays enter top-down. Then the derivation is the same as above except the translucent-base and subsurface slabs behave differently: - The translucent-base reduces to a thin sheet of dielectric. This can just be considered the thin-wall limit of the BTDF $\color{darkblue}{f^T_\textrm{specular}}$. Note that in this limit, the reflection lobe from the dielectric $\color{darkblue}{f^R_\textrm{specular}}$ will also technically be modified due to the internal bounces in the sheet. @@ -1381,7 +1394,7 @@ ### Entering versus exiting -An aspect that has been ignored in this approximation (in the non-thin-walled case) is the different light transport for rays incident from the top or the bottom side. In reality the physical effect of the layers differs in these cases. For entering rays: +An aspect that has been ignored in this approximation (in the non-thin-walled mode) is the different light transport for rays incident from the top or the bottom side. In reality the physical effect of the layers differs in these cases. For entering rays: - The fuzz reflection is not tinted by the coat absorption. - The coat reflection is dimmed and roughened by the fuzz. @@ -1494,6 +1507,8 @@ Nicolas Wirrmann for their useful contributions. +The "shader playground" scene shown at the top of the document was authored by Nikie Monteleone. The shader ball used in various images is the Standard Shader Ball asset of [#Mazzone2023]. + References ============================================ @@ -1560,7 +1575,7 @@ [#Langlands2014]: Anders Langlands. *Physically Based Shader Design in Arnold*, ACM SIGGRAPH Talks (2014). -[#McAuley15]: Stephen McAuley, *Rendering the World of Far Cry 4*, GDC (2015). +[#Mazzone2023]: André Mazzone and Chris Rydalch. [*Standard Shader Ball: A Modern and Feature-Rich Render Test Scene*](https://github.com/usd-wg/assets/tree/main/full_assets/StandardShaderBall), ACM SIGGRAPH Asia (2023). [#McDermott2018]: Wes McDermott. [*The PBR Guide*](https://substance3d.adobe.com/tutorials/courses/the-pbr-guide-part-1), Allegorithmic white paper (2018). @@ -1574,7 +1589,7 @@ [#Polyanskiy2023]: Mikhail N. Polyanskiy. [*Refractive Index Database*](https://refractiveindex.info/) (2023). -[#Revie2011]: Donald Revie, *Implementing Fur Using Deferred Shading*, GPU Pro 2 (2011). +[#Portsmouth2024]: Jamie Portsmouth, Peter Kutz and Stephen Hill. [*EON: A practical energy-preserving rough diffuse BRDF*](https://arxiv.org/abs/2410.18026) (2024). [#Schott2023]: SCHOTT. [*Interactive Abbe Diagram*](https://www.schott.com/en-gb/interactive-abbe-diagram) (2023). @@ -1605,12 +1620,16 @@ [^lerp]: Where $\mathrm{lerp}(a, b, t) \equiv (1 - t) a + tb$. +[^ingamut]: Note that we assume that all RGB colors are in-gamut, and that colors representing albedos have components in the $[0,1]$ range (otherwise RGB renderers do not produce sensible results). The `emission_color` however is the exception which is permitted to have arbitrarily large (positive) components, since it represents an arbitrary luminance multiplier. + [^Jacobian]: Omitting Jacobian factors. [^normalization]: Omitting normalization factors. [^anisotropy_g]: Technically, $g$ is the _mean cosine of deflection_ of the phase function, which is not specific to the Henyey--Greenstein phase function model [#d'Eon2021]. +[^component_wise]: Note that in this concise notation, the scalar denotes a constant vector. + [^Oren_Nayar_formula]: The $s$ term is given by (with normal $\mathbf{n}$): \begin{eqnarray*} s = \omega_i \cdot \omega_o - (\mathbf{n} \cdot \omega_i) (\mathbf{n} \cdot \omega_o) \nonumber = \cos(\phi_i-\phi_o) \,\sin\theta_i \,\sin\theta_o @@ -1629,26 +1648,13 @@ B &=& \sigma A \ . \end{eqnarray} -[^Oren_Nayar_albedo]: The albedo of the [#Fujii2012] form of the Oren-Nayar BRDF is given by $E_\mathrm{ON}(\omega) = \rho\,\hat{E}_\mathrm{ON}(\omega)$, where -For unit $\rho$, -\begin{eqnarray} -\hat{E}_\mathrm{ON}(\omega) = A + \frac{B}{\pi} G(\omega) \ , -\end{eqnarray} -where (in spherical polars) -\begin{equation} -G(\theta) = \sin\theta \Bigl( \theta - \sin\theta \cos\theta \Bigr) + \frac{2}{3}\tan\theta \Bigl(1 - \sin^3\theta - \cos\theta\Bigr) \ . -\end{equation} -The corresponding albedo averaged over the hemisphere is given by -\begin{equation} -\langle\hat{E}_\mathrm{ON}\rangle = A + \left(\frac{2}{3} - \frac{28}{15\pi}\right) B \ . -\end{equation} - [^porosity]: In reality, coats can also darken the underlying surface due to a different mechanism where the coat modifies the Fresnel factor of the base due to the coat material filling in air gaps between granules or threads of a porous base material, which reduces the relative IORs at the internal interfaces. This occurs e.g. on adding water to sand or fabric, or adding a penetrating wood finish. We assume here that this effect explicitly does _not_ occur, at present, since we do not have enough knowledge about the properties of the underlying substance to model it. We can only safely assume that the first mechanism of darkening, i.e. internal reflections, occurs. [^avg_fresnel]: The hemispherical (or average) albedo of the Fresnel factor is defined as $E_F(\eta) \equiv 2 \int_0^1 F(\mu, \eta)\,\mu\,\mathrm{d}\mu$. This can be tabulated, or one can use the convenient analytical approximation [#d'Eon2021] (accurate to within 0.2% in the limited range $\eta \in [1,3]$): \begin{equation} E_F(\eta) \approx \ln \biggl( \frac{10893\eta - 1438.2}{-774.4\eta^2 + 10212\eta + 1} \biggr) \ . \end{equation} +(The more complicated exact formula is also provided in [#d'Eon2021], which we do not reproduce here). Values of $E_F(\eta)$ for $\eta < 1$ are related to the values for $\eta > 1$ via: \begin{equation} E_F(\eta) = 1 - \eta^2 \bigl(1 - E_F(1/\eta)\bigr) \ . @@ -1659,6 +1665,7 @@ [^BSDF_BSSRDF_sum]: This sum of BSDF and BSSRDF can be justified mathematically by interpreting a BSDF as the special case of a BSSRDF restricted to equal exit and entry points. +