From d4319fae0c8d3d29d7a2b46bac81c9c722aa2e08 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Mon, 2 Dec 2019 10:24:46 +0100 Subject: [PATCH 01/15] Rewrite Appendix B: BRDF Implementation. --- specification/2.0/README.md | 132 ++++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 35 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index ecf1eb4747..aa47809e1e 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3905,65 +3905,127 @@ Application-specific data. *This section is non-normative.* -The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. +The metallic-roughness material model is a linear blend of two BRDFs, a metallic BRDF and a dielectric BRDF. The blending factor `metallic` describes the metalness of the material. The BRDFs share the parameters for roughness and base color, following [Burley (2012): Physically-Based Shading at Disney](https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf). -An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. +``` +material = mix( + dielectric_brdf(baseColor, roughness^2), + metal_brdf(baseColor, roughness^2), + metallic) +``` -As previously defined +The metal BRDF is based on a microfacet model. The base color modifies the color at normal incidence. The roughness is squared to make it perceptually linear to allow interpolation between rough and smooth materials. -`const dielectricSpecular = rgb(0.04, 0.04, 0.04)` -
-`const black = rgb(0, 0, 0)` +The dielectric BRDF is a Fresnel-weighted combination of a diffuse BRDF and a microfacet BRDF. The Fresnel term uses a fixed index of refraction of 1.5, which is a good compromise for the majority of opaque, dielectric materials. -*cdiff* = `lerp(baseColor.rgb * (1 - dielectricSpecular.r), black, metallic)` -
-*F0* = `lerp(dieletricSpecular, baseColor.rgb, metallic)` -
-*α* = `roughness ^ 2` +``` +dielectric_brdf = + fresnel_mix( + diffuse_brdf(baseColor), + microfacet_brdf(roughness^2), + ior = 1.5) +``` -Additionally, -*V* is the normalized vector from the shading location to the eye -*L* is the normalized vector from the shading location to the light -*N* is the surface normal in the same space as the above values -*H* is the half vector, where *H* = normalize(*L*+*V*) +The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. Some implementations may focus on an accurate simulation of light transport, others may choose to deliver real-time performance. Therefore, any implementation that adheres to the rules for mixing BRDFs is compliant to the glTF spec. -The core lighting equation the sample uses is the Schlick BRDF model from [An Inexpensive BRDF Model for Physically-based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) +In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The specification will provide a mathematical model that allows implementations to achieve an exact result in an unbiased renderer. Note that unbiased renderers may still decide to deviate from the specification to achieve better visual quality. -![](figures/lightingSum.PNG) +The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take short-cuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the constraints of the platform (mobile or web applications, desktop applications on low or high-end hardware, VR), and the constraints change over time. -Below are common implementations for the various terms found in the lighting equation. +## Metal BRDF -### Surface Reflection Ratio (F) +The metallic reflection is modeled as a GGX microfacet BRDF with Schlick Fresnel term to configure the complex index of refraction via the `baseColor` of the material. The microfacet model lacks multiple scattering, resulting in high energy-loss with increased roughness. Accurate models to simulate multiple scattering are costly to compute. [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) introduces an easy approximation of the effect that does not violate the mathematical properties of a BRDF and, thus, can be used in unbiased ray tracing and real-time rasterizatiom. -**Fresnel Schlick** +``` +metal_brdf = + microfacet_brdf(alpha) * fresnel(HdotV, baseColor) + + multiscatter_microfacet_brdf(alpha) * multiscatter_fresnel(baseColor) +``` -Simplified implementation of Fresnel from [An Inexpensive BRDF Model for Physically based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) by Christophe Schlick. +The microfacet BRDF uses the GGX distribution and Smith height-correlated masking-shadowing term ([Heitz 2014: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf)). -![](figures/lightingF.PNG) +``` + 1 alpha^2 +D = -- -------------------------------- + pi (HdotN^2 * (alpha^2-1) + 1)^2 -### Geometric Occlusion (G) + 2 * NdotV * NdotL +G = ---------------------------------------------------------------------------------------------- + NdotL * sqrt(NdotV^2 * (1-alpha^2) + alpha^2) + NdotV * sqrt(NdotL^2 * (1-alpha^2) + alpha^2)) -**Smith Joint GGX** -[Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf) by Eric Heitz. + G * D +microfacet_brdf = -------------------- + 4 * NdotL * NdotV +``` -![](figures/lightingG.PNG) +The Schlick Fresnel is computed via the reflection half vector `H = normalize(V + L)`. -### Microfacet Distribution (D) +``` +fresnel = baseColor + (1 - baseColor) * (1 - HdotV)^5 +``` -**Trowbridge-Reitz** +The multi-scattering approximation uses the directional albedo `E_m` and average albedo `E_mavg` of the single-scattering model. These values are typically precomputed and fetched from a lookup table during rendering. The average Fresnel `F_mavg` for Schlick can be computed analytically. -Implementation of microfacet distrubtion from [Average Irregularity Representation of a Roughened Surface for Ray Reflection](https://www.osapublishing.org/josa/abstract.cfm?uri=josa-65-5-531) by T. S. Trowbridge, and K. P. Reitz +``` + (1 - E_m(VdotN)) * (1 - E_m(LdotN)) +multiscatter_microfacet_brdf = ----------------------------------- + pi * (1 - E_mavg) -![](figures/lightingD.PNG) + 1 20 +F_mavg = ---- * baseColor + ---- + 21 21 -### Diffuse Term (diffuse) + F_mavg^2 E_mavg +multiscatter_fresnel = ------------------------- + 1 - F_mavg * (1 - E_mavg) +``` -**Lambert** +Although it is possible to compute the multi-scattering approximation in real-time (see [McAuley (2019): A Journey Through Implementing Multiscattering BRDFs and Area Lights](http://i3dsymposium.github.io/2019/keynotes/I3D2019_keynote_StephenMcAuley.pdf)), implementations may omit it to improve performance. + +## Dielectric BRDF + +Dielectric materials like plastics are modeled as a GGX microfacet BRDF coupled with a diffuse BRDF via the Schlick Fresnel term in the `fresnel_mix` operation. Microfacet BRDF and multi-scattering approximation are the same as in the metal BRDF. The diffuse reflection is modeled with a Lambertian BRDF. + +``` + 1 +diffuse_brdf = ---- + pi +``` + +The Fresnel term in the mixing operation and its multi-scattering equivalent are now computed with the index of refraction, which is fixed at 1.5. + +``` +f0 = ((1-ior)/(1+ior))^2 = 0.04 +fresnel = f0 + (1 - f0) * (1 - HdotV)^5 + + 1 20 +F_mavg = ---- * f0 + ---- + 21 21 +``` + +An energy-conserving and energy-preserving coupling can be achieved via the same albedo-scaling technique as in the metal BRDF, as shown in [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf). + +The `fresnel_mix` operation weights the (multi-scatter) microfacet BRDF with the Fresnel term, and the diffuse BRDF with `diffuse_weight`. + +``` +dielectric_brdf = + diffuse_brdf() * diffuse_weight(VdotN, LdotN, f0) + + microfacet_brdf(alpha) * fresnel(HdotV, f0) + + multiscatter_microfacet_brdf(alpha) * multiscatter_fresnel(f0) +``` + +`diffuse_weight` is derived from the albedo of the BRDFs involved in the mixing. The directional albedo `E` and average albedo `Eavg` of the microfacet BRDF (including multiple scattering) are measured and used to scale the diffuse BRDF such that it scatters the remaining energy of the microfacet BRDF equally in all directions. + +``` + (1 - E(VdotN, f0)) * (1 - E(LdotN, f0)) +diffuse_weight = ----------------------------------------- + 1 - Eavg(f0) +``` -Implementation of diffuse from [Lambert's Photometria](https://archive.org/details/lambertsphotome00lambgoog) by Johann Heinrich Lambert +There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. -![](figures/lightingDiff.PNG) +*TODO: typesetting equations, images for BRDFs, white furnace test showing difference between albedo scaling and real-time weightings* # Appendix C: Spline Interpolation From 4ba472d8a4024a5333a899f42207e56b5b95d4af Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Sat, 21 Dec 2019 16:39:04 +0100 Subject: [PATCH 02/15] Add more details. --- specification/2.0/README.md | 41 +++++++++++------ specification/2.0/figures/pbr.dot | 73 ++++++++++++++++++++++++++++++ specification/2.0/figures/pbr.png | Bin 0 -> 20615 bytes 3 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 specification/2.0/figures/pbr.dot create mode 100644 specification/2.0/figures/pbr.png diff --git a/specification/2.0/README.md b/specification/2.0/README.md index aa47809e1e..6a9a4c33a5 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3903,36 +3903,51 @@ Application-specific data. # Appendix B: BRDF Implementation -*This section is non-normative.* - The metallic-roughness material model is a linear blend of two BRDFs, a metallic BRDF and a dielectric BRDF. The blending factor `metallic` describes the metalness of the material. The BRDFs share the parameters for roughness and base color, following [Burley (2012): Physically-Based Shading at Disney](https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf). ``` -material = mix( - dielectric_brdf(baseColor, roughness^2), - metal_brdf(baseColor, roughness^2), - metallic) +material = mix(dielectric_brdf, metal_brdf, metallic) ``` -The metal BRDF is based on a microfacet model. The base color modifies the color at normal incidence. The roughness is squared to make it perceptually linear to allow interpolation between rough and smooth materials. +The metal BRDF is based on a microfacet model which describes the orientation of microfacets on the surface as a statistical distribution. The distribution is controlled by a parameter called `roughness`, varying between 0 (smooth surface) and 1 (rough surface). For most microfacet distributions the blending between the two extremes does not behave linear, making it necessary to square the material's `roughness` parameter before using it as the distribution's roughness. -The dielectric BRDF is a Fresnel-weighted combination of a diffuse BRDF and a microfacet BRDF. The Fresnel term uses a fixed index of refraction of 1.5, which is a good compromise for the majority of opaque, dielectric materials. +Most metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material. This effect is described by the Fresnel term with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. + +``` +metal_brdf = + conductor_fresnel( + f0 = baseColor, + f90 = 1, + bsdf = specular_brdf(roughness^2)) +``` + +Unlike metals, dielectric materials transmit most of the incident illumination into the interior of the object and the Fresnel term is parameterized only by the refractive index. This makes dielectrics like glass, oil, water or air transparent. Other dielectrics, like the majority of plastic materials, are filled with particles that absorb or scatter most or all of the transmitted light, reducing the transparency and giving the surface its colorful appearance. + +As a result, dielectric materials are modeled as a Fresnel-weighted combination of a microfacet BRDF, simulating the reflection at the surface, and a diffuse BRDF, simulating the transmitted portion of the light that is absorbed and scattered inside the object. The reflection roughness is given by the squared `roughness` of the material. The color of the diffuse BRDF comes from the `baseColor`. The amount of reflection compared to transmission is directional-dependent and as such determined by the Fresnel term. Its index of refraction is set to a fixed value of 1.5, a good compromise for the majority of opaque, dielectric materials. ``` dielectric_brdf = fresnel_mix( - diffuse_brdf(baseColor), - microfacet_brdf(roughness^2), + base = diffuse_brdf(baseColor), + layer = specular_brdf(roughness^2), ior = 1.5) ``` +The BRDFs and mixing operators used in the metallic-roughness material are summarized in the following image. + +![](figures/pbr.png) + The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. Some implementations may focus on an accurate simulation of light transport, others may choose to deliver real-time performance. Therefore, any implementation that adheres to the rules for mixing BRDFs is compliant to the glTF spec. In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The specification will provide a mathematical model that allows implementations to achieve an exact result in an unbiased renderer. Note that unbiased renderers may still decide to deviate from the specification to achieve better visual quality. The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take short-cuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the constraints of the platform (mobile or web applications, desktop applications on low or high-end hardware, VR), and the constraints change over time. -## Metal BRDF +## Implementation + +*This section is non-normative.* + +### Metal BRDF The metallic reflection is modeled as a GGX microfacet BRDF with Schlick Fresnel term to configure the complex index of refraction via the `baseColor` of the material. The microfacet model lacks multiple scattering, resulting in high energy-loss with increased roughness. Accurate models to simulate multiple scattering are costly to compute. [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) introduces an easy approximation of the effect that does not violate the mathematical properties of a BRDF and, thus, can be used in unbiased ray tracing and real-time rasterizatiom. @@ -3983,7 +3998,7 @@ multiscatter_fresnel = ------------------------- Although it is possible to compute the multi-scattering approximation in real-time (see [McAuley (2019): A Journey Through Implementing Multiscattering BRDFs and Area Lights](http://i3dsymposium.github.io/2019/keynotes/I3D2019_keynote_StephenMcAuley.pdf)), implementations may omit it to improve performance. -## Dielectric BRDF +### Dielectric BRDF Dielectric materials like plastics are modeled as a GGX microfacet BRDF coupled with a diffuse BRDF via the Schlick Fresnel term in the `fresnel_mix` operation. Microfacet BRDF and multi-scattering approximation are the same as in the metal BRDF. The diffuse reflection is modeled with a Lambertian BRDF. @@ -4025,7 +4040,7 @@ diffuse_weight = ----------------------------------------- There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. -*TODO: typesetting equations, images for BRDFs, white furnace test showing difference between albedo scaling and real-time weightings* +*TODO: clean-up and typeset equations, images for BRDFs, white furnace test showing difference between albedo scaling and real-time weightings* # Appendix C: Spline Interpolation diff --git a/specification/2.0/figures/pbr.dot b/specification/2.0/figures/pbr.dot new file mode 100644 index 0000000000..4bd0acb532 --- /dev/null +++ b/specification/2.0/figures/pbr.dot @@ -0,0 +1,73 @@ +digraph D { + graph [rankdir="LR", fontname="Helvetica"] + node [shape=plaintext, fontname="Helvetica"] + edge [fontname="Helvetica"] + + subgraph cluster_dielectric { + label="Dielectric" + + dielectric_specular_brdf [label=< + + + + +
specular_brdf
color = [1, 1, 1]
roughness = <roughness>2
+ >] + + dielectric_diffuse_brdf [label=< + + + +
diffuse_brdf
color = <baseColor>
+ >] + + dielectric_fresnel_mix [label=< + + + + + +
fresnel_mix 
layer
base
ior = 1.5
+ >] + + dielectric_diffuse_brdf:out -> dielectric_fresnel_mix:in_base + dielectric_specular_brdf:out -> dielectric_fresnel_mix:in_layer + } + + subgraph cluster_metal { + label="Metal" + + metal_specular_brdf [label=< + + + + +
specular_brdf
color = [1, 1, 1]
roughness = <roughness>2
+ >] + + metal_conductor_fresnel [label=< + + + + + +
conductor_fresnel  
bsdf
f0 = <baseColor>
f90 = [1, 1, 1]
+ >] + + metal_specular_brdf:out -> metal_conductor_fresnel:in_bsdf + } + + subgraph core { + core_mix [label=< + + + + + +
mix
bsdf0
bsdf1
weight = <metallic>
+ >] + + dielectric_fresnel_mix:out -> core_mix:in_bsdf0 + metal_conductor_fresnel:out -> core_mix:in_bsdf1 + } +} diff --git a/specification/2.0/figures/pbr.png b/specification/2.0/figures/pbr.png new file mode 100644 index 0000000000000000000000000000000000000000..75bd80d1c6dcc998a269965d677b50c8f79e5f54 GIT binary patch literal 20615 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 Date: Thu, 16 Jan 2020 13:02:01 +0100 Subject: [PATCH 03/15] Remove redundant description of BSDF implementation. --- specification/2.0/README.md | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 6a9a4c33a5..86b14302b5 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -1164,19 +1164,7 @@ Then, the result would be [0.9 * 0.2, 0.5 * 1.0, 0.3 * 0.7, 1.0 * 1.0] = [0.18, 0.5, 0.21, 1.0] ``` -The following equations show how to calculate bidirectional reflectance distribution function (BRDF) inputs (*cdiff*, *F0*, *α*) from the metallic-roughness material properties. In addition to the material properties, if a primitive specifies a vertex color using the attribute semantic property `COLOR_0`, then this value acts as an additional linear multiplier to `baseColor`. - -`const dielectricSpecular = rgb(0.04, 0.04, 0.04)` -
-`const black = rgb(0, 0, 0)` - -*cdiff* = `lerp(baseColor.rgb * (1 - dielectricSpecular.r), black, metallic)` -
-*F0* = `lerp(dieletricSpecular, baseColor.rgb, metallic)` -
-*α* = `roughness ^ 2` - -All implementations should use the same calculations for the BRDF inputs. Implementations of the BRDF itself can vary based on device performance and resource constraints. See [Appendix B](#appendix-b-brdf-implementation) for more details on the BRDF calculations. +Implementations of the BRDF itself can vary based on device performance and resource constraints. See [Appendix B](#appendix-b-brdf-implementation) for more details on the BRDF calculations. ### Additional Maps From 22843d60e808c5691cb561b333195e46ce34d756 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Wed, 29 Jan 2020 19:35:24 +0100 Subject: [PATCH 04/15] Add function args. --- specification/2.0/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 86b14302b5..f450c614a5 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3971,17 +3971,17 @@ fresnel = baseColor + (1 - baseColor) * (1 - HdotV)^5 The multi-scattering approximation uses the directional albedo `E_m` and average albedo `E_mavg` of the single-scattering model. These values are typically precomputed and fetched from a lookup table during rendering. The average Fresnel `F_mavg` for Schlick can be computed analytically. ``` - (1 - E_m(VdotN)) * (1 - E_m(LdotN)) -multiscatter_microfacet_brdf = ----------------------------------- - pi * (1 - E_mavg) + (1 - E_m(VdotN, alpha)) * (1 - E_m(LdotN, alpha)) +multiscatter_microfacet_brdf = -------------------------------------------------- + pi * (1 - E_mavg(alpha)) 1 20 F_mavg = ---- * baseColor + ---- 21 21 - F_mavg^2 E_mavg -multiscatter_fresnel = ------------------------- - 1 - F_mavg * (1 - E_mavg) + F_mavg^2 E_mavg(alpha) +multiscatter_fresnel = --------------------------------- + 1 - F_mavg * (1 - E_mavg(alpha)) ``` Although it is possible to compute the multi-scattering approximation in real-time (see [McAuley (2019): A Journey Through Implementing Multiscattering BRDFs and Area Lights](http://i3dsymposium.github.io/2019/keynotes/I3D2019_keynote_StephenMcAuley.pdf)), implementations may omit it to improve performance. @@ -4021,9 +4021,9 @@ dielectric_brdf = `diffuse_weight` is derived from the albedo of the BRDFs involved in the mixing. The directional albedo `E` and average albedo `Eavg` of the microfacet BRDF (including multiple scattering) are measured and used to scale the diffuse BRDF such that it scatters the remaining energy of the microfacet BRDF equally in all directions. ``` - (1 - E(VdotN, f0)) * (1 - E(LdotN, f0)) -diffuse_weight = ----------------------------------------- - 1 - Eavg(f0) + (1 - E(VdotN, alpha, f0)) * (1 - E(LdotN, alpha, f0)) +diffuse_weight = ------------------------------------------------------- + 1 - Eavg(alpha, f0) ``` There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. From 4961bec48f0eb525b9b427e2e6316e2817c64d0b Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Thu, 30 Jan 2020 14:17:20 +0100 Subject: [PATCH 05/15] Add missing baseColor in dielectric BRDF. --- specification/2.0/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index f450c614a5..42d2df6cc7 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -4013,7 +4013,7 @@ The `fresnel_mix` operation weights the (multi-scatter) microfacet BRDF with the ``` dielectric_brdf = - diffuse_brdf() * diffuse_weight(VdotN, LdotN, f0) + + diffuse_brdf() * diffuse_weight(VdotN, LdotN, f0) * baseColor + microfacet_brdf(alpha) * fresnel(HdotV, f0) + multiscatter_microfacet_brdf(alpha) * multiscatter_fresnel(f0) ``` From 255d2ce72d7384553391e67d1ee1c9662aedb40a Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Tue, 4 Feb 2020 17:06:25 +0100 Subject: [PATCH 06/15] Fixed average Fresnel. --- specification/2.0/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 42d2df6cc7..ff95d3f2b6 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3975,9 +3975,9 @@ The multi-scattering approximation uses the directional albedo `E_m` and average multiscatter_microfacet_brdf = -------------------------------------------------- pi * (1 - E_mavg(alpha)) - 1 20 -F_mavg = ---- * baseColor + ---- - 21 21 + 1 20 +F_mavg = ---- + ---- * baseColor + 21 21 F_mavg^2 E_mavg(alpha) multiscatter_fresnel = --------------------------------- @@ -4002,9 +4002,9 @@ The Fresnel term in the mixing operation and its multi-scattering equivalent are f0 = ((1-ior)/(1+ior))^2 = 0.04 fresnel = f0 + (1 - f0) * (1 - HdotV)^5 - 1 20 -F_mavg = ---- * f0 + ---- - 21 21 + 1 20 +F_mavg = ---- + ---- * f0 + 21 21 ``` An energy-conserving and energy-preserving coupling can be achieved via the same albedo-scaling technique as in the metal BRDF, as shown in [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf). From 5a684c0d0d5189f27633cbfd9320fe958696fe95 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Fri, 17 Jul 2020 10:18:07 +0200 Subject: [PATCH 07/15] Add CR suggestions. --- specification/2.0/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index ff95d3f2b6..6397beb976 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3897,7 +3897,7 @@ The metallic-roughness material model is a linear blend of two BRDFs, a metallic material = mix(dielectric_brdf, metal_brdf, metallic) ``` -The metal BRDF is based on a microfacet model which describes the orientation of microfacets on the surface as a statistical distribution. The distribution is controlled by a parameter called `roughness`, varying between 0 (smooth surface) and 1 (rough surface). For most microfacet distributions the blending between the two extremes does not behave linear, making it necessary to square the material's `roughness` parameter before using it as the distribution's roughness. +The metal BRDF is based on a microfacet model which describes the orientation of microfacets on the surface as a statistical distribution. The distribution is controlled by a parameter called `roughness`, varying between 0 (smooth surface) and 1 (rough surface). As the blending between the two extremes does not behave linearly, like most microfacet distributions, the material's `roughness` parameter is squared before using it as the distribution's roughness. Most metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material. This effect is described by the Fresnel term with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. @@ -3925,11 +3925,11 @@ The BRDFs and mixing operators used in the metallic-roughness material are summa ![](figures/pbr.png) -The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. Some implementations may focus on an accurate simulation of light transport, others may choose to deliver real-time performance. Therefore, any implementation that adheres to the rules for mixing BRDFs is compliant to the glTF spec. +The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. Some implementations may focus on an accurate simulation of light transport while others may choose to deliver real-time performance. Therefore, any implementation that adheres to the rules for mixing BRDFs is conformant to the glTF spec. In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The specification will provide a mathematical model that allows implementations to achieve an exact result in an unbiased renderer. Note that unbiased renderers may still decide to deviate from the specification to achieve better visual quality. -The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take short-cuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the constraints of the platform (mobile or web applications, desktop applications on low or high-end hardware, VR), and the constraints change over time. +The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take shortcuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the constraints of the platform (mobile or web applications, desktop applications on low or high-end hardware, VR), and the constraints change over time. ## Implementation @@ -4026,7 +4026,7 @@ diffuse_weight = ------------------------------------------------------- 1 - Eavg(alpha, f0) ``` -There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. +There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. *TODO: clean-up and typeset equations, images for BRDFs, white furnace test showing difference between albedo scaling and real-time weightings* From c14920dcfe400b28644109944f9ba67fe1422e89 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Fri, 17 Jul 2020 10:19:50 +0200 Subject: [PATCH 08/15] Minor improvements. --- specification/2.0/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 6397beb976..aaa0052ab4 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3899,7 +3899,7 @@ material = mix(dielectric_brdf, metal_brdf, metallic) The metal BRDF is based on a microfacet model which describes the orientation of microfacets on the surface as a statistical distribution. The distribution is controlled by a parameter called `roughness`, varying between 0 (smooth surface) and 1 (rough surface). As the blending between the two extremes does not behave linearly, like most microfacet distributions, the material's `roughness` parameter is squared before using it as the distribution's roughness. -Most metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material. This effect is described by the Fresnel term with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. +Metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material. This effect is described by the Fresnel term with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. ``` metal_brdf = @@ -3929,7 +3929,7 @@ The glTF spec is designed to allow applications to choose different lighting imp In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The specification will provide a mathematical model that allows implementations to achieve an exact result in an unbiased renderer. Note that unbiased renderers may still decide to deviate from the specification to achieve better visual quality. -The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take shortcuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the constraints of the platform (mobile or web applications, desktop applications on low or high-end hardware, VR), and the constraints change over time. +The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take shortcuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the platform (mobile or web applications, desktop applications on low or high-end hardware, VR) different constraints have to be taken into account. ## Implementation @@ -3937,7 +3937,7 @@ The unbiased light simulation with physically realistic BRDFs will be the ground ### Metal BRDF -The metallic reflection is modeled as a GGX microfacet BRDF with Schlick Fresnel term to configure the complex index of refraction via the `baseColor` of the material. The microfacet model lacks multiple scattering, resulting in high energy-loss with increased roughness. Accurate models to simulate multiple scattering are costly to compute. [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) introduces an easy approximation of the effect that does not violate the mathematical properties of a BRDF and, thus, can be used in unbiased ray tracing and real-time rasterizatiom. +The metallic reflection is modeled as a GGX microfacet BRDF with Schlick Fresnel term to configure the complex index of refraction via the `baseColor` of the material. The microfacet model lacks multiple scattering, resulting in high energy-loss with increased roughness. Accurate models to simulate multiple scattering are costly to compute. [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) introduces an easy approximation of the effect that does not violate the mathematical properties of a BRDF and, thus, can be used in unbiased ray tracing and real-time rasterization. ``` metal_brdf = @@ -4028,8 +4028,6 @@ diffuse_weight = ------------------------------------------------------- There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. -*TODO: clean-up and typeset equations, images for BRDFs, white furnace test showing difference between albedo scaling and real-time weightings* - # Appendix C: Spline Interpolation Animations in glTF support spline interpolation with a cubic spline. From 62d9174e1e3ee2b0dd5db29c3e4711a580ad7d0a Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Fri, 17 Jul 2020 11:27:00 +0200 Subject: [PATCH 09/15] Restore sample viewer implementation in implementation sections. --- specification/2.0/README.md | 103 ++++++++++++------------------------ 1 file changed, 34 insertions(+), 69 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index aaa0052ab4..e5a7378a3d 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3935,98 +3935,63 @@ The unbiased light simulation with physically realistic BRDFs will be the ground *This section is non-normative.* -### Metal BRDF +An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. -The metallic reflection is modeled as a GGX microfacet BRDF with Schlick Fresnel term to configure the complex index of refraction via the `baseColor` of the material. The microfacet model lacks multiple scattering, resulting in high energy-loss with increased roughness. Accurate models to simulate multiple scattering are costly to compute. [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) introduces an easy approximation of the effect that does not violate the mathematical properties of a BRDF and, thus, can be used in unbiased ray tracing and real-time rasterization. +As previously defined -``` -metal_brdf = - microfacet_brdf(alpha) * fresnel(HdotV, baseColor) + - multiscatter_microfacet_brdf(alpha) * multiscatter_fresnel(baseColor) -``` +`const dielectricSpecular = rgb(0.04, 0.04, 0.04)` +
+`const black = rgb(0, 0, 0)` -The microfacet BRDF uses the GGX distribution and Smith height-correlated masking-shadowing term ([Heitz 2014: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf)). +*cdiff* = `lerp(baseColor.rgb * (1 - dielectricSpecular.r), black, metallic)` +
+*F0* = `lerp(dieletricSpecular, baseColor.rgb, metallic)` +
+*α* = `roughness ^ 2` -``` - 1 alpha^2 -D = -- -------------------------------- - pi (HdotN^2 * (alpha^2-1) + 1)^2 +Additionally, +*V* is the normalized vector from the shading location to the eye +*L* is the normalized vector from the shading location to the light +*N* is the surface normal in the same space as the above values +*H* is the half vector, where *H* = normalize(*L*+*V*) - 2 * NdotV * NdotL -G = ---------------------------------------------------------------------------------------------- - NdotL * sqrt(NdotV^2 * (1-alpha^2) + alpha^2) + NdotV * sqrt(NdotL^2 * (1-alpha^2) + alpha^2)) +The core lighting equation the sample uses is the Schlick BRDF model from [An Inexpensive BRDF Model for Physically-based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) +![](figures/lightingSum.PNG) - G * D -microfacet_brdf = -------------------- - 4 * NdotL * NdotV -``` +Below are common implementations for the various terms found in the lighting equation. -The Schlick Fresnel is computed via the reflection half vector `H = normalize(V + L)`. +### Surface Reflection Ratio (F) -``` -fresnel = baseColor + (1 - baseColor) * (1 - HdotV)^5 -``` +**Fresnel Schlick** -The multi-scattering approximation uses the directional albedo `E_m` and average albedo `E_mavg` of the single-scattering model. These values are typically precomputed and fetched from a lookup table during rendering. The average Fresnel `F_mavg` for Schlick can be computed analytically. +Simplified implementation of Fresnel from [An Inexpensive BRDF Model for Physically based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) by Christophe Schlick. -``` - (1 - E_m(VdotN, alpha)) * (1 - E_m(LdotN, alpha)) -multiscatter_microfacet_brdf = -------------------------------------------------- - pi * (1 - E_mavg(alpha)) +![](figures/lightingF.PNG) - 1 20 -F_mavg = ---- + ---- * baseColor - 21 21 +### Geometric Occlusion (G) - F_mavg^2 E_mavg(alpha) -multiscatter_fresnel = --------------------------------- - 1 - F_mavg * (1 - E_mavg(alpha)) -``` +**Smith Joint GGX** -Although it is possible to compute the multi-scattering approximation in real-time (see [McAuley (2019): A Journey Through Implementing Multiscattering BRDFs and Area Lights](http://i3dsymposium.github.io/2019/keynotes/I3D2019_keynote_StephenMcAuley.pdf)), implementations may omit it to improve performance. +[Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf) by Eric Heitz. -### Dielectric BRDF +![](figures/lightingG.PNG) -Dielectric materials like plastics are modeled as a GGX microfacet BRDF coupled with a diffuse BRDF via the Schlick Fresnel term in the `fresnel_mix` operation. Microfacet BRDF and multi-scattering approximation are the same as in the metal BRDF. The diffuse reflection is modeled with a Lambertian BRDF. +### Microfacet Distribution (D) -``` - 1 -diffuse_brdf = ---- - pi -``` +**Trowbridge-Reitz** -The Fresnel term in the mixing operation and its multi-scattering equivalent are now computed with the index of refraction, which is fixed at 1.5. +Implementation of microfacet distrubtion from [Average Irregularity Representation of a Roughened Surface for Ray Reflection](https://www.osapublishing.org/josa/abstract.cfm?uri=josa-65-5-531) by T. S. Trowbridge, and K. P. Reitz -``` -f0 = ((1-ior)/(1+ior))^2 = 0.04 -fresnel = f0 + (1 - f0) * (1 - HdotV)^5 - - 1 20 -F_mavg = ---- + ---- * f0 - 21 21 -``` - -An energy-conserving and energy-preserving coupling can be achieved via the same albedo-scaling technique as in the metal BRDF, as shown in [Kulla and Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf). - -The `fresnel_mix` operation weights the (multi-scatter) microfacet BRDF with the Fresnel term, and the diffuse BRDF with `diffuse_weight`. +![](figures/lightingD.PNG) -``` -dielectric_brdf = - diffuse_brdf() * diffuse_weight(VdotN, LdotN, f0) * baseColor + - microfacet_brdf(alpha) * fresnel(HdotV, f0) + - multiscatter_microfacet_brdf(alpha) * multiscatter_fresnel(f0) -``` +### Diffuse Term (diffuse) -`diffuse_weight` is derived from the albedo of the BRDFs involved in the mixing. The directional albedo `E` and average albedo `Eavg` of the microfacet BRDF (including multiple scattering) are measured and used to scale the diffuse BRDF such that it scatters the remaining energy of the microfacet BRDF equally in all directions. +**Lambert** -``` - (1 - E(VdotN, alpha, f0)) * (1 - E(LdotN, alpha, f0)) -diffuse_weight = ------------------------------------------------------- - 1 - Eavg(alpha, f0) -``` +Implementation of diffuse from [Lambert's Photometria](https://archive.org/details/lambertsphotome00lambgoog) by Johann Heinrich Lambert -There are several options to simplify this method for real-time rendering, like omitting `E(LdotN)`, replacing the `diffuse_weight` by `1 - fresnel`, or replacing it by 1. Note that this will violate certain physical properties of BRDFs. An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. +![](figures/lightingDiff.PNG) # Appendix C: Spline Interpolation From 25f01b01a584e94128696681a6c9c91441286480 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Mon, 17 Aug 2020 17:31:28 +0200 Subject: [PATCH 10/15] Add details about microfacet model and rewrite some parts as suggested by reviewers. --- specification/2.0/README.md | 49 +++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index e5a7378a3d..18fc56e8f7 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3891,15 +3891,22 @@ Application-specific data. # Appendix B: BRDF Implementation -The metallic-roughness material model is a linear blend of two BRDFs, a metallic BRDF and a dielectric BRDF. The blending factor `metallic` describes the metalness of the material. The BRDFs share the parameters for roughness and base color, following [Burley (2012): Physically-Based Shading at Disney](https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf). +The metallic-roughness material model is a linear blend of two bidirectional scattering distribution functions (BRDF), a metallic BRDF and a dielectric BRDF, as introduced by [Burley (2012)](#Burley2012). The BRDFs share the parameters for roughness and base color. The blending factor `metallic` describes the metalness of the material. ``` material = mix(dielectric_brdf, metal_brdf, metallic) + = (1 - metallic) * dielectric_brdf + metallic * metal_brdf ``` -The metal BRDF is based on a microfacet model which describes the orientation of microfacets on the surface as a statistical distribution. The distribution is controlled by a parameter called `roughness`, varying between 0 (smooth surface) and 1 (rough surface). As the blending between the two extremes does not behave linearly, like most microfacet distributions, the material's `roughness` parameter is squared before using it as the distribution's roughness. +Usually, a material is either metallic or dielectric. A texture provided for `metallic` with either 1 or 0 separates metallic from dielectric regions on the mesh. There are situations in which there is no clear separation. It may happen that due to anti-alising or mip-mapping there is a portion of metal and a portion of dielectric within a texel. Futhermore, a material composed of several semi-transparent layers may be represented as a blend between several single-layered materials (layering via parameter blending). -Metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material. This effect is described by the Fresnel term with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. +In this chapter, we will first sketch the logical structure of the material. We use an abstract notation that describes the material as a directed acyclic graph (DAG). The vertices correspond to the basic building blocks of the material model: BRDFs, mixing operators, input parameters, and constants. In the second part we will provide a sample implementation as a set of equations and source code for the BRDFs and mixing operators. In contrast to the logical structure the implementation is not normative. + +## Material Structure + +### Metals + +Metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material ([Pharr et al. (2018)](#Pharr2018)). This effect is described by the Fresnel term `conductor_fresnel` with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. The reflection color at grazing incidence is called `f90`. It is set to 1 because the grazing angle reflectance for any material approaches pure white in the limit. The conductor Fresnel term modulates the contribution of a specular BRDF parameterized by the `roughness` parameter. ``` metal_brdf = @@ -3909,9 +3916,11 @@ metal_brdf = bsdf = specular_brdf(roughness^2)) ``` -Unlike metals, dielectric materials transmit most of the incident illumination into the interior of the object and the Fresnel term is parameterized only by the refractive index. This makes dielectrics like glass, oil, water or air transparent. Other dielectrics, like the majority of plastic materials, are filled with particles that absorb or scatter most or all of the transmitted light, reducing the transparency and giving the surface its colorful appearance. +### Dielectrics -As a result, dielectric materials are modeled as a Fresnel-weighted combination of a microfacet BRDF, simulating the reflection at the surface, and a diffuse BRDF, simulating the transmitted portion of the light that is absorbed and scattered inside the object. The reflection roughness is given by the squared `roughness` of the material. The color of the diffuse BRDF comes from the `baseColor`. The amount of reflection compared to transmission is directional-dependent and as such determined by the Fresnel term. Its index of refraction is set to a fixed value of 1.5, a good compromise for the majority of opaque, dielectric materials. +Unlike metals, dielectric materials transmit most of the incident illumination into the interior of the object and the Fresnel term is parameterized only by the refractive index ([Pharr et al. (2018)](#Pharr2018)). This makes dielectrics like glass, oil, water or air transparent. Other dielectrics, like the majority of plastic materials, are filled with particles that absorb or scatter most or all of the transmitted light, reducing the transparency and giving the surface its colorful appearance. + +As a result, dielectric materials are modeled as a Fresnel-weighted combination of a specular BRDF, simulating the reflection at the surface, and a diffuse BRDF, simulating the transmitted portion of the light that is absorbed and scattered inside the object. The reflection roughness is given by the squared `roughness` of the material. The color of the diffuse BRDF comes from the `baseColor`. The amount of reflection compared to transmission is directional-dependent and as such determined by the Fresnel term. Its index of refraction is set to a fixed value of 1.5, a good compromise for the majority of opaque, dielectric materials. ``` dielectric_brdf = @@ -3921,13 +3930,25 @@ dielectric_brdf = ior = 1.5) ``` +### Microfacet Surfaces + +The metal BRDF and the dielectric BRDF are based on a microfacet model. The theory behind microfacet models was developed in early works by [Torrance and Sparrow (1967)](#TorranceSparrow1967), [Cook and Torrance (1982)](#CookTorrance1982), and others. A microfacet model describes the orientation of tiny facets (microfacets) on the surface as a statistical distribution. The distribution determines the orientation of the facets as a random perturbation around the normal direction of the surface. The perturbation strength depends on the `roughness` parameter and varies between 0 (smooth surface) and 1 (rough surface). A number of distribution functions have been proposed in the last decades. We use the Trowbridge-Reitz distribution first described by [Trowbridge and Reitz (1975)](#TrowbridgeReitz1975). Later [Walter et al. (2007)](#Walter2007) independently developed the same distribution and called it "GGX". They show that it is a better fit for measured data than the Beckmann distribution used by [Cook and Torrance (1982)](#CookTorrance1982) due to its stronger tails. + +The Trowbridge-Reitz/GGX microfacet distribution describes the microsurface as being composed of perfectly specular, infinitesimal oblate ellipsoids, whose half-height in the normal direction is α times the radius in the tangent plane. α = 1 gives spheres, which results in uniform reflection in all directions. This reflection behavior corresponds to a rough surface. α = 0 gives a perfectly specular surface. As suggested by [Burley (2012)](#Burley2012) we use the mapping α = `roughness`^2 which results in more perceptually linear changes in the roughness. + +The distribution only describes the proportion of each normal on the microsurface. It does not describe how the normals are organized. For this we need a microsurface profile. The difference between distribution and profile is detailed by [Heitz (2014)](#Heitz2014), where he in addition provides an extensive study of common microfacet profiles. Based on this work, we suggest using the Smith microsurface profile (originally developed by [Smith (1967)](#Smith1967)) and its corresponding masking-shadowing function. Heitz describes the Smith profile as the most accurate model for reflection from random height fields. It assumes that height and normal between neighboring points are not correlated, implying a random set of microfacets instead of a continuous surface. + +Microfacet models often do not consider multiple scattering. The shadowing term suppresses light that intersects the microsurface a second time. [Heitz et al. (2016)](#Heitz2016) extended the Smith-based microfacet models to include a multiple scattering component, which significantly improves accuracy of predictions of the model. We suggest to incorporate multiple scattering whenever possible, either by making use of the unbiased stochastic evaluation introduced by Heitz, or one of the approximations presented later, for example by [Kulla and Conty (2017)](#KullaConty2017) or [Turquin (2019)](#Turquin2019). + +### Complete Model + The BRDFs and mixing operators used in the metallic-roughness material are summarized in the following image. ![](figures/pbr.png) The glTF spec is designed to allow applications to choose different lighting implementations based on their requirements. Some implementations may focus on an accurate simulation of light transport while others may choose to deliver real-time performance. Therefore, any implementation that adheres to the rules for mixing BRDFs is conformant to the glTF spec. -In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The specification will provide a mathematical model that allows implementations to achieve an exact result in an unbiased renderer. Note that unbiased renderers may still decide to deviate from the specification to achieve better visual quality. +In a physically-accurate light simulation, the BRDFs have to follow some basic principles: the BRDF has to be positive, reciprocal and energy conserving. This ensures that the visual output of the simulation is independent of the underlying rendering algorithm, as long as it is unbiased. The unbiased light simulation with physically realistic BRDFs will be the ground-truth for approximations in real-time renderers that are often biased, but still give visually pleasing results. Usually, these renderers take shortcuts to solve the rendering equation, like the split-sum approximation for image based lighting, or simplify the math to save instructions and reduce register pressure. However, there are many ways to achieve good approximations, depending on the platform (mobile or web applications, desktop applications on low or high-end hardware, VR) different constraints have to be taken into account. @@ -3935,7 +3956,7 @@ The unbiased light simulation with physically realistic BRDFs will be the ground *This section is non-normative.* -An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. +An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. In order to achieve high performance in real-time applications, this implementation takes some short-cuts and uses non-physical simplifications that break energy-conservation and reciprocity. As previously defined @@ -3993,6 +4014,20 @@ Implementation of diffuse from [Lambert's Photometria](https://archive.org/detai ![](figures/lightingDiff.PNG) +## References + +* [Burley, B. (2012): Physically-Based Shading at Disney.](https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf) +* [Cook, R. L., and K. E. Torrance (1982): A Reflectance Model for Computer Graphics](https://graphics.pixar.com/library/ReflectanceModel/paper.pdf) +* [Heitz, E. (2014): Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf) +* [Heitz, E., J. Hanika, E. d'Eon, and C. Dachsbacher (2016): Multiple-Scattering Microfacet BSDFs with the Smith Model](https://eheitzresearch.wordpress.com/240-2/) +* [Kulla C., and A. Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) +* [Pharr, M., W. Jakob, and G. Humphreys (2016): Physically Based Rendering: From Theory To Implementation, 3rd edition, chapter 8.2.](http://www.pbr-book.org/) +* Smith, B. (1967): Geometrical shadowing of a random rough surface +* [Torrance, K. E., E. M. Sparrow (1967): Theory for Off-Specular Reflection From Roughened Surfaces.](http://www.graphics.cornell.edu/~westin/pubs/TorranceSparrowJOSA1967.pdf) +* Trowbridge, T., and K. P. Reitz (1975): Average irregularity representation of a rough surface for ray reflection. Journal of the Optical Society of America 57 (9), 1105–14. +* [Turquin E. (2019): Practical multiple scattering compensation for microfacet models](https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf) +* [Walter, B., S. Marschner, H. Li, and K. Torrance (2007): Microfacet models for refraction through rough surfaces.](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html) + # Appendix C: Spline Interpolation Animations in glTF support spline interpolation with a cubic spline. From f513c9edeb423fdf1bce8f2ce7be97e490981f6f Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Tue, 18 Aug 2020 15:01:57 +0200 Subject: [PATCH 11/15] Refactor implementation section. --- specification/2.0/README.md | 174 ++++++++++++++++----- specification/2.0/figures/lightingD.PNG | Bin 10938 -> 0 bytes specification/2.0/figures/lightingDiff.PNG | Bin 8426 -> 0 bytes specification/2.0/figures/lightingF.PNG | Bin 8441 -> 0 bytes specification/2.0/figures/lightingG.PNG | Bin 17866 -> 0 bytes specification/2.0/figures/lightingSum.PNG | Bin 43739 -> 0 bytes specification/2.0/figures/pbr.dot | 7 +- specification/2.0/figures/pbr.png | Bin 20615 -> 19817 bytes 8 files changed, 133 insertions(+), 48 deletions(-) delete mode 100644 specification/2.0/figures/lightingD.PNG delete mode 100644 specification/2.0/figures/lightingDiff.PNG delete mode 100644 specification/2.0/figures/lightingF.PNG delete mode 100644 specification/2.0/figures/lightingG.PNG delete mode 100644 specification/2.0/figures/lightingSum.PNG diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 18fc56e8f7..12a0dca761 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3912,8 +3912,8 @@ Metallic surfaces reflect back most of the illumination, only a small portion of metal_brdf = conductor_fresnel( f0 = baseColor, - f90 = 1, - bsdf = specular_brdf(roughness^2)) + bsdf = specular_brdf( + α = roughness^2)) ``` ### Dielectrics @@ -3925,9 +3925,11 @@ As a result, dielectric materials are modeled as a Fresnel-weighted combination ``` dielectric_brdf = fresnel_mix( - base = diffuse_brdf(baseColor), - layer = specular_brdf(roughness^2), - ior = 1.5) + ior = 1.5, + base = diffuse_brdf( + color = baseColor), + layer = specular_brdf( + α = roughness^2)) ``` ### Microfacet Surfaces @@ -3958,73 +3960,159 @@ The unbiased light simulation with physically realistic BRDFs will be the ground An implementation sample is available at https://github.com/KhronosGroup/glTF-Sample-Viewer/ and provides an example of a WebGL implementation of a standard BRDF based on the glTF material parameters. In order to achieve high performance in real-time applications, this implementation takes some short-cuts and uses non-physical simplifications that break energy-conservation and reciprocity. -As previously defined +We use the following notation: +* *V* is the normalized vector from the shading location to the eye +* *L* is the normalized vector from the shading location to the light +* *N* is the surface normal in the same space as the above values +* *H* is the half vector, where *H* = normalize(*L*+*V*) -`const dielectricSpecular = rgb(0.04, 0.04, 0.04)` -
-`const black = rgb(0, 0, 0)` +### Specular BRDF -*cdiff* = `lerp(baseColor.rgb * (1 - dielectricSpecular.r), black, metallic)` -
-*F0* = `lerp(dieletricSpecular, baseColor.rgb, metallic)` -
-*α* = `roughness ^ 2` +The specular reflection `specular_brdf(α)` is a microfacet BRDF -Additionally, -*V* is the normalized vector from the shading location to the eye -*L* is the normalized vector from the shading location to the light -*N* is the surface normal in the same space as the above values -*H* is the half vector, where *H* = normalize(*L*+*V*) + -The core lighting equation the sample uses is the Schlick BRDF model from [An Inexpensive BRDF Model for Physically-based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) +with the Trowbridge-Reitz/GGX microfacet distribution -![](figures/lightingSum.PNG) + -Below are common implementations for the various terms found in the lighting equation. +and the separable form of the Smith joint masking-shadowing function -### Surface Reflection Ratio (F) +, -**Fresnel Schlick** +where χ+(*x*) denotes the Heaviside function: 1 if *x* > 0 and 0 if *x* ≤ 0. See [Heitz (2014)](#Heitz2014) for a derivation of the formulas. -Simplified implementation of Fresnel from [An Inexpensive BRDF Model for Physically based Rendering](https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf) by Christophe Schlick. +Introducing the visibility function -![](figures/lightingF.PNG) + -### Geometric Occlusion (G) +simplifies the original microfacet BRDF to -**Smith Joint GGX** + -[Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf) by Eric Heitz. +with -![](figures/lightingG.PNG) +. -### Microfacet Distribution (D) +Thus we have the function -**Trowbridge-Reitz** +``` +function specular_brdf(α) { + return V * D +} +``` + +### Diffuse BRDF + +The diffuse reflection `diffuse_brdf(color)` is a Lambertian BRDF + + + +multiplied with the `color`. + +``` +function diffuse_brdf(color) { + return (1/pi) * color +} +``` + +### Fresnel + +An inexpensive approximation for the Fresnel term that can be used for conductors and dielectrics was developed by [Schlick (1994)](#Schlick1994): + + + +The conductor Fresnel `conductor_fresnel(f0, bsdf)` applies a view-dependent tint to a BSDF: + +``` +function conductor_fresnel(f0, bsdf) { + return bsdf * (f0 + (1 - f0) * (1 - abs(VdotH))^5) +} +``` + +For the dielectric BRDF a diffuse component `base` and a specular component `layer` are combined via `fresnel_mix(ior, base, layer)`. The `f0` color is now derived from the index of refraction `ior`. + +``` +function fresnel_mix(ior, base, layer) { + f0 = ((1-ior)/(1+ior))^2 + fr = f0 + (1 - f0)*(1 - abs(VdotH))^5 + return mix(base, layer, fr) +} +``` + +### Metal BRDF and Dielectric BRDF + +Applying the functions we arrive at the metal BRDF and dielectric BRDF: + +``` +metal_brdf = specular_brdf(roughness^2) * (baseColor.rgb + (1 - baseColor.rgb)) * (1 - abs(VdotH))^5) +dielectric_brdf = mix(diffuse_brdf(baseColor.rgb), specular_brdf(roughness^2), 0.04 + (1 - 0.04) * (1 - abs(VdotH))^5) +``` + +These are mixed according to the metalness: + +``` +material = mix(dielectric_brdf, metal_brdf, metallic) +``` + +Taking advantage of the fact that `roughness` is shared between metal and dielectric and that the Schlick Fresnel is used, we can simplify the mix and arrive at the final BRDF for the material: + +``` +const dielectricSpecular = 0.04 +const black = 0 + +c_diff = lerp(baseColor.rgb * (1 - dielectricSpecular), black, metallic) +f0 = lerp(0.04, baseColor.rgb, metallic) +α = roughness^2 + +F = (f0 + (1 - f0) * (1 - abs(VdotH))^5 + +f_diffuse = (1 - F) * (1 / π) * c_diff +f_specular = F * D(α) * G / (4 * abs(VdotN) * abs(LdotN)) + +material = f_diffuse + f_specular +``` + +### Discussion + +#### Masking-Shadowing Term and Multiple Scattering + +The model for specular reflection can be improved in several ways. [Heitz (2014)](#Heitz2014) notes that a more accurate form of the masking-shadowing function takes the correlation between masking and shadowing due to the height of the microsurface into account. This correlation is accounted for in the height-correlated masking and shadowing function. Another improvement in accuracy can be achieved by modeling multiple scattering, see Section [Microfacet Surfaces](#microfacet-surfaces). + +#### Schlick's Fresnel Approximation + +Although Schlick's Fresnel is a good approximation for a wide range of metallic and dielectric materials, there are a couple of reasons to use a more sophisticated solution for the Fresnel term. + +Metals often exhibit a "dip" in reflectance near grazing angles which is not present in the Schlick Fresnel. [Lazányi and Szirmay-Kalos (2005)](#LazanyiSzirmayKalos2005) extend the Schlick Fresnel with an error term to account for it. [Hoffman (2019)](#Hoffman2019) improves the parameterization of this term by introducing an artist-friendly "f82" color, the color at an angle of about 82°. An additional color parameter for metals was also introduced by [Gulbrandsen (2014)](#Gulbrandsen2014). Gulbrandson calls it "edge tint" and uses it in the full Fresnel equations instead of Schlick's approximation. Even though the full Fresnel equations should give a more accurate result, Hoffman shows that it is worse than Schlick's approximation in the context of RGB renderers. As we target RGB renderers and do not provide an additional color parameter for metals in glTF, we suggest to use the original Schlick Fresnel for metals. -Implementation of microfacet distrubtion from [Average Irregularity Representation of a Roughened Surface for Ray Reflection](https://www.osapublishing.org/josa/abstract.cfm?uri=josa-65-5-531) by T. S. Trowbridge, and K. P. Reitz +The index of refraction of most dielectrics is 1.5. For that reason the dielectric Fresnel term uses a fixed `f0 = 0.04`. The Schlick Fresnel approximates the full Fresnel equations well for an index of refraction in the range [1.2, 2.2]. The main reason for a material to fall outside this range is transparency and nested objects. If a transparent object overlaps another transparent object and both have the same (or similar) index of refraction, the resulting ratio at the boundary is 1 (or close to 1). According to the full Fresnel equations, there is no (or almost no) reflection in this case. The reflection intensity computed from the Schlick Fresnel approximation will be too high. Implementations that care about accuracy in case of nested dielectrics are encouraged to use the full Fresnel equations for dielectrics. For metals Schlick's approximation is still a good choice. -![](figures/lightingD.PNG) +#### Coupling Diffuse and Specular Reflection -### Diffuse Term (diffuse) +While the coupling of diffuse and specular components in `fresnel_mix` as proposed in this section is simple and cheap to compute, it is not very accurate and breaks a fundamental property that a physically-based BRDF must fulfill: energy conservation. Energy conservation means that a BRDF must not reflect more light than it receives. Several fixes have been proposed, each with its own trade-offs regarding performance and quality. -**Lambert** +[Burley (2012)](#Burley2012) notes that a common solution found in many models calculates the diffuse Fresnel factor by evaluating the Fresnel term twice with view and light direction instead of the half vector: `(1-F(NdotL)) * (1-F(NdotV))`. While this is energy-conserving, he notes that this weighting results in significant darkening at grazing angles, an effect they couldn't observe in their measurements. They propose some changes to the diffuse BRDF to make it better predict the measurements, but even the fixed version is still not energy conserving mathematically. -Implementation of diffuse from [Lambert's Photometria](https://archive.org/details/lambertsphotome00lambgoog) by Johann Heinrich Lambert +More recently, [Jakob et al. (2014)](#Jakob2014) developed a generic framework for computing BSDFs of layered materials, including multiple scattering within layers. Amongst much more complicated scenarios it also solves the special case of coupling diffuse and specular components, but it is too heavy for textured materials, even in offline rendering. -![](figures/lightingDiff.PNG) +[Kulla and Conty (2017)](#KullaConty2017) found a solution tailored to the special case of coupling diffuse and specular components which is easy to compute. It requires the directional albedo of the Fresnel-weighted specular BRDF to be precomputed and tabulated, but they found that the function is smooth and a low-resolution 3D texture (16³ pixels) is sufficient. Their coupled diffuse-specular model is not only energy-*con*serving, but also energy-*pre*serving, meaning that if neither the specular nor the diffuse component absorb any energy, all energy is reflected. ## References * [Burley, B. (2012): Physically-Based Shading at Disney.](https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf) -* [Cook, R. L., and K. E. Torrance (1982): A Reflectance Model for Computer Graphics](https://graphics.pixar.com/library/ReflectanceModel/paper.pdf) +* [Cook, R. L., and K. E. Torrance (1982): A Reflectance Model for Computer Graphics. ACM Transactions on Graphics 1 (1), 7-24.](https://graphics.pixar.com/library/ReflectanceModel/paper.pdf) +* [Gulbrandsen, O. (2014): Artist Friendly Metallic Fresnel](http://jcgt.org/published/0003/04/03/paper-lowres.pdf) * [Heitz, E. (2014): Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs](http://jcgt.org/published/0003/02/03/paper.pdf) * [Heitz, E., J. Hanika, E. d'Eon, and C. Dachsbacher (2016): Multiple-Scattering Microfacet BSDFs with the Smith Model](https://eheitzresearch.wordpress.com/240-2/) -* [Kulla C., and A. Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) +* [Naty Hoffman (2019): Fresnel Equations Considered Harmful](http://renderwonk.com/publications/mam2019/) +* [Jakob, W., E. d'Eon, O. Jakob, S. Marschner (2014): A Comprehensive Framework for Rendering Layered Materials](https://research.cs.cornell.edu/layered-sg14/) +* [Kulla, C., and A. Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) +* [Lazanyi, I. and L. Szirmay-Kalos (2005): Fresnel term approximations for metals](http://wscg.zcu.cz/WSCG2005/Papers_2005/Short/H29-full.pdf) * [Pharr, M., W. Jakob, and G. Humphreys (2016): Physically Based Rendering: From Theory To Implementation, 3rd edition, chapter 8.2.](http://www.pbr-book.org/) -* Smith, B. (1967): Geometrical shadowing of a random rough surface -* [Torrance, K. E., E. M. Sparrow (1967): Theory for Off-Specular Reflection From Roughened Surfaces.](http://www.graphics.cornell.edu/~westin/pubs/TorranceSparrowJOSA1967.pdf) -* Trowbridge, T., and K. P. Reitz (1975): Average irregularity representation of a rough surface for ray reflection. Journal of the Optical Society of America 57 (9), 1105–14. +* [Schlick, C. (1994): An Inexpensive BRDF Model for Physically-based Rendering. Computer Graphics Forum 13, 233-246.](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.50.2297&rep=rep1&type=pdf) +* Smith, B. (1967): Geometrical shadowing of a random rough surface. IEEE Transactions on Antennas and Propagation 15 (5), 668-671. +* [Torrance, K. E., E. M. Sparrow (1967): Theory for Off-Specular Reflection From Roughened Surfaces. Journal of the Optical Society of America 57 (9), 1105-1114.](http://www.graphics.cornell.edu/~westin/pubs/TorranceSparrowJOSA1967.pdf) +* Trowbridge, T., and K. P. Reitz (1975): Average irregularity representation of a rough surface for ray reflection. Journal of the Optical Society of America 65 (5), 531-536. * [Turquin E. (2019): Practical multiple scattering compensation for microfacet models](https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf) * [Walter, B., S. Marschner, H. Li, and K. Torrance (2007): Microfacet models for refraction through rough surfaces.](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html) diff --git a/specification/2.0/figures/lightingD.PNG b/specification/2.0/figures/lightingD.PNG deleted file mode 100644 index cce55fb5e4a250b18174206cddb47981c63740fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10938 zcmcI~WmJ{X*C!w#(%lUrB_$#y-6bH>-5}D^EhR`;gmfuLgLF3%0wN_1(v2Vu@4oMs zS^s%w&4*cQTvx%%z0W<*K70S_@LF9>9tV>W6A1|kM^QmW6A1}98orOlK!<uCU$I z+Hhr&m1>ODdD3atc(3o!xUTU!z0{)Xcd@@WYT$|Z-bozADb9(e>-(<{tJk$`o2qh8f&<-%TswZ^LN46Sf}p(+qFwW<&x60kc7}l zuU$HitFtv55j;ABK9sl62;5Dxg8e6aa?Cqp_^-05j%=Ews{ky##=Y~w=fyT!E7PZAwiA;l(`S?ni>D*) z-&staJifz|ru9>aDeYTE!#$g5*=qh>MlK=m%n_uVXmRJn3srf_)=~$-;APxo?XwwW zpM;$u*Yr1GIu$`D%q+^-X9n~89BDu5kU##c%8TvM-d1+ZEsu^iRAOMM4^|L%%GtD7 zh})~lh<=VP=|A8=?cC{YgLGZ6fw$I&H=G>XcSX`#P<(=#6iLIHqDX;iuB!J`wOrES z{#|T4B>u^Ie03t-cV9UL*zT@j3d$fqfABf)OJRQFCkCmYVMA$0Q)yciZMLYJZ|0}N z!$q>s3I!hS2-}xDYPWxJ%(rP<_wjRa^?1>-K!_E`XYJx-y_%6c8*&|ygUR9(G4yC$ zYuY!o?&KDI1C=UiFRSe;hZYG%eO-<>2L~JC?s9N1d5w)F6gPLPQR)1)+A3*yG3_7s zsxZy3Z{+C{5f2~1WumG_Mf3iFx2lfhRB3Y^d;YzqEH3s}dCQfy-i6(n%Z%hi7X0B= zZx^RNyDXP0S>M)VM?dn50~$}esS;nZC}s6`8k4@9YR&bmPR)7-No zpI>~yTz^UL-my>l&^kL#P5KQT-|EmF!?k(O&4x_Q)(lfgk#7m_1n1)wUP|rKkf?kE z^RSG;MYZieFSkh?t91gde;dt?mq<@z7KH51S;)>h>L+en3SXUn8Q;p+BjmW4Q4j3D z>uMFQ#iBCzRj1MS93vM8#o0z6wZ?|+ph&oWi+n|a!aDL*-Qepe!L^OSqlI>yTt&9_ zkwjV=v*Y?7oXx&pdrtJ{2uE!ni*hI1JgS&&BPmPCV*ZLVKi~N0S=l`GzRgv~9`5NZ z&G(;8q6Dh16)J2uOYBygezH>?ArElO2x6M?uj2Z5m-nD%6-?Tn4N{KvIKDD;QQFkx zJTtq_A@?1;^Sfv7UHWd-eXne^ouZMSMe+$_Z_um!(bgCB?j0>QyMD6y7vT4rk~xSr za=(L?zWG5&mJOc1OZvFlY{M2qwo|r)4bA^KTftC-EnCVB^*0-HB4%H!*Ys$lw#sx;w z9hY;M(J^io!nah=2+UUP3rP(|E%Cz+9GE2sv4YExo_v3ZA@VM4wIu87OLtk3(D}v( zc5Ql?4n{Ld$wiA^G-3)C?_Eh7x`+;NUE5ghX338`1`mJvn7{jh?jvDNo&01ro*-Q* zO;a`luMER$jj*v5tHicxs}0t#{$JE2&`3!vB~qnkt3^2Yy*_sYGky2l>tVBsPtl$IL0;{iv(k zOpU$|FxlZf-+iq{`RBW<_jkK0TsI@JIo4@C#n{n&Q;Ez;L7LbHc9m(~g;eT~vPJl( zbf&zYT-gp_>EPde?L+rR3}uWf_#Hb(sG^h&-8~}>B}}niY|O7ItoHd;bYp?{3sN?qyU;Lc{Hnp&);NalL*mJK_eE$?j8 zo6fY2>R`Xf#;P_0^;u=i!vvDBwJ)~|act3^=!dh#tDI_vEx*mtrJyUU!3}-D6}Tdu z&X&6IEqVVLu~M2vb~K80&>QT3zG^!f!mp8WK4PNaJ-vHLc9VKap|4P?;q$v@*r@8h zyd~#;f`p2yC-+C}3JdwYvM@X5W<@^LKVyX@S)CZjUt%ML?$2s!GxRgzXwwqABZI&x*KI07;y~XKjWcDR zY2ful6g%_No{&|>T1yOvPR#o=XN)B=?9%HM=sf(cn4^oIT#lY*yvfQL_)g*c)Q_mA z+#puB83jj8d6E2`+d9iRhg4NtxDVc5Ev}?+uq(Hq*;{?o8cCUSds}(qz59K?aIY8` zH#1w>bouVR^4JKfa=B+ndClbdPs;oGa|0pjO^d>Xn(s=3bvpD->~{sJ!u$?@*AeFD zb)Ha=9YAcD4|AM&TS$U-bH^75Ia+zE-q{$lL2jfH({ zXh9p3loO&VVHy&MV0^KNi^=XqwjqHb(r8LmitdyBI;?#1mbfr_{?n8S^llGBkG&>( zlfUTqx7a4|LTx((ydqO^#U*D#3D8DJ5`({D2_#K9_Ab`2{tg*wJYwMqX)S$aNOnhm zUZkDKX1YT!U`S@?*~v-}Qqz)pjiyeZVB#pz9rZoYkvpl$-zUlr>$bzC)!)u`D1<2X zJ`DIgUM|`hi}p8@yL#Jsn0%Um*b+N8v}0iU`6sv8o3G`Rl+GVm>L))AqLblQhAOpc zFj^{enf51N6Hq=QoM=pSCH)>MkWUoVDC523Mif=E9l`o4T!Y=Xqmd2A>-O01XTDeu zgF6RmP_qPPBSce&h|1S&j%7}%!g_&XVo<6gZcunpQe<>-zi z?P_J_Ze>aDY3FWBFR!Sot`m$)hJ-|qq$ne)<@I}K)=o?7WKnG2M!=Lj-i&}4-O|mB zwk(5D)ui{?HoreA$~5~f$V_NV4j(yk^R22XtEdS3@#Dv3(>rDQ#gVbGa!N{=jZID7!M(+0R8i~5Rjgcw zwLwhsv2brF8yg$zdwV^xG$QKS+UO~R-O*5m?4C3kMo9+;PUC!A}q2 za<;a%L0#sHvWzwDj;z_YnT3SB)s;JJ`K7Yd=>-MJU4`gW&HFj=L$&}3sKWw$+lO&eywd8w4^$6Fsj=HI-2_F@CxjW`nVj>w5{B#lCJ-l_? z`{Re4sVO}=IyyZD%H`!H{l|*MCvZRVQG?dfMn*JhX~JQ_!N{SZp_%pdlzMu4kaLxbSc zr%z>pH`kIzPqrpXBUD(H!|v9!^I~N;vfq~*h+FJ{^H5r4YvVxTImL}24tt5|FtJwSc`u2Bf=9h*7 zuOFb?x|KHn{=22ElT$>OdD~vViAZQf1m5{vt;@0(@7M5NJZDUY1w^z|tl5@05dYB#sG5O-s4VUeX-kZMAPio7Fn&3$WmXJEVr3~PEH7@V z_zJWztMp@D6Wy!0NsL@~!No#?s%q$h^zk@N115IHt_?w2nX z8$a{Z3&$MhhzK6XnlZfpj!#1q)7dGre(W=lAx`)G`*)bSBwh=2wN%02G!f72!a^)6 z0f&Y0J2EmS@dn&|mAahJ_!zjja$a7wZttrOmU}F^qDT}}Rl62DA~c>p?Py^p7+Izy zy>;tWety1$uI^;~4k0v1)`+e1*`d|Z(NWOy5nL>G+CzG3#{)k2+qZ8EXKNXB6?akq z24J52{QT5)bRzUBtzkEPJBPM+cEY9{nv0kBkBT+9vok@-yry}?e5KGd~Vy5DMQa>~mI zMn9`k@waYcMEPI*V_;>)C~Z89QZB}nZ@U?IFl0Jg|FY&Kr)I%X`5jaZV!HnQhPvm6 z8p1abXN|Opz6WOKRCPwWlRF;2#>NmF(w}f&T3sDqg@x!-N{WV&QOwMYp+cUf!*n$c z;3P%GwRz|JmC5!pR7nYc|HqV+l(2b0Wo2a%=YGN>A}$+0@2Vv6AeWbyLzhq=(hFOU zKGW9D&dIq2kZxVcz|4&LzDG{TmZ0A zr4t>FHSn-l>U^!BsOWOx89cq?!7m`N)I%32BPE5xqLQ?)AXamAb;ZifE${0q0<-EM zKn0Kz|Lz@1mHtjb&$c$VIH4?os;a7>|2aR9VU{}U@bBMI{fXQ;jg8bkO|)2~oUNlz z#AC|Jcu23g%BCE6C}Vh%RrdGy$+c{SF%yXHsV$^9H3w@J$T&D`OSfQ*I0)o?{fas7 z_ZR1z{(XK*94+>-Ot%{7b?-xFTspBg(1^@;?`8q^(D@$`d{DakStZ$Z9-Vy9`T>_o z^P5|@aWjjHaWphEl6cJ8UpxzS6f3ppiCz3VBrXqxO-M+n{_I&8>|A==+I@+Zx19LdRqFRZ9_c0j=qeeR*DPYUSqUN)(Qn z52Zg=XC+opQE~6r4xersYIm#=nb#5hV|tfRA@8S%Pb96pTn>Rwsj;lFF)fsBza5Jk z+h-j>7w9Sg6onbILS#$~4KZtM;)yON>Ds6FDOkMGT_NG&=-AlUNT>7mo-uL{tgBor zr`~LCZc6Tzj@$D8P-QaE*Uy~TN;4vbafytI3Xx$9?lPBzZhwxj!?rijzbRSIR1kT{N zxFMSPWk6swG_-i7JOoCZLe;ZyKiV(+SuTo)!pv0$^eEPjmX5$>;N--1TOE+JwEPp_ zk_R&4*)tNTO#G)$m>-qGc6S{w;bUIa)I6$on%_;ZN}Ybjo2$tND+#~)qRvWA%mvga z=ySv>c71BW%)(+0*!-#_ZN#=S`GE~cuJHQ?)%0Rw0ScZmtWm7@?{{$ro+)#hG*i((Ll|08f

VfS8&ZBIAux_Y+`1<4s0wH*1lrI<%^ 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 diff --git a/specification/2.0/figures/lightingDiff.PNG b/specification/2.0/figures/lightingDiff.PNG deleted file mode 100644 index f1fae699dbb24b7539790c2975cdc2a31e2f1709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8426 zcmcI}bySqmyDo~-jevAXH%NDP4UKe4*U$nYCEeYv(xEg+H%Lo&iIl|9+|6C1AUDUbwKG_O6z=2|aYRDS|nW0{N2xMwQmQcuFoN z%b>Zh!C3l`5KThytZAKhXTY;P=ZA}N;)hPA^dD-|`iI|TjEYlp5JdGqwDp~_)CjHS z@_08q{382%rdGhZvs4{#vBa-lUuz%lGQF&LRdCu8uyJ!c zcdSh&q8K3gKs|jrr}plFYjPcVuT=2?IsfMHX4qpwbfFs-C(`K0>sE1Wyx;F}So2uD zi)s7N6ZXcekLkGaitINs`DavviJe>_%*BLx+VRMYSIo%iFNs{t3%AKaZj z1lcT+=O?Pkq65j~d0eE)2Z}$h zzckP!?lz`$Qk>mel-q?@fm-oNz?v46PR`U2&tH1~86l2xX;4h~8ciFoeyRWcfz4MgG-VB6!&Js%Utf=U;4I0QCRvqm_l@7~+Vca* z#O!H*^XmoPmhxKm#Jb`1ze4*eGU^;KlI@**ahH^uR)hJnC91S zHfhlEL|5za@GbZ8_JUGLhzYWeDiQBd0#>h;!&MClQ#@A;RN_>tA76oe_ z&Jc7>p@6?7f$o$6P@d2Q)~;YQ2r>arKUPn% zK$(R&XB)jQ<|*VbKQeD~KG!5Vl%O&{K9d-?@i1o!aT&jSVYq28{j7L!pSNEl`$H_{ zh4Y_K0&D|4`oQjZ7m7$&NmXZB6Wx?RbePuyyVPGclE3jK-s!QD~hfkV;yR&6%> zdsr5<2eiVMmjINl;t?D-EfOL>K)$X0EU1p$~(}ozjt00Zi;clE1+7*+FLR3U14`K3<+byn+ z;E)JoTIY~NB=y#8=hc+hJ4SNK>(J>tms4muIhfxluJ`P$;rDzx;1 zDLV^o3n72l=v?#(C>z`PUvOO4OrY97PintA*ML$wyhkCpkQaC^m0Ir$zddGwC*?3l zW-Ts>)iY-E2J*&#ypmAMl{Kx#{+kkol(6MIExdL4vzs0~N7;IPdrApcBjVRXy{2N( zN(A6Xy$O8Ln|a+d!~E6TP{9;EHYAFKE#~pE}!2G z6S=WuqeC2n-%@$=;^a$$1V2RfBg;(0OongrftJ{e)gL@whWo4;lx9B7-_FHiI;lux ziMuOJ2>~_ei@Fw-D9?&)2A6euzkb^+F3u_m`ra=|_z|j@BYQKLHHU)Yu0z8RH>~67 zp?*ZrwsnbYf@U6O@-u84U3GW7VjNwel${QlETB3&(IiJevBuw)Xm&a!Z2m%QfAWht zn$PT5xM`I>EopOq^{BhE+#a8ReF4+95Km3|Ge*b-X^X%=7wRqy+C8;g<;nhnf-c`* zw3QyG!KA;)xG0o`F1|SF{AkuH=2#ERuJroHtgGsl-zhm1-L^iy_AcpNKZ6JabvR|A+Q@V9`fak6$;fRx@dP5!I=Q_}SfF|02 zmy{q0v;ShuEc|(pzim#4o;wikd)ztE0jvLsoo2EpWAPS6`rfpmz(e!?c8&sPaqw&P zZ)b4Y%~y;V{_+9D9Bw#&a3?mbbv0}pyg63n#Fxmo!u>sAVyKf&^U-7So)8+5YfhQP zH>i86qMK zKF^=z{XkS*)?K16ddcD8koCz;*g5kgD`7m(q*>Fb9d~u45}%48BqS99iuGFO(}{-K6miKJ(_&-g z=46|RJt(t(A3e7qhaD5Q`Wt;FaPE@ZV|-1J{Ilq<#e68WEFE+y`BO}-3ME&L;fY~S zESr`w^?tA$o8Iu*5O<7Z_6}XASanuV`6hhM<|@6tEDN_(t^U%2Kt^tR$f_6ClG@G4i5iHUP@fk zYvFL&S50&GzW)@)+ER@=Y}v$2;VG^;9U=84LMHl4jgd2sWTDNdl5MH`q)JI@QT7;B`~e}2q=_t8&p`M+=XA0H#M@U|AY=P^u-Ld?mD?eOrhaoO>C zAUKNa>#eP=0fYqn5U=T`WyclYV_|<-%j(4RbnwLcqK=MS!xj&hgISh&vB?6gSb>gJ zRX;!B7SH37Z{H&5az7;O?Y)OUAkIw&7FJe6G8xY`K`rPr#qUa)@li#u2UR~uL~OiU zy}_qVME+>PF30{_su+?F`D!64KPM^l?NcX(ySw}J^t76hkqQJd`Ir-^$vAC$5lp!b zyLI6s`F-eNz)C6oWTE@tUe__AaFx--2y zE~O#nDTAk=<8re!1cIZdrza&PC3Iq5q0JPANnX<2oN;k5SLd=RbM7My*Vfk7dbwby zsi~=^u8w`#2x_CFLqMmJ_0zFoYG$VQ&rF%#4|_uW3hk!c;q8L<_MC+U{SPAK%gf7m zYlxy0l$7EgSuaAa-lAh-PAx7*4qDv&Ml?}SKtaW4Ui+0V+0)ybKeeBh8|L$0uiHMQc=*y0T)Vk}c31fyXp3JSr<7J(C#48y2#To#BS73}*vU+4X|rXTLTt!+U`Nobi)RjtRN{%pBkkW68x zJSNAJRD3l(y>M`0_e|Z`c>JqIDX4{ovvV9+t;f-lytw$Y6LAjMzwP0rX7|Xn zwAYTS?W405@6tsB9{T@82>&fgV|XwJTOG+2&5en{xIA7RpD2{&_d1~feL%~}nXt8G zvCZti*@ymc5+)j#n%WQEJzs4KFOVHmU;h@Op^?1Cz{;v^i{`)KQNf5LVC#GTw$}YX`-ju2ij55eQ8WTLwBhZIaJn40yow6+ zhQ$h~jjgTi!04!S#lu?lYeK^Hi#cQKl~!*d*pi#j#k9t2Gz6N~o7>y@1}AczDkICY zol&9t^C>SOvau}wpzifJ{17ZS+wU34OgbALE&Tp>e7Bc}<_q;U_VcwN2?;m=E=eg} zs}GmFu5NC6O|CRx^Nj|qI5;?Rii)Vjgf0TvQBhHGxw%y&)s&KwlDZYzDJ<_oJ564@ z`F@FDS9h?@tvNS z2<%>`;NnVj`mjm-I$8#>(s3J%3_#_>vF|E17Z+~X%+SC9()|3qX^0jw%IN?XQS{S7 zhlYk+ZcjQ*;%;tyDvdkFzG;f-}1Iy!n%N=mKQ=>~%i-~EWYFkrSo zF|ljj`9pG8(-AN1Zy_wz<@yml6aWm=_j61PnZ^KD<|t^4C>d(TWR%!`NznE@nJmm$ zLS&fW22ZV>lOtk-@YGHICpdGT=PXt`x1jl;YvJ`F$*hmcSnK&I0KE3&ui`fQhh zfk7SP1W1ugVLpJEQ^4(_g|+qBf?d_b%1R|v%W`rxO0_;-MeR|b@TL$jAnoXG%C}tAKS+7{5x>EjH(Fg=10I9 z!y_XltLC^kIX|hCb~`p`=;+8gI#$+3OBzOrQT+V%3u~%GnOacLw`=ZTf8P`|X;M;B z^+Y5l>URauM?ev>gnd&=N@$JzuPp(gXqP1ePR+>3(EVQom zO4WyLCR~wmu$q9!+f^GUC+maR3eZ$zIl_vXn$wMx>resj+rtKazniyOT3TD%+b%mJ zgari!B}?qT>1xJz#MTwFLn*?`Qk^YIO2aNDVs%}7a0Ppq!0 zDl4OdM*R2B6<}iT;GnR$IHbP5zM5)R78daC9WmfkAkWCF8h~uUUV;7qbOKdV$`#3O zZx>luTx6i92Xf`M_VXD)T%Gm!lg3R>LM$)84qBL9{F!;G*ZDaVoY&W~GV{JDLJiyc zO|Ex^K$od_c<{4T`aiuy?Yj8{`e=Gu)BiNmI4(V%-%)gS^VIp_&KsbmjH5@eI6XkkD=vUA_p{)co z`jaHUBVxoQCrg`}<|jPh`d!=e5FfXmVPJ#>Z4ak1Ek}h%*qAX_Xb(S?>;a#cc(~qX zs;eW42p!ygh$I9v%vV(v6X344w$`P=kN%CmzJ4076B%es-1gk_^YiK^0=VMhV$(-e zMa9f|`~t{V_H?Bos>ZKJ`4|zPahDx;SK559?)@zFa*xBf$Wt?hRY^3%S){971XgPC4J@DZp!*fP7*iV(mo0jt5<^jD46tBpugEeF6??S8j>AFkNPh0f4c z?{;{*Q4~~46T!J3Ej0!8Z{~mbf)v^NX~vdDK)^>yEqKffn69N3&)CsSUh^8=*JNZe zg%eoB#APFVLg3cEu%qIdn)t)ThO>*R07DyZP_usr#*Z05;{ES7$-`bs`}zt#-pq9X zqxy<~U}|EbGoD&Djo*!yt>dnCQV8S4^Ye=fmw#LG07_3?)YO#z$h%2_j&FbTC{mGfsGoj8y6WKN$2V(^+1b$^1ik2C#Y)c>WUSwzPt#Tx3?P45#GD- zX+JM!i;s`bSBjeN2oNPCBs4{Yo$pTp>fFqIyrTocOneriprBwjm_TFD3=Pl9A{iPU zW?*E@IJq!4H-9oW?3trIJw4U7Gv8b?+kl#HcZHy8YHM$tdI4*NLCix+NSF_-DPW&! zle&3(5`NdKl9ni|$@>tl6J4w;XS4?PnTSkwy4570?- zOG`Sx+fMN2Mn2VY#k+?0c6R2=&F(|D=*rBHvYC-=L0)EhkRSjNXNmY_0M7;i@dZ#c zKR-WETqanX$05;EivZsMYCSbSA3krt1MKdrSFb?O@n5z20mylGEc;P?&b*dY+|V#v zNg%TakV%@b?~fO~be+H@&CUYOMg*E>YCZ|vfI*v2GN4}$aS#R+K!gK-=;`l|U5q{4 z+smt~O9XC+W6HN5#$6UQq`9VK-Y&$;GAdzrzmDq038;jLb|zKn(j(95e(5Ha6?azw<>U zB`du2BH{Yoz>|T#>)nScP$`)Vr?89wVN;k^Bx}xd7RY|G(v6LLC@3gN(SKpL`$tDR zHx~y#|`w0NsC3n%RW({^Lub|+QmpwN>FK=y4m&xOh0WHa1JS@r2 z4-5`|VcDhpp8m&=AKK~junGSQK)+WHu#WM3$*`-l+{Y1+>Ad%gQ`1EJnqApf+Wj(t zhc)_eDh(CLcKv1deF2fI%CpJf90m(0uj>Ge&&}=L#f@rXV{`XMrz7EQ+TXRw_a#c| z7x}0WzbuEL0;J*L;X`qIKYzjjc>yto;Q;=5;78X>p3G4|zuO$-?JUr0G&D35&UCUp zW)d`n8vTmK<)iBLv2cBHkY|B98-7&}wsKo(bO|cW^(V?!;kDWlFPq`Cn`NGynvz#m z-sbJNM(45~+X^8t5-Xir_hHl6wSe9q}vSXe;Dg6QhX0UV5uj)IyO zPVHCE+XFh<*x0Dnub7^jtFsuyDK_F@XBRU!r*3L$8Y1-NEG#SpVJ<#BU0z#zwn!Ws z=>?!3Kyipb61vy(fUf}P0iFwt41fXrb8wI@;wKOk6aZ!QDCsTQCpcDcYylNL98+(Zp5 zb7wqv{NetVAG(KSH&?lRcYOwId5+fx^5xO8B5<0~(b1;dQED2G08&q^3BpJ<_UHI` zY=Bpg*yn>ILqzP~zn9Z{caqnkJOP9r0lO$n@nIqT0zt(1;U58ru-yRVN4_83Jw4A#MeoA_t1>b& z(i-mJ3j7++7VPhhB;ZI_($vz52Yv+v2d9pE9uSf27wVA{2SJoZd@}SPF6NHQ0w-iW zmX%*r6bv?B{F+!lg_H=l7_h!2 zLI*4XMm*pwftfNHfxd59u3SnDT$C*9FVfzJ5Z7>(2REgIr?Kj-94U+ z^;5#IS!aLs3W#R1La_n+>@jR=bv3qs6S?K{-@UyroSW?R*W5(tAYp=82nT^ZAqj~E z6q*Fg5NK3D{8v|AdQMbiheRRTWu%_sfMw5v-QGwLs1U}2nM`G6%-!7`2W~EH^W#jJ z4j>V;^{x<@ArJU(90yUf`HmHs|3vA1ctLK!zb_tYy&jZ5`V@Z1=dd@Xc(zsL^SNAs z(IVz`{E!Df4TdI$hNEEYGdMDmPl>G7CZs3eI zdXT|jhm21*IF6{-S{GEjR5e$oZ05-b05e8==mFf1^W|SX;C_JT1MH|+X>t*V!g83q z2a^|NW@UBklJ}DML}l-N5u{}P&Sy&WtvPsK<20G>!Ut$bA|?lP-!KHE_S2DvYLj~2|gs9(S0=H}ko-DTo( zb>JcPJYJ!prZ!i2K#BzeQ}V=KvwR={dUaL|I^=FG%b+_Gb8}-?kNd$?EJXH^hCVng zYJ9g4;6TvxC@v)h-$OiiVnTgkVS&$O;{_rHNu1(^JlM4sAj9MKTUNmAX-c%kjll0e z1r^`Rzw2P|W7?s@`ruS@KBC0I9UT*6_FZ2c3>|1*t_5jz0NjHf0@E{@LUmibr)loK v&;L7W{m(J&|C#pw$N2SsXtL||;trGHPrXM9XSf|0l*7qOt4LK!n0)$Qlt)cH diff --git a/specification/2.0/figures/lightingF.PNG b/specification/2.0/figures/lightingF.PNG deleted file mode 100644 index 4c0fa0b00c4876cbde3c8ef98f12b9ad07973e77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8441 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%0D5Na9;w_d8y#Bu7UtV^}I*sa7O%wF@M94=hr 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 specular_brdf - color = [1, 1, 1] - roughness = <roughness>2 + α = <roughness>2 >] @@ -40,8 +39,7 @@ digraph D { metal_specular_brdf [label=< - - +
specular_brdf
color = [1, 1, 1]
roughness = <roughness>2
α = <roughness>2
>] @@ -50,7 +48,6 @@ digraph D { conductor_fresnel   bsdf f0 = <baseColor> - f90 = [1, 1, 1] >] diff --git a/specification/2.0/figures/pbr.png b/specification/2.0/figures/pbr.png index 75bd80d1c6dcc998a269965d677b50c8f79e5f54..85ff27b5ab62204ab874c3eb572470fbabc3f72f 100644 GIT binary patch literal 19817 zcmdVCbySsY_b$2+L_}#6L>ehUQV@_3SV*^YhbYqBA=0R%gp?qNba#n>h=@o_mxzF* zbe{R(@7rgey~o~Tk2A*kJ<6ko5mb?nHD9B7JuNL@@K-!n?z$$Y+YGbcZmL~ zDsJclDfUa@8k*;^(7O6p6wsP+?*_VXf1KN7(QJr1iL%jbsMy4*3nC?|&dSv%eSLl) zTVuGLKH`$NzD>Kdu5qP-!F9A0?$Quk=qXA$v!X2(WVW|%-OBqS zb(5N&UQSqni8bSvQ4^(yhX)G_%RN24{l=SalQLaIh{j~U-t?bSw6@0l@19sx-_Em24ltZ=a;`Ga$_>ZUWA*y>-y)r&<%R} z%*2o8F*x_c#W7IEhdV2?LfOlgmzS4SA3T7IyYQ@KdYIGx{lxI1bLP8u*x1j+8>-54 zb31SG*9sVP!Ig56UuI!tRTaK!WCPDEmmaI-@on7uZ@Ck1hSHz&pI)BFzxRE4+i;gV zNnzG=vDKVs-&%R4DS#Hov(d2XPnw9=_)>ys*0O=kh&6w^yLY8H=?V%*GhbtwE0lP` zdPjj+_Q#5AyUq6YHdk^tSCYbGJG&5C9OS>9<^dzt!L2hmolS5%uJsdz1>F{y_6Naq zDBEE%T%KV`L(j!*LM#mR93>55rGMAgVjd%t?KbIg;ltu}qrU!r4AkP{;_M5qu_~KO zolSaG))*+^^$(b)Bf0815`{4Lk`Es;ezoAmy>ux$HMLON^-CNp%D=3Pr}{=gQxi3u zZhn5AZp7`+k5ZKX!>;%+vA^2t>I_O#bF!;Bv_2cvco45rE#sHIu){pBDH=xeaE9)Vg#<@VmQFKm57 z9{>7vc)H(-4#ak7D6zxlpb z=%!*~h;Q@pu?{WT3m9{ex0SU-rAa<(q4mNatTKQYw9PLlKtnpSHgI$yfyj>|3^2Y; zasF*Dxx$rH?Ly5KEp0qJymP2_X*098+M0ES#lvnlt$31z2JOm6%$K)w*ijj^wL1Lx z%8p|{hxqvUJw;YUymt14S0Vh17c^fsFQ_PvF~#Ppi=?@D4b87m*1h*QCRFuC(ZbOS zTWRH-%gxFjZRX~r5hv*B>Cxewqqu&(-97qWKD%>*5F=>+7X?nF)kYY{vlQC-2tN;A@qjY$Qx^=Xu4vBi9Hgg`! z>aq5DpTnJ&MQ3_8HhG2HH*elF-(`aW;OSXc^QX+`(AB{MQr2vlVetjj&!0a-mnS_I zs7A_oExr;iH|_sQR)q(Cjn@Lp*;@`i3)gf1Ir-D7D*l1tVY894hqJEP=4ze=MdX-_ zh4OXmBAiX5@$ni5Vsuase!L+G`2DN1r{@AnyKpG#`~w4n7e`0l#f{34OjtNLT=gFD zByl;+qMwsOrB*H~DDEd$pzPa(a9AELCiB{nAWG)U2p7@cmd!m| z{O^m-CAx)N6cFSRai4#+nfI8Bi$4`;TQcQO=63ukLw-3}>CW4>2nZ^DhxRLw^8Y1N zm+QZnAbP_q5>qHx7#J`ifh2O9VN>E?sInfR$KM!Taot)TR(5zlM$OdvO;!@;A|p)l;VJWu)Q48R%S!@fUR+c2YFT-CZ@w1i z3kEnvB{dl#%U{TZVkj!pXUITO^9o z$VNssvg?(MP^!}4VMxGhr{58M9+%!pdu;vgb>E*);C5Mhfco$?iPzz9rTVSk>B-)3 z^GVQ)>vuAh_Z66+{1#TM<;xCo^t z`pd*V{rFL0#)C8sNGVv?bvrL~|L(r&s@=SQ36 zQv0obxprLe!B~~^N4MeqLHeXPA=f{NB@T1%?Ytkzg9X|)|o#4!q3X&d6>>mg^{=`A!(b9f6t%`jSCHE z&wU!2DPawDmGt7HRF|vNp1yS9J2?}6;{I;57{?ErolQWPVGg)mYgXvF73KWyVu^PbF`W_vIW0b<3}z&orS0rm`M0-$3vHvo{ZbK;_a>0uT|hjz*-a}Di8-H8WwlF zq`GUrJ}s{AHsK=Ry;m|s2X_^O2iM0%F6_=#WjFOQE{^m$r64gZOzyu|&&SI4q3IQ# zPv$7oH0(}#eg5+0V~xYydM9)GV=7{(PM^7xvO@b8oo$_TJ~>H@GjYCh>kXJz4o z=GO~y+qJfjRr4el-5aR#o5$iz*T*?~iDeTE8$C_B;%^B!|0dkr+_c~PDf{nkw8xoa z9o_KR7`gi#(+K!hWX3kHMyTnZP)Djc=2RG1CRb~pn_x0nU@KK@GaUchBSr)GSzJ;Q zbG7-@x3Cpz2`+Mo=xMev=M9A$m^K~dqP6@Dm1~7c*{-ja)~mWJl~{YXm~|qh;r@dr zY(u&&Bt1N8hh_i~p3jOH!a$SQiI_LV+#YT!O(f41w5`qR9pmq*GuvoDe}t9W*zDqb z`{oVm*#&}6ffq?C@L3De+-EQTnQAs#=90n0ynx@Pt}K%6LXIZIR$yWbkaZU(VY4(i z*+P59Z&wwMm(;$tkt_AepZdGkU=z#18@6Qw`}s$;9nJIm3{b|o+}Di@C2^D6BgimO z?-Y_U9d3}yE)NxAqL^aQ4&j~Vq33zx3Lo(64-@ApsbrRA$ZfCA$8k?M8KXIeyQv#Fd=a+QQX` zqxVmG7oD}sE%3ex%v~P$JzQyMO%4q;y$>tue~3p@v=D7OrKJGiXGdeSXUvK3p-+3} zfJNpMnnZ4*&PCG3=9cKmo|*8`daG`TBpRJ1CvhWoXmNDm8-q$7ff%r-9wiG)>Mr!M ze*7M@%Rjw6BNSO*1_xsobHlG)Zn7CHcr-KxF8eGlZ$pCQP8Nwpa~n@KcmO0y6!ze0 zI$XV5*n080xCw{4^2o@@Y}I0a4kijP5$s|Vs}@@I&F`By`wkN^jPmAlUEjXl_wu@nCGOvCK{8zL%kh0mKti^7SdtLy&q%qnenLXRg^2cZ z;)LJ7f2S?-+aAdRzh2*8NcN#!uJs1`ld$1Zl$guP%G$6h zGczTsCIGpHt|+DoY3Oq{e(O&ckXRhjvpa7uH1kSN%(M;1A@#N)W2D%LfPeqOQotpS z-xX=0pMxNrp4(4El{+mcvFq2UEZg6PcpS7eaBwKCVZSr+V#NAtLf4lsZS&*f`hd!i zhUG`8S;(*}FE6jpr(epH8FA6kGsB)nNSx{EEmsv)RcQ_i(q^{xNiCy<0dive_NEgh z!obA7e9y&&&$f2{>gDVFmt&cgVUs65P*L#*oKfBO&6>Z}njiY;w*>_X{3eRG(;8ET z4ct=iM-!^vj;J%=jMuYm3C6ol>`NYb&JD`D6_tecg!|l!z2h~%$bf)zNXl;wAs80Q zde7jNn*HGZeQek!+-9FH3sB-)kCaJK9#oF4{2ne&pH*>VnG1F8vl7QJhP-6kdiaFh zppLY-`9ugcUD`n{nZRLS|4ndV`si;@$9Xb+|F2&awif%D&ACZbe@YqfjAYA`?Nkx& zbNQWkdvA6!LuCD^bzsne4?O$SSCrTx=n z&3os4_q&W{Ut1Nm3~Cv@0Gb0^GWfE10*C7E6)7|iux6^y^9l;uzGq09aFGMVtHhUf zf+9+maK~m8YkEsRrpW4QS65g2${8Z2dj0w}3I#=_<>D~ou?{#tWM~~*l zoqD98)3fHkJ~}og>1B^5)ooE=Cw=L`6eiOM4|%3fp7V;MqhsJ%H*fD95blAI!L^&& z=gAt|dE;(zreQIeuAW}IV|RBqMmKLRzhT%IJfvlG3O71f!R=P79{cU_OT2uAy;7 zO-;?dgUW6C<0VcsG$;5}LZtCKVW0hk#Bq*rH=sF0`42w9)47NK*-RjIL?|dI=njB! zeXC#Dis~gj(1`hixNm#kyReXo4-O7~?&%>o2+o44Z3;b_cC900)A5ep5yYtbVs-+T z)ldPUlpGo(u{BLLQ-BM&lLm+=?J{%Ok3HhD8~M;YAu-r=v?;%#6^>x!ujyjx!+0c? zp^ySnYUbnhRG{I5pxZS`CQtq-FVtCEEKM)3s3-+x0W}SIr;V++A)w{i1-I8<0K7hf zk5TS-+xcSV4~9ea=CN3%V8Z>RcxNIIQl&y77X}c9%uGrtp>WAhsIIC?082;uXtm+5 zQp3?^SE87oDDvQ-P>SK4?%UY&5gZgl!9#8i39xlo&)F|*#cjX3lPmEfSWE!og-g0k z`P>1v7Je79kmjYdY#&N*3gqk$h*79zTb?4+9zTg-^E`(0jnDO5B5cn+T&*WS*`FTo z&ZVCoF{k;R><2avy__}D)uliZE~GWmt5;2TS0{dym|z08S&9FG#kLe$qn8tKHUyBD zBC$R{Uwi!JlB#f5PY;5XOZ-lKpHuMR0+*{Bf+np77~L)i_{Cmr8-k(DysuhWgR+G3b)RY}>`cR(jle+ljgv=rTKg z_r68&ar5c%8gf7_xH`rt?GCL-48kgl=Tk ze1MKa9Pb(r)?K&NHnT{PV2BN31oQ8#j3E!Q0Jep3`N;QTBQf~c)8<7*(sRgZv;n$9 zm$I`u5h3bxU<|dUW_w8QnEITs=N60WpC2to78!|A@$tchde!GpOv-6r4Lvexxsz_t zU#1iwv}-=*=eL`D4v=^zoUQ0Xg=Ig|U}zkQ9sVgN7j(SAQU8bMftD6?TLLe$f20lE z!`b_hT=4f-cfSy2W+K84qM>W}P-IXKS2%4i5S5zx0s_Q(wBllpQmWc`&!V$LPXA1K zkEkRt|Jaww{ek~;ig6Bqf^=q(a*(u$L^ps((sEe!=yZdL&%pRq2KA#*47WkcOfh9 zL99TGVWYGgJ^AqA@nn2vkj&`^v1%iOA7iUB-Rf@8RA06{(1*xn7E02E3qlNh=F~E9 zxsv9yqXRhV0`TboGFw zUsUu7?mXOOc?giXssiL1G{*8^K3P%oiD&Vh1(tp2DoT8h54h0Tc-b>c_AAmEcc9T` zH*6r^o$?cVoeWtfgvA2xGxN>f!IkKNfd|!SOUNzAEi~=TUIIcWH9tQsUE({r)1^tfMUT0`0&!h?rnpzb+3@&w~kh3k}Cn1Dj@*v95O z3XzkLOa=k;Mz&#wX}I+_#nR3z_A)m$FHj%ywTeG2r2D-D;y@QUs03LdCT-@AUv-8& z(En-~`S3vz(BpjdgzI(N`W61m z*Lcv&QK6X>XIGac8w*TL2p}U`Mn);<9X|1H{7s=?{qA`#_nE}nuVlMV1G(zlJ_pVX zrzeLpN=iept>3qs*wW+5!5)Qk6W@%^YFmfOGuOr0+y>Mj)F`wn^esfH*r4hu`*VWee>E?ohZ z47%A?ApADqkAIn1>928b;5FFKNHlDIVFTh_b?L>O$q#S`aDdR+0eQ~GKsw1_mi6n#h?>k);MNY8Gfeg@;cKOcRon-bY1sW?2!NEP9(bE{~3ms_5t} zRuz_&sX6$t$J||&sk)-P5EDw=3cRj8z~z~f!?g~`C9o1QP8X9D@+x8NzNQGOZ+mXi z^e_^&XFf{vzy|$ffu!IcN5U)UJfxa8YIFO(y{`{ zhDBnb-2gg!_Aio>Y^$xvqY(+#_~+;7)S>!dpX=AJN56W-SX2zcvY}zxo;P&C+D+b& zOGp6wKYRJ;U~6%9zjSP+WNc;cXRI>mG6yRwQP=M8-c}o*+v#q&jZhTnfEmAZmHord z&e-1aN6JXu3xyv4zxX{i+opYs!qyC0`vGoyhcR9qXpNa}gTV1m>3|M0Z)ew=&f|5W z{D1QTOx|Cs6(v*_*^a9jA05SoM)1cEmLk0}^RSvf_5y9_vj0dS_=rj(*(aF3u}+jTw^Q; z`raGu!2PvA(%kPaiYuArPx4+!b!(f4t|%)fC!(uYVpOl%Zc0=jRmuF}!!TJ5DXE|u zpZ}*4lGSmYWwADzgKhBEtvR9QQu|3(Z>2QhFgWEj68}(8?N@6T=s7tF{0{ol&lpB` zx`jGhHNrrpa!Hv}6ka=jxM8I5CJyxVC69aQ3nepXSzIWh?HrO7T_u3kc-`@D3%=QYbx)h=^!^SetffaRXa!QJ8h`mK%rJOoRGfDwHdzyB`6nK-E8T!?w zrKPCk6QP`+Ft=P)$;ovG6r~cZo3MS}! zLs7%m->)^F8j^Dv`vWQ|aAENctNKfhv$zo6Zc2nDPKb0}^-UQW;`%wiyoRH1e65=b(mze}VFO-`qv5gt|VD zn5q@|tZ((bk4e3p_may-#RlxRsomBlsZRfjojyalph%G&Z5bo7UKv~5f_uB!zg>SN zJu=;18q}_HW}Wmq^(kzX)vliOWJ5XEZS+?fj*_q*r)g~N%|&7gOeC{X$vPC~2sBwZ z4!l>Lb%Y)a7!vqDbhRIc-Yw%lM$J;bP|6_z-Zu8u+G|d=oc^%RAqcOw6<}j#H}^K? z+UFIM`7s1i-_-7KLaYn<4tqG>s+Z}>=G0Ab3pX^VbAGCn)0*@sEzGk29R})TJw$BU z?{wGCp_^~`F{QzJ*08p0?2{QW$q`4AWcg~3vB=oWj(1ROjaSEOYoKYd-}*5# zDz=e3&AWE{F(FuH#*9P=M7E-8QjiSN1BElAf066)cUn}=+A4ngL?7^Tp#S(QZ_szc^03Q4m6Kz zQnv-*RtKKH0<$As9uqFZmZY-I;gQNN=YifS8L^&q`e$1RE^JImp#&N(Oe7qL4X`wn zYHYud*K>arcmzB}(Z#yEiIvypyB3@3XXVy5sY0c_KifOuKGpjT}> z$P&ZCh(-6>?n6eKzd((>Fg4;#`3OkiMnz?%$E}Xj;q|Z8|FN6*q(JK?TVu3z@o+>JwEi=9-{9c3ocbM2`b(mt%bge1zP{$W)abe02M(wA z8xVJ9>(ecXLN0j%QdirlhbdzrklyFz5la)3aT*pp)K(4ZG*5{(Y*`O3LNr z?qKK^%vu7@!-ZqmcS~PPQDW-v@84)6QAP>)FuSw(ei5KX05?5uEa-%pb#)W~XoQD~ z4DwwBeuh8-BfpG|%E@VTnh0cQ?7e;GPC~OkfDs32oQ-jR(2PDHtrh! zlafdh;+n>ebk=G)7#JkIPu5!r>Q|rzzG*whIsNZc_4|Jp=I%7_<1s0|4lHgukOSx` z5stX8RIv*5Yl#88wt`&HMiWXKegVKbPyn<5M}fTp15Y~?&k5g+=PdC^Lq;DS1?tEQ zlnn{skdcmG=^EPM%+aNag-6bX0>z`n=wy>@++!hC!1t&IWS;ZDM8c^8@qi@(`t^(g zNS->v7CSvEM_xvJV9|j?BnSDH>0%OuG|+4XgWmmTyp{w)ZOZSo5qVeO*}LMMN)BR4 z9VdV6oxwNgz(EWM^eQaDJ@&RZC`2`!?A@@U&@*UP=MGa zdbBQ?_3oYN-ulcQEEK?=&zu+26=H<7Hh+&CwqQlirY>0NFGjKsJJs$6j&oHMi+vto zict`n>xcUZ0VRxpLHcDI(4-rHk^i11nPSIwvfS9s&TbEp%NjG!lo{=ITq-Y2Sd9) zILnl@HS}yc-%Z@6)_z;U9iKI1b5Fv-u%Vr5>F>>3t(-F98W{(e>iDtYZT67OjDZuW zS*aSc-<@zX17ZMn+sTX;^0e{Pozbhv;YeQ+jN1<^vV}e9uPXM*HZm?MYr#*=pDYgZQyLE1BFHepS&7ckU zUQyMC^mk3RWlJJ3lkA&ba+-)wnn>))P9pkd?O(p1%5m@aE@;ly9xUaT0%P5<)h7=c zEF038l3uxjSX&%uv_5+5t(%NHcHIKcM;DS9QiNP?s+maZzn{GB`1a8Z`NL3V1tv+_ zABH$~lJ!l*H+$&JwS0d2REg#J0X-NqTRbLOQcxh zAIOZnpCaB3G6QEK=qOs!9kQZAlg<0|2m(eYgB~viMIFwncv(;G{5`tVHCFn?hG184 zK7pPnS_s@8HJ~MzKJ2>c4ZTmIpc50o68pIqcQUn#4c&owkB%GIXPeyC@r6}Jk|7Y> zD1St+Js|ve-;#WEjIgrr^P4RrwX1hJZ@d|QHf@tU)JWL$*`>Ja)yCCo5D#rGl!=V? zuo9^XcYgia1_V|qP&E}571Ol~X{}I=5izyh2W|s8nKlphg|A7^a?(6;5i;b#4->kT zBbB>eVSS=$2`{6|YUGeqM67dqa;&PY9STV7yA{vkBEnS#oWB&6mPY;Q_s5=euPXr~ z>EkXN27w^Fn|40MywG5)3?y2P|r>pQ9NZRw{>0Klo!%NRxXgP`84?6p|jL;BrCv`d8i_W8fgkMZE=J zOBA`t5WT$}w_=m1*PRmW_%Jc$gzVpOc|mq4lnfOx>NKEL@AqIzy%7mVks7FTS&oW{ z$#fwn6$e$LUkHmHmjOCdQtsT`+#fX#3_yJ&T(SxLRX5}w+5`-&q4dFG6Zg@iegc+) zp!XA?|s2#7z#Ik35vdW_<_M{7~cJ1GC^dnveoY#OOaRa_D3P}%p+KquT zwv!=NX6npLtV#*agF8sQ;O!A6Nigyi48D9VK%S!(OGifs@hrd|eh!%836+KRd&Q%; zFCI*BS@{1B-dCu12ZiLUjg|{E#tYw45yQyFTn7dUa>4JhYEEnd>gQ0&5>Wo2WST-> z`uXcuGz67JX-I@xF+&h`2;$0|{S2~+!>4PHLVJ``1n8JzP-kSHs5dz@Vb9u4!9M%< zD=)xr6tE#vqD61b(N50;CEnT*5lo`De4 z@9;PfvI_FQ2^5td@T~7ciJIQ3jCzKRN1PBF6T<}};8`-`v(nU`s#J{b&?13t_k15P z5+0EDVAjG)zGL?ZIG!K5U!&+GOQ2as$h9k1u7DpX6gygt{$D z;5+e$wMB?lc)KWxY^Kbacb^m!5jc=XK;ylR0l*-~MF35I#x|+0A{74SeAfm5cE?QD za3Oe{fWiJ_!e{w)gPGZ^GlubZe~z;Dl9>BCE$I2{Kz?poP=w2gcO&f0Ghj)BkY|;d zs1AQSI5;R7xP@~L+Iwomdjq;3p8R!m3$AD4*#GU&&rBrwmd@Y}YBrLsy^l6JxDU%i z5a-^SPX4U~oU8>2OTpLcWcILaGrw0)`9>gs5*nq8V}zbJ0_pd|2GOI84>qLD=r5ij z&Tu*C%8~uoxI3Be!gBGMtd+6*9U#h75+ecVj{r7DZb5FTq&yQE8YT*WoM^C;bRMXkk9?zS;!1}jX@4zOAkf23%OE(K8 zRok`tSgQ>=F2>2H#ly8CK97!zDiI6UN+$-zlj z)UYXsFhSsn{QclvVIdyya;;!n+nDrP%K#+)rV1=(QAtUQyS}WG>+u?* zbnnfup^O?v3As~jz3PQJ8P)5}kFFWXmQl1YeRyIT{!@`6(1eH&8tLm(4xFH~ULfrTP@L|+GeRox+wF?z42C81U5~@Wg)Xlo zP4C~mU0CI_xL&>Ry@J@!lgyxlxbyS^EFcB405BK*_)~ z4%_SnsGyIj!aqC7=yelTzfP-uT<4_w`a!V7n{6zfoUDpM8RlpXxX;^Mz_p|NTW9R` z);vYQAk^;j-%m??Ure|oET)~+1AGmTwC&sAEaBth6Q>~{I==>nnU*|_eA6nezU|uC zWs7S@5984E`lh)I6Fj+uS^#l6N?8gkf;jA6R^O4Hzvqkoa8z?9f+0o)o2>}G*5T+wMB zbIS;5LR-84OkI#IJ8VC>>4UlsecL@r$!9f9wYAq!Q3(lTRdYA!r(V*Cy-YClym&@} zWM%CgKY95s!v;5X&!?SOsut1uQTEdxFsl6wmPHytw?QdQ>Bl0@5E*4j0w91JGW)z`u14SfM@0RC6Z;cPm?GNc9Bx2&3=oOOC)Apxn!ManB$Li%AC-&q>Ln7#W75 zi|q#LShXj3!{d%nm4G&b=tCPAPytu;Y-nhxq(Tb4LGQ$IIv!LI_y{B z5*>cjg3+V2z-m=?csu6gTkfydIE~OFfC~N@{54<&lyu`llSTm;v@%y$E1d_t)cCJk9*mjm zBv=^vnuQ-lcE?+j)mbc{SMB=_*l#?|2)20mLnlYaw!76J)!j1ukOo8?0DGWN;ToSr z0}b=${d*h~=z^$}CMNZq{tRe@Y=@QWVif4ZQ;?nyq~IFJ^p$Xx$n3>!@Ws$E`9gDg z?bH7~$tWrg0(J7{4BxQ?G@Tq+fxG@~QIQhd zphN(;wZOHt1zL0l(1PT=7SD$=2!pWBunLp>yr1+%-a_hz4-i^Fb2-YkV^eL$dSfxO@j zeR7FKHwALS>oD~MhTKjN+d@GeM@FCEAV2;cQX5$SEA)RSeGlW4`&aRPg3@i{x$MZG$jxyZ+$CqbV1}9a( z;T)on9PR&g*co|b1p@02hbOd|SYUATKjY7^qknx9JM{+4#8Y4cp$z^>0x&(=YLC%{ zUxig6{_sx?L#s*>29^vSL+d(k}aP=4;#UHg;0tF*7PFG1A_GYgbF*_0-jfN zdOFPzKSF3+23iPQQYJPbEU*9F^i%Kwn0CMBLjWH#J2*oqb=mF%VxR4cW{_S7eflck z3k1F)FOi-=X2(jx)>+` zL+w&z23Zcb(W3|kPgMX!@{XWgS^IoIA61T3t)-WQkdi2lvBf zyg=|!)f9n-Z&dR$Mm`WMM7Va1+wo)kd~2MU0{n>o6Dy>Z?&K&Lvg?0ro0!wSn4l2K z=aj)do2@j13C+?wym#-`t53j)<2C)IvpJ)??J=pTRJ~?bgoC5bixUo?_rlkAQA`(| zDE`sd{xctM(E;49Fz*PAHwFrNV7;Dca85IFz@P^F_BKC%_;NhEPNutc(}~}47y|_Y zo>^|*{0Ph-$d*CSG0ws~OXZLWkyL`QnksDZcI>_1f~;(8u`5B=c6MZ6zI+)Uf_gbZ zorl;@8(}uXO0USa$A+WNP&WG@dwzb%W9(N?>CHi^uYytW1c7P_O`}oN)#JW>hT@h6 zz@x$)*XOwp9GzlQNVDwq^CHyPOtdsL5#o=Y0eX@QVbO2KZ*QN_hdY%gfl&x$WaN6{ zZ7CnZ^J=Mgc{^_jU&@jE%jT0EvcT_Yn0~pkOg<|)TlUdR;J_#bO~^%9ZtN(Gp|A5N z=r^>;SROQe0Z}O_?B?d?I4~JT|_~Afox;sy>T9rYq(Uz)fs5_qj0d_S5$e3ln(gko{NUx&7qmZ~7@>J>!1(h17Xvl<#LLVLQU61j3x0 zgU;ykPiG-jL&H^9-mu%UG4ZcBF2u^Pw$IwxCH6g#IHAmsu}^2WyOO@YXO@Zxy0fi8XAWyCLO4H0Br4}9u;x|)B6}kerfhZ!3#SqDN&uPRA z^^5ZI0{R!RP}UQ5R{*GKH@KJ9_y8hL{Q_+mc+$g`?O=$+-|QOSlenIP?5x&O0MRHV z=HP#N7sScMT|t}+iw<^RX!@}DbC^%s93}^9CiqU@f+|Mx6V%wSv22l7GtU_wAn1ND zUuzB;o%1N+lfAhbK%U5Kiu2l}$j=ob#uVeCnxD{ilw#bpC5)QP__M#>aQDX;Wdwh6 zq57CgO_+pbve;jRp~1n0yCy#uw-3lR!J(9@u74j)?Sz%UVtapg`HW@p~!pP=`BB7aPaO zibsjrTAo|z8y&p~<*GVMf0gq5!D&7dSV7U;CRIv==bA?a{|jhg76ydULlSNIuiAwB z-)hrlviIIeCf1#hVWc_}seY(?Oy!@GDs-OWJbZ%yHuAjycij*j0pJohGQ4u8W`Lh7 zvw!hH0-j4G1(7NX+JL7P+=QqPqm@>CF9S_g!6kjh)sX`fy2!8;BbxxE%VVl@?QdSb zgzF3g#0btx3RWzo`z4B)}}dpo9D7Bl22cM*E}epa%oH zG3m0i042=5n~oUE^kl$Zhl#bZqTF1f>i<+Ej@mjXyDV}z;((q4dLLhY7p_#GnLo`| z0QPtrK;>~2F1h6cVEHuXzEh+h;`Zaf%;Yd@8jd_*F%_VZ5)?@oNuJwg(~1p z?FLTlVJEhZDW~`EY+^eHa;bajM3y&Q@eKwVe2Ixr@H`Qq@$TdH{)b&M#+nfrUfds0 zR}SlfaDgcRn7W>=W0a5oyqW+$Krk@l1fXI&u~5+KAQpJ-Pc!zkAQ7Wf^z<%?6N0CT zIsVm-id@%g1*THlS6A1Zw zz8B#-6uMHV-wyR^Jgg#`TF;-x3^5wSr;!=i$amd5PA6;+P%&_9=@JZOiC+w)t@GIY z`xgVHna^jA0dv<3Vq#NPYw8{zf&e@xhLRMR6jB6$5qNH|$9a5jr$8O*Ie~p`S(B0( zmxD~#T}u1{qh`ZDBbTJCn*wj{*bg#i|JsfXg=VcllkNHaw?i3iS5lS8VuoK=q^S(b zrUotleY(aeXYXWM_NeU5n|qX|F5Jo8h@0~=wq#DS>Z}yBdPOy}xX^z?*AD*dIy@(J zQxDKBdMmB8;JYZ$JHHr#=8_5R%zX-CuL|hSup}R5?2REM&Jq?+*h)A19+QUD9TV9! zVghy}Nzj6+P582QXaIApRJ{QG|deMCLnlgt%X9AM`4E zmoqUYTIBL4^+u*PacpOnyoCi5SOPMJ&vZe={_|nc>cV^sGGUI`c)B=Xtk$-xh;9qI z-r|eN6$KTxfK5S5H-#@W03LeF^YY0Si)?Y2bNjrrkj5Gf?vrmBoN^1d5~=4AmnhQE z7@ZzyA;S+~si_#-f!V%`;BI!(a}`2#S%Ie06R(Qu>Nyx44enoTLwIn&wi%6$2IJCs zAhrW5b`Pdok@?@PrNK)udo5LL*!aEP%`OGZ-^i;lzzxJgq<>^*0=OZa7yHgLE2W@N z2sQkp!Gjmk{_0ojE+KA6AnEc-DwT6s@l?H-0w=%J;sks^$Ap?H!5A+j8B^22A3s71 z3fQYTkN-2ui&$v4ww%vOpY#g~Mvh3NOiorb* z@EIV)B4i6Y&54Vh3UYH>pr@R17Mieqvyoj=q9VMCSj@nEqh0S>xO6Nj-YvK#r8}gN zZY8KvB*qT?6pGfoIq`45vKX=w3LN0F_M3x+Btx26=m=(zKZDyp5Zt|CJ<4gqtgELH zMn@lSwfq6a0L+;yRjXi^C89Y&xS5Hx`j{^Oe~jD1uefitlR3b@AxHPQ9CP?L)Nd}x z(T0VZYI2cWvgGSA2mVTXAt^2yv$xU@DyN@*)i3t>Qz6y#abPcNz1E>jC@BLRGu$`87r zDBv!T-;j%VR@g5WR^y&OfBqu~$$`kYnft+FP7pvRRd>L%LBmFV28p*VV}^I1F89J@ z42Hiw%p>3emLfvBgzj(34IAEtogxWdE1q6O^UHT89biJCB#{b2oE8VZjw2twOuaDTA4xzI9GOF|m zL8%WytRzD0S0jdxG3g4sTqX^A=D%f(R%Mek)qk@qV2(WzfWc#!QlmeDCq*{txqK_5 zu1;6G$~tKsOo6ySw-P~v69}d&Tx8@3;VMl)qx%SQBpZM~4HT`u&-P$mjBM?Npy1*g zs+QMdWo-bJ;YN&b3-U#YNeD{eOEsgDDBgoehM1E8x-OMl%gNzFuzZJ11eq5b6pdDB zdnuo?%%zVm(?1)zpV11F%OC0abFk^s|1wAN#0jU_i7Uo_bC$|wnI8_nWW{X#a#$Uh0?i;rAhh167uP%5qJif@2AEG?OiKqwwk4&ZcUE+CicFEyFe4#vb9Gr()de<*-gb z?pTH!*=GeWyU_1?$_5Tcv4ttLnK5Vn?l4*9QeBdg#d;E%Y7|I%N!X}Ix6zhi!h+r} zm?+whIP(#V&6#9#V%pK9JrVotvrQ{ArdjuPWEk&eAHVRjQ=xiZzn-^T$I=?V-3kj8 zNi^}WRp-=CrXRcIuZK(2d@{y=tu$s<*=F|;W;-^Ca)yRx&59;%Eqt3X7UdfB{{4l~ z_sQ(0rt}*dEVXaxHfh{ne4-sZY1Je-YE|ovXpek2y+jE*_$wXqM~u2@@}Eq0pwS!- z=?eD)MhSfQMDR{376wyT6BSS@Q-_2+8oSjd}*2UG@oIBCNl%B?-DUC8h)^kPbCI)gi#J+l28Rl%`ObJ|4o|tZouUcJK71;AiwSPalb+z@>ZtbNFX-Fn2 zyoo42N*|MMp7z`gdfmjwycBQnc!&ehL?kL$*Ia1%4OaeK-g!1+m+aI>uz6|E{-Ie- z^`j=e!zW^uf)=scRgv}8*y}kh9p-J#Q||KAr<0fc`~-X|UDsN(J9U$FMhjYaeRe%L zxI2{pBz=9stvHmt>UMbTvtv>{^GQcGAIiVVaQ5p@!lO1uTa>?aSSPgu6EW&HMM5nG zN`?dsy;)(hC{$nD4HU}Klo;iIoBJZ_-s^Pi05Wh^&bkZ7Q)7mYtnFq?`-?B>D-5|% z5v8AQod2v>JnSHvE+2^@bt|DOQ7I?8!@p%wU*VfYIq>rijfV1(63Ren^f5TYuUJLS zp)dz)6ASWgUX74i`*41OcwD-Ke zfbz^KTJB@G$8A?Vwi55NIqw+Ozqs|)1NBA=zEVrL88wQL!aX-sxJ@Pf sAD!p*|LSt`LiaR0aZo7F#ko5gpWi)`<`nFQ?@mL>N-3d>B#Z<8FUMl{iU0rr literal 20615 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 Date: Wed, 19 Aug 2020 11:49:29 +0200 Subject: [PATCH 12/15] Refactor clearcoat extension to look similar to Appendix B. --- .../Khronos/KHR_materials_clearcoat/README.md | 89 ++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md b/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md index 8139520468..35cd96b2ef 100644 --- a/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md +++ b/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md @@ -53,7 +53,6 @@ The PBR clearcoat materials are defined by adding the `KHR_materials_clearcoat` ### Clearcoat The following parameters are contributed by the `KHR_materials_clearcoat` extension: - | | Type | Description | Required | |----------------------------------|---------------------------------------------------------------------------------|----------------------------------------|----------------------| |**clearcoatFactor** | `number` | The clearcoat layer intensity. | No, default: `0.0` | @@ -62,34 +61,100 @@ The following parameters are contributed by the `KHR_materials_clearcoat` extens |**clearcoatRoughnessTexture** | [`textureInfo`](/specification/2.0/README.md#reference-textureInfo) | The clearcoat layer roughness texture. | No | |**clearcoatNormalTexture** | [`normalTextureInfo`](/specification/2.0/README.md#reference-normaltextureinfo) | The clearcoat normal map texture. | No | -The clearcoat BRDF is layered on top of the glTF 2.0 Metallic-Roughness material, including emission and all extensions. The `clearcoatFactor` determines the view-independent intensity of the clearcoat BRDF. If `clearcoatFactor` (in the extension) is zero, the whole clearcoat layer is disabled. Implementations of the BRDF itself can vary based on device performance and resource constraints. As in the specular term of the glTF 2.0 Metallic-Roughness material, the roughness input is squared to make it perceptually linear, and the Fresnel term uses a fixed refractive index of 1.5, corresponding to a F0 of 0.04. +If `clearcoatFactor` (in the extension) is zero, the whole clearcoat layer is disabled. The values for clearcoat layer intensity and clearcoat roughness can be defined using factors, textures, or both. If the `clearcoatTexture` or `clearcoatRoughnessTexture` is not given, respective texture components are assumed to have a value of 1.0. All clearcoat textures contain RGB components in linear space. If both factors and textures are present, the factor value acts as a linear multiplier for the corresponding texture values. +``` +clearcoat = clearcoatFactor * clearcoatTexture.r +clearcoatRoughness = clearcoatRoughnessFactor * clearcoatRoughnessTexture.g +``` + If `clearcoatNormalTexture` is not given, no normal mapping is applied to the clear coat layer, even if normal mapping is applied to the base material. Otherwise, `clearcoatNormalTexture` may be a reference to the same normal map used by the base material, or any other compatible normal map. -## Implementation Notes +The clearcoat effect is modeled via a microfacet BRDF. The BRDF is layered on top of the glTF 2.0 Metallic-Roughness material, including emission and all extensions, using a new `fresnel_coat` function: + +``` +# from glTF 2.0 Metallic-Roughness material (core) +material = mix(dielectric_brdf, metal_brdf, metallic) + +# clearcoat +clearcoat_brdf = specular_brdf( + normal = clearcoatNormal, + α = clearcoatRoughness^2) + +# layering +coated_material = + fresnel_coat( + normal = clearcoatNormal, + ior = 1.5, + weight = clearcoat, + base = material, + layer = clearcoat_brdf) +``` + +The `fresnel_coat` function adds a BRDF as a layer on top of another BSDF according to `weight` and a Fresnel term. The layer is weighted with `weight*fresnel(ior)`. The base is weighted with `1-(weight*fresnel(ior))`. `normal` is a float3 vector that affects the top layer, but not the base. + +### Implementation *This section is non-normative.* -All implementations should use the same calculations for the BRDF inputs. See [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation) for more details on the BRDF calculations. +Implementations of the BRDF or the layering operator can vary based on device performance and resource constraints. + +#### Clearcoat BRDF + +The specular BRDF for the clearcoat layer `clearcoat_brdf` is computed using the specular term from the glTF 2.0 Metallic-Roughness material, defined in [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation). Roughness and normal are taken from `clearcoatNormal` and `clearcoatRoughness`. -The clearcoat formula `f_clearcoat` is computed using the specular term from the glTF 2.0 Metallic-Roughness material, defined in [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation). Use specular F0 equal `0.04`, base color black `0.0, 0.0, 0.0`, metallic value `0.0`, and the clearcoat roughness value defined in this extension as follows: +#### Layering + +The `fresnel_coat` function is computed using the Schlick Fresnel term from the glTF 2.0 Metallic-Roughness material, defined in [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation). ``` -clearcoatRoughness = clearcoatRoughnessFactor * clearcoatRoughnessTexture.g +function fresnel_coat(normal, ior, weight, base, layer) { + f0 = ((1-ior)/(1+ior))^2 + fr = f0 + (1 - f0)*(1 - abs(NdotV))^5 // N = normal + return mix(base, layer, weight * fr) +} ``` -The following abstract code describes how the base and clearcoat layers should be blended together: - +Applying the functions we arrive at the coated material + +``` +coated_material = mix(material, clearcoat_brdf(clearcoatRughness^2), clearcoat * (0.04 + (1 - 0.04) * (1 - NdotV)^5)) +``` + +and finally, substituting and simplifying, using some symbols from [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation) and `Nc` for the clearcoat normal: + ``` -clearcoatBlendFactor = clearcoatTexture.r * clearcoatFactor -clearcoatFresnel = fresnel(0.04, NdotV) +clearcoatFresnel = 0.04 + (1 - 0.04) * (1 - abs(VdotNc))^5 +clearcoatAlpha = clearcoatRoughness^2 + +f_clearcoat = clearcoatFresnel * D(clearcoatAlpha) * G / (4 * abs(VdotNc) * abs(LdotNc)) -color = (f_emissive + f_diffuse + f_specular) * (1.0 - clearcoatBlendFactor * clearcoatFresnel) + - f_clearcoat * clearcoatBlendFactor +coated_material = (f_diffuse + f_specular) * (1 - clearcoat * clearcoatFresnel) + + f_clearcoat * clearcoat ``` +#### Emission + +The clearcoat layer is on top of emission in the layering stack. Consequently, the emission is darkened by the Fresnel term. + +``` +coated_emission = emission * (0.04 + (1 - 0.04) * (1 - NdotV)^5) +``` + +#### Discussion + +In order to make the material energy conserving with a simple layering function, we compute the microfacet Fresnel term with `NdotV` instead of `VdotH`. That means that we ignore the orientation of the microsurface. As the clearcoat roughness is usually very low the microfacets orientation is very close to the normal direction, and `NdotV ≈ NdotL`. + +The simple layering function ignores many effects that occur between clearcoat and base layer. For example: +* The clearcoat layer is assumed to be infinitely thin. There is no refraction. +* The index of refraction of clearcoat and base layer do not influence each other. The Fresnel terms are computed independently. +* There is no scattering between layers. +* There is no diffraction. + +More sophisticated layering techniques that improve the accuracy of the renderings are described in [Appendix B](/specification/2.0/README.md#appendix-b-brdf-implementation). + ## Schema - [glTF.KHR_materials_clearcoat.schema.json](schema/glTF.KHR_materials_clearcoat.schema.json) From f6e62a1a900beccb92c2bcc0d637560092016853 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Thu, 20 Aug 2020 17:22:29 +0200 Subject: [PATCH 13/15] Explain that the material model is defined in terms of a BRDF. --- specification/2.0/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 12a0dca761..3972df56a8 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3891,13 +3891,15 @@ Application-specific data. # Appendix B: BRDF Implementation -The metallic-roughness material model is a linear blend of two bidirectional scattering distribution functions (BRDF), a metallic BRDF and a dielectric BRDF, as introduced by [Burley (2012)](#Burley2012). The BRDFs share the parameters for roughness and base color. The blending factor `metallic` describes the metalness of the material. +The bidirectional reflectance distribution function (BRDF) of the metallic-roughness material is a linear interpolation of a metallic BRDF and a dielectric BRDF. The BRDFs share the parameters for roughness and base color. The blending factor `metallic` describes the metalness of the material. ``` material = mix(dielectric_brdf, metal_brdf, metallic) = (1 - metallic) * dielectric_brdf + metallic * metal_brdf ``` +Such a material model based on a linear interpolation of metallic and dielectric components was introduced by [Burley (2012)](#Burley2012) and adapted by many renderers, resulting in a wide-range of applications supporting it. + Usually, a material is either metallic or dielectric. A texture provided for `metallic` with either 1 or 0 separates metallic from dielectric regions on the mesh. There are situations in which there is no clear separation. It may happen that due to anti-alising or mip-mapping there is a portion of metal and a portion of dielectric within a texel. Futhermore, a material composed of several semi-transparent layers may be represented as a blend between several single-layered materials (layering via parameter blending). In this chapter, we will first sketch the logical structure of the material. We use an abstract notation that describes the material as a directed acyclic graph (DAG). The vertices correspond to the basic building blocks of the material model: BRDFs, mixing operators, input parameters, and constants. In the second part we will provide a sample implementation as a set of equations and source code for the BRDFs and mixing operators. In contrast to the logical structure the implementation is not normative. From b76a37883d21bbbcc3b45985b9a744917c8472a2 Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Fri, 11 Sep 2020 11:34:24 +0200 Subject: [PATCH 14/15] Add reference about BRDF. --- specification/2.0/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 3972df56a8..9c76d89fe7 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -3891,7 +3891,9 @@ Application-specific data. # Appendix B: BRDF Implementation -The bidirectional reflectance distribution function (BRDF) of the metallic-roughness material is a linear interpolation of a metallic BRDF and a dielectric BRDF. The BRDFs share the parameters for roughness and base color. The blending factor `metallic` describes the metalness of the material. +In this chapter we present the bidirectional scattering distribution function (BRDF) of the glTF 2.0 metallic-roughness material. The BRDF describes the reflective properties of the surface of a physically-based material. For a pair of directions, the BRDF returns how much light from the incoming direction is scattered from the surface in the outgoing direction. See [Pharr et al. (2018), Chapter 5.6 "Surface Reflection"](#Pharr2018), for an introduction to radiometry and the BRDF. + +The BRDF of the metallic-roughness material is a linear interpolation of a metallic BRDF and a dielectric BRDF. The BRDFs share the parameters for roughness and base color. The blending factor `metallic` describes the metalness of the material. ``` material = mix(dielectric_brdf, metal_brdf, metallic) @@ -3908,7 +3910,7 @@ In this chapter, we will first sketch the logical structure of the material. We ### Metals -Metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material ([Pharr et al. (2018)](#Pharr2018)). This effect is described by the Fresnel term `conductor_fresnel` with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. The reflection color at grazing incidence is called `f90`. It is set to 1 because the grazing angle reflectance for any material approaches pure white in the limit. The conductor Fresnel term modulates the contribution of a specular BRDF parameterized by the `roughness` parameter. +Metallic surfaces reflect back most of the illumination, only a small portion of the light is absorbed by the material ([Pharr et al. (2018), Chapter 8.2 "Specular Reflection and Transmission"](#Pharr2018)). This effect is described by the Fresnel term `conductor_fresnel` with the wavelength-dependent refractive index and extinction coefficient. To make parameterization simple, the metallic-roughness material combines the two quantities into a single, user-defined color value `baseColor` that defines the reflection color at normal incidence, also referred to as `f0`. The reflection color at grazing incidence is called `f90`. It is set to 1 because the grazing angle reflectance for any material approaches pure white in the limit. The conductor Fresnel term modulates the contribution of a specular BRDF parameterized by the `roughness` parameter. ``` metal_brdf = @@ -3920,7 +3922,7 @@ metal_brdf = ### Dielectrics -Unlike metals, dielectric materials transmit most of the incident illumination into the interior of the object and the Fresnel term is parameterized only by the refractive index ([Pharr et al. (2018)](#Pharr2018)). This makes dielectrics like glass, oil, water or air transparent. Other dielectrics, like the majority of plastic materials, are filled with particles that absorb or scatter most or all of the transmitted light, reducing the transparency and giving the surface its colorful appearance. +Unlike metals, dielectric materials transmit most of the incident illumination into the interior of the object and the Fresnel term is parameterized only by the refractive index ([Pharr et al. (2018), Chapter 8.2 "Specular Reflection and Transmission"](#Pharr2018)). This makes dielectrics like glass, oil, water or air transparent. Other dielectrics, like the majority of plastic materials, are filled with particles that absorb or scatter most or all of the transmitted light, reducing the transparency and giving the surface its colorful appearance. As a result, dielectric materials are modeled as a Fresnel-weighted combination of a specular BRDF, simulating the reflection at the surface, and a diffuse BRDF, simulating the transmitted portion of the light that is absorbed and scattered inside the object. The reflection roughness is given by the squared `roughness` of the material. The color of the diffuse BRDF comes from the `baseColor`. The amount of reflection compared to transmission is directional-dependent and as such determined by the Fresnel term. Its index of refraction is set to a fixed value of 1.5, a good compromise for the majority of opaque, dielectric materials. @@ -4110,7 +4112,7 @@ More recently, [Jakob et al. (2014)](#Jakob2014) developed a generic framework f * [Jakob, W., E. d'Eon, O. Jakob, S. Marschner (2014): A Comprehensive Framework for Rendering Layered Materials](https://research.cs.cornell.edu/layered-sg14/)
* [Kulla, C., and A. Conty (2017): Revisiting Physically Based Shading at Imageworks](https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) * [Lazanyi, I. and L. Szirmay-Kalos (2005): Fresnel term approximations for metals](http://wscg.zcu.cz/WSCG2005/Papers_2005/Short/H29-full.pdf) -* [Pharr, M., W. Jakob, and G. Humphreys (2016): Physically Based Rendering: From Theory To Implementation, 3rd edition, chapter 8.2.](http://www.pbr-book.org/) +* [Pharr, M., W. Jakob, and G. Humphreys (2016): Physically Based Rendering: From Theory To Implementation, 3rd edition. ](http://www.pbr-book.org/) * [Schlick, C. (1994): An Inexpensive BRDF Model for Physically-based Rendering. Computer Graphics Forum 13, 233-246.](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.50.2297&rep=rep1&type=pdf) * Smith, B. (1967): Geometrical shadowing of a random rough surface. IEEE Transactions on Antennas and Propagation 15 (5), 668-671. * [Torrance, K. E., E. M. Sparrow (1967): Theory for Off-Specular Reflection From Roughened Surfaces. Journal of the Optical Society of America 57 (9), 1105-1114.](http://www.graphics.cornell.edu/~westin/pubs/TorranceSparrowJOSA1967.pdf) From 796de90055086c4f53e26a4e3b00fbbd866e146e Mon Sep 17 00:00:00 2001 From: Tobias Haeussler Date: Wed, 16 Sep 2020 11:42:05 +0200 Subject: [PATCH 15/15] Describe how functions are applied to derive dielectric and metal BRDF. --- specification/2.0/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/specification/2.0/README.md b/specification/2.0/README.md index 9c76d89fe7..1f9e8d0545 100644 --- a/specification/2.0/README.md +++ b/specification/2.0/README.md @@ -4046,14 +4046,16 @@ function fresnel_mix(ior, base, layer) { ### Metal BRDF and Dielectric BRDF -Applying the functions we arrive at the metal BRDF and dielectric BRDF: +Now that we have an implementation for all the functions used in the glTF metallic-roughness material model, we are able to connect the functions according to the graph shown in section ["Complete Model"](#complete-model). By substituting the mixing functions (`fresnel_mix`, `conductor_fresnel`) for the implementation, we arrive at the following BRDFs for the metal and the dielectric component: ``` metal_brdf = specular_brdf(roughness^2) * (baseColor.rgb + (1 - baseColor.rgb)) * (1 - abs(VdotH))^5) dielectric_brdf = mix(diffuse_brdf(baseColor.rgb), specular_brdf(roughness^2), 0.04 + (1 - 0.04) * (1 - abs(VdotH))^5) ``` -These are mixed according to the metalness: +Note that the dielectric index of refraction `ior = 1.5` is now `f0 = 0.04`. + +Metal and dielectric are mixed according to the metalness: ``` material = mix(dielectric_brdf, metal_brdf, metallic)