Siggraph 2017: Physically-Based Materials: Where Are We?

The slides and course notes files of my talk “Physically-Based Materials: Where Are We?” in the open real-time rendering course at Siggraph 2017 are available here:

This talk is about current state of the art of physically based material in real time rendering and what could be done in the future.
Often people tend to say that material rendering is a solve problem, but we are very far to have solved it. And the main reason is that we even don’t know what is a true/correct model for a physically based material.

Note: I forget to mention in the slides 56-57 where I compare the anisotropic GGX with reference that I use Disney remapping for anisotropy parameter.

// Ref: (in addenda)
// Convert anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) to roughness
void ConvertAnisotropyToRoughness(float roughness, float anisotropy, out float roughnessT, out float roughnessB)
    // (0 <= anisotropy <= 1), therefore (0 <= anisoAspect <= 1)
    // The 0.9 factor limits the aspect ratio to 10:1.
    float anisoAspect = sqrt(1.0 - 0.9 * anisotropy);

    roughnessT = roughness / anisoAspect; // Distort along tangent (rougher)
    roughnessB = roughness * anisoAspect; // Straighten along bitangent (smoother)

The conclusion of my talk is that a future BRDF could be:

Layered BRDF: 2 specular BRDF + Diffuse BRDF
– All derives from the same anisotropic NDF
– Energy conserving: MultiScattering, Fresnel interfaces
– Option to switch to Airy reflectance Fresnel
– Shape-invariant “matching measure” NDF
– Multiscale Diffuse and Specular representation

Other than the two last points, I think we can approximate such BRDFs for realtime in two years (next console generation ?).
To extent a bit, here I think a good BRDF could be an anisotropic GGX diffuse lobe + two anisotropic GGX specular lobe (one for hazy and one for sharp) + one isotropic coat GGX lobe. Added to that an option to replace Fresnel term of base specular layer by Airy reflectance. Multiscattering specular/diffuse should be possible in real time with precomputed table. Approximation for Fresnel interfaces should be possible given some constrain and chosing a physical representation. Diffuse and specular roughness should be separated. Complex IOR for metal should use the artists friendly 2 color model of Framestore.
The true challenge being to be light coherent. i.e have a good approximation of the interaction of this model with area light, image based light and GI.

But what is interesting is the consequence of such a choice. With 2 parameter for diffuse roughness, 5 for specular roughness, RGB diffuse, 2x RGB specular color, 1 for coat specular: 17 parameters solely for BRDF without normal map, AO, SO… And with the growing adoption of VR and 4k, I predict that forward engine will be the norm in the future. Not necessary for game, but maybe for the growing demand of real time movie.

Originally I wanted to cover current state of physically based rendering (Material, lighting and camera). Due to lack of time I have switch to Material only (volume, surface, character BRDF etc…) and , again, due to lack of time, I have restrict myself to “common” material. Then reduced it to only opaque reflective material (no transparency)… Too much thing to cover!

PBR is a huge unsolved topic and when I heard people saying, “yes, we are PBR”, I just heard “I have no clue what PBR mean”. And I am not confident myself that I understand what PBR really mean 🙂


Siggraph 2016: An Artist-Friendly Workflow for Panoramic HDRI

The slides and course notes files of me and my-coworker Sébastien Lachambre and Cyril Jover “An Artist-Friendly Workflow for Panoramic HDRI” are available here:

On the official PBR course website:

and Unity Labs website:

On the asset store of Unity there is a pack of HDRI. This is a pack of 7 LatLong, 8192×4096 HDR images shot in different locations around the world. Accurate, unclamped cubemaps of interior and exterior environments; HDRIs that include the Sun are provided with an alternate version with the Sun already removed.!/content/72511
Note: HDRI can be download in Unity then use in another context, they are just .exr files. There is no restriction on both commercial and non-commercial usage for them.

Few notes:
As a programmer, I was often asking myself how artists are capturing HDRI ? After few research I have noticed that very often the HDRI available on the Internet lack range or metadata information to reconstruct absolute HDRI. Worse, many HDRIs are tweaked to looks good instead of being accurate to be used as a light sources. With my co-worker we have decided to write an extensive “tutorial” that explain how to capture an accurate HDRI. We have voluntary provide a lot of details and our equipment/software recommendation list. We hope by this to save readers time when they will try to reproduce our workflow. We have consider our workflow from an artists point of view instead of a programmer point of view, trying to use commonly know artist softwares. We also limit ourselves to average budget for this kind of capture.

The course notes (~80 pages) is the interesting part of the talk, the slide are just here to give an overview. I have included a section about what I call the “path of light”. It explain what is happening inside a camera from an emit photon to its life through the optics, the sensor, then the software processing. This is not something that is needed to understand to apply our method. But it is a really interesting piece of knowledge and help to put correct words on thing :).

Lastly in the course note I have decided to integrate a section call “Look Development”. Look development is a term pretty common in VFX industry but I was surprise to see how few people know about it in the game industry. At Unity we have develop a new tools call “Look Dev” that will be experimental in the next version 5.5 beta. This is a viewer that aim to help look development with HDRIs:


Of course, this kind of tools already exist, Substance, Marmoset, Mari, etc… The benefit of having one integrated into Unity is that it is WYSIWYG (What you see is what you get) in your Unity game.

Finally I have chose to add some digression about how to remove the sun and replace it with analytic directional light of similar intensity as it is often either not discuss or resume to a single sentence in others documents. This is currently a complex topics and I will be happy to see more technical discussion around this topics.

We hope that our document will help people to take their first steps into accurate HDRI capture and see more absolute HDRI appearing. The document come with some materials: Various Photoshop Actions that we use and set of HDRIs. One is available on publications website but we expect to deliver soon a package of HDRI via the Unity Asset Store for free that include all versions (white balance, absolute, unprocessed…) of an HDRI and metadata.  At first we were willing to distribute all the CR2 too but the size of the download become crazy insane and we think to do it only for one HDRI, so programmer willing to do some test will be able to do it.

Siggraph 2014 : Moving Frostbite to Physically based rendering V3

Here is the slides, course notes and Mathematica files of me and my-coworker Charles de Rousiers “Moving Frostbite to Physically based rendering” (The course notes have been update to v3, mathematica files to v3):

Course notes: course_notes_moving_frostbite_to_pbr_v3
Pdf Slides: s2014_pbs_frostbite_slides
PowerPoint Slides: s2014_pbs_frostbite_slides
Mathematica Notebooks: movingfrostbitetopbr-mathematicanotebook_v3
Mathematica Notebooks export as pdf to be readable without Mathematica: movingfrostbitetopbr-mathematicapdf_v3

Caution : Both Mathematica files are .zip that I rename to “.pdf” as WordPress don’t support zip file. So just right-click on the image below, save the pdf file then change the extension to “.zip”,

Slideshare version:

Alternatively the files are/was available at others location (Let here in case links are update):
And also on the official PBR course website: (To be update only slides for now)

The talk is a survey of current PBR technics and small improvement we have done for the Frostbite engine. It covert many topics. Here is the table of content of the course note (available on linked website):

1 Introduction
2 Reference
2.1 Validating models and hypothesis
2.2 Validating in-engine approximations
2.3 Validating in-engine reference mode
3 Material
3.1 Material models
3.2 Material system
3.3 PBR and decals
4 Lighting
4.1 General
4.2 Analytical light parameters
4.3 Light unit
4.4 Punctual lights
4.5 Photometric lights
4.6 Sun
4.7 Area lights
4.8 Emissive surfaces
4.9 Image based lights
4.10 Shadow and occlusion
4.11 Deferred / Forward rendering
5 Image
5.1 A Physically Based Camera
5.2 Manipulation of high values
5.3 Antialiasing
6 Transition to PBR

v2 Update:
During a year, we have get several feedbacks from various people on our document (Sorry we forget to do a list of all of them). There was several mistakes, typo and unclear statement. We have upgrade the course note with all the reported error and clarified some part. The v2 course contain the following list of correction (Also listed on page 98 in the new course note pdf document):

– Section 3.2.1 – Corrected wrong statement for describing the micro-specular occlusion of the Reflectance parameters: ”The lower part of this attribute defines a micro-specular occlusion term used for both dielectric and metal materials.”. Description of BaseColor and Reflectance parameters have been updated.
– Section 3.2.1 – Removed reference on Alex Fry work of normal encoding as it has not been done.
– Section 4.2 – Updated the description of color temperature for artificial lights sources. Including the concept of color correlated temperature (CCT).
– Section 4.4 – Clarified what is lightColor in Listing 4
– Section 4.5 – Clarified what is lightColor in Listing 5
– Section 4.6 – Updated and explained the computation of the Sun solid angle and the estimated illuminance at Earth surface.
– Section – Added comment in Listing 7: FormFactor equation include a invPi that needs to be canceled out (with Pi) in the sphere and disk area light evaluation
– Section – Clarified in which case the diffuse sphere area formula is exact above the horizon
– Section – Clarified in which case the diffuse disk area formula is exact above the horizon
– Section 4.7.4 – Correct listing 15. getDiffuseDominantDir parameter N is float3
– Section 4.7.5 – Correct listing 16. getSpecularDominantDirArea parameters N and R are float3
– Section 4.9.2 – Corrected the PDF of the specular BRDF and equations from 48 to 60. They had missing components or mistakes. The code was correct.
– Section 4.9.3 – Correct listing 21/22/23. getSpecularDominantDir parameters N and R are float3. getDiffuseDominantDir parameters N and V are float3
– Section 4.9.5 – Added and update comment about reflection composition: The composition weight computation for medium range reflections was causing darkening if several local light probes were overlapping. The previous algorithm was considering that each local light probes visibility was covering a different part of the BRDF lobe (having 10 overlapping local light probes of 0.1 visibility result in 1.0). The new algorithm considers that it covers the same part of the BRDF lobe (Adding 10 overlapping local light probes of 0.1 visibility result in 0.1).
– Section 4.10.2 – Corrected listing 26. Roughness and smoothness were inverted. The listing have been updated and an improve formula have been provided. Figure 65 has been updated accordingly.
– Section 4.10.2 – Added a reference to “Is Accurate Occlusion of Glossy Reflections Necessary” paper.
– Section 5.2 – Table~\ref{tab:SmallFloat}: Fixed wrong largest value for 14-bit float format. 16-bit float format is a standard floating point format with implied 1 on the mantissa. Max exponent for 16-bit float is 15 (not 16, because 16 is reserved for INF). Largest value is (1+m)^{maxExp} = (1+\frac{1023}{1024})*2^{15} = 65504. Whereas 14-bit float format has no leading 1, but a max exponent of 16. Largest value is m*2^{maxExp} = (\frac{511}{512})^{16} = 65408. 10-bit and 11-bit float format follow same rules as 16-bit float format.

v3 Update:
– Section 5.1.1 – Fix equation 67

Few notes

Last year I was giving a talk about Remember Me at GDCEurope 2013 : The art and rendering of Remember Me. And I was saying: Read more of this post

Inverse trigonometric functions GPU optimization for AMD GCN architecture

Version : 2.0 – Living blog – First version was 01 December 2014

First advice anybody have regarding inverse trigonometric functions (acos, asin, atan) is “do not use it”. And this is a good advise. It is often possible to get rid of all the trigonometric functions with trigonometric identities [1][2]. However with the growing complexity of lighting models I see more and more usage of them. One of the main use case I met is when I deal with solid angle calculation and area lights. So if we need to manipulate such functions, better to be aware of their cost. This post is about knowing the cost of GPU inverse trigonometric function and providing optimize version for the AMD GCN architecture (PS4, XBone, PC – AMD). For this post I have use the PS4 shader compiler (v2.00) for the analysis.

AMD GCN architecture basics

There is already plenty of good information available on the web about the AMD GCN architecture, so I will not repeat them here [3][4][5]. I recommend to read the excellent talk of Michal Drobot about “Low level optimization for GCN” [3] as I will mainly follow its vocabulary.

Main basics:
– instruction are classify into vector instructions v_ and scalar instruction s_. The scalar instruction can be coarsely consider as free as they are executed in parallel.
– instruction are full rate or quater rate, i.e this is equivalent to say there is instruction which are 4x slower than other. Full rate (FR): mul, mad, add, sub, and, or, bit shift… Quater rate(QR): transcendental instruction like rcp, sqrt, rsqrt, cos, sin, log, exp…
– macro instructions can expand to several instructions: tan, acos, asin, atan, pow, sign, length…
– there is free modifier: saturate, abs, negate, mul2, mul4, mul8, div2, div4…
– dynamic branching can be considering having cost >= 16 FR.
– VGPR count are more important than instruction count

Cost of inverse trigonometric function

How expensive is an inverse trigonometric function ?

On PS4 I get these numbers using the following code and isolating the instructions related to the function itself

float val;

float4 main() : S_TARGET_OUTPUT0
    float res = acos(val);
    return float4(res, res, res, res);

acos: 48 FR (40 FR, 2 QR), 2 DB, 12 VGPR
asin: 48 FR (40 FR, 2 QR), 2 DB, 1 scalar instruction, 12 VGPR
atan: 23 FR (19 FR, 1 QR), 2 scalar, 8 VGPR

I do not report the asm listing of these functions to avoid to overcharge the post with useless code.
The number 48 for acos is the equivalent full rate cost of the sum of full rate and quarter rate instructions.
To be fair, the PS4 implementation of acos/asin use a dynamic if to select between negative and positive value but the code in both branch is identical and only differ by the sign. So in reality the runtime cost is rather half of this, like 24FR + 1 DB. Still it bloat the shader code and cause increase of VGPR.
GPU compiler have a generic and accurate implementation of inverse trigonometric functions.  But we are free to use what we desire and are not force to use the GPU compiler version as they are only macro and not hardware instruction. I have decided to also provide the cost of the Cg reference implementation of these functions [6]. So the following cost are from explicit implementation of the function with the code provide in the Cg documentation:

acos: 19 FR(14 FR, 1 QR), 4 VGPR
asin: 18 FR(13 FR, 1 QR), 4 VGPR, 1 scalar instruction
atan: 23 FR (19 FR, 1 QR), 2 scalar, 8 VGPR

The difference between Cg version and macro version come from the “dynamic if” which is no more present in the Cg version. I also suppose that the Cg version is less accurate (Documentation said absolute error <= 6.7e-5). Still regarding these numbers, we get that inverse trigonometric function are expensive. As a game developer we know which accuracy and which range of values we need to support and we can tune functions to fit our need and reduce the cost.

Read more of this post

IES light format: Specification and reader

During my investigation on supporting IES lights for the Frostbite engine (With the help of Rodney Huff!) I have met several hurdles. The IES format is rather badly specified and when implementing a parser, many questions come without answer (And handling the different sysmetry is insane). This post is about helping people to find their way to support IES lights in their engine. And I will say that it is preferable to support EULUMDAT format, but sadly there is less resource on the web.

Photometric lights

There is few references about implementing photometric lights for real-time on the web. I already write several information about photometric lights, for both IES and EULUMDAT format,in the Siggraph 2014 PBR course notes of the talk Moving Frostbite to PBR. So I will not rewrite them here. Please refer to section 4.5 of the course notes. Here is some useful links:

IES and EULUMDAT viewer:
IES unofficial specification :
EULUMDAT unofficial file format:

The iesna.txt document speaking about the IES format is written by Ian Ashdown who is a member of the IES Computer Committee responsible for LM-63-02, and he also maintain the EULUMDAT file format specification on the Web. His website contain the latest information about these formats (

There use to have companion files with code for the iesna.txt document. But it is no more accessible. I get the permission from Ian Ashdown to host them here, and this is the only purpose of this blog post. The files below contain the IES parser with the C source code and some example files mention in the iesna.txt document (WordPress doesn’t handle zip file, so right-click then save target. Then rename extension to “.zip”) :


And here is some advice from Ian Ashdown:

The code was last updated in 1998. The code is still used in Ian Ashdown commercial products, so he cannot release the latest version. However, here is the (edited) change log for IES_READ.C reads:

// 98/09/12 – Fixed vertical axis symmetry determination error in ReadFile.
// 99/05/21 – Modified ReadFile to initialize horz_dist data member for luminaires with vertical axis rotational symmetry and to initialize vsymm_flag data member.
// 99/06/04 – Modified GetLine to check for buffer overflow.
// 99/08/15 – Modified ReadFile to call strncmp rather than strcmp to support lines with trailing whitespace.
// 01/08/07 – Modified ReadFile to initialize lum_dim data structure.
// 02/04/26 – Modified ReadFile to accept LM-63-2002 format files.
// 05/03/21 – Modified ReadFile to flush photometric data if error.

IESNA Type A and Type B photometric data files van be ignored – He have never encountered them in 20 years of architectural and roadway lighting work.

LM-63 specifies a maximum of 132 characters (inherited from the days of IBM Hollerith punch cards), but he have seen LM-63 files with up to 4,000 characters per line in the candela fields.

And lastly if you are generating a photometric web from the data for ray tracing or radiosity, you should interpolate the horizontal angles using a cubic spline curve (open or closed depending on whether the full 360 range of horizontal angles is specified).

Weathering and aging effects in the hand of artists

Version : 1.1 – Living blog – First version was 04 May 2014

With permission of Dontnod entertainmen

It is now frequent in game to have dynamic weathering and aging effects: Rain, snow, dirt, rust, dust, pollution… Most of the time these effects are drive by programmers because they require specific code like access to a custom shadow map or perform by a full screen space post process. Before leaving Dontnod I was working on a feature to allow artists to handle themselves these kind of effects. At the time we were requiring a lot of effects and I wanted to allow artists to prototype as much idea as they can. This post will provide explanation of this feature and will give implementation details under the Unreal Engine 4. It aim to work with a deferred rendering engine. These weathering and aging effects feature has been use at Dontnod but there is some pitfalls which may prevent to use it effectively in a shipping game. It all depends on the scale of the game and performance expected. I hope by exposing this idea that others could improve the system 🙂

I thanks Dontnod to allow me to talk about it.

 The weathering and aging effects

We know from graphic literature that a lot of weathering and aging effects can be done through surface properties modification [1]. Of course using complex multi-layered lighting model is the right way to handle it but it is way less flexible, will require a programmer to code every effects, and it will be difficult to get right regarding all supported lights type (like image based lighting or area lights).

As an example, the wet surfaces appearing when it is raining could be simulated with material properties modification: Roughness, diffuse albedo, normal… I talk a lot about this subject in other posts on this blog (see water drops series). However these modifications should be done only were it matter. When it is raining, you don’t want your interior surface to be wet. In Remember Me, we were handling this by adding some extra code in the shaders to modify the surface properties, then artists were vertex painting the part of the surfaces requiring to be dry. But this was not sufficient to handle all cases of wet surface. For example, a player walking in a wet street could, once he get into a dry interior, will let wet footprint on the ground. This could have been simulated with decals.

Taking another example, in Kill zone 4: Shadow fall [2] they perform a full screen space pass to modify the material attributes where normal are pointing up to add dust where it matter (after an explosion for example).

GBuffer modification

Thinking with a deferred renderer in mind, it is possible to identify a set of desired control for artists allowing them to modify material properties and simulating a weathering or aging effect. These controls are perform with GBuffer modification with:
– Deferred decals
– Full screen space quad. I call it material postprocess.
– Deferred effect lights: These are same as lights with shadow map or not, except they behave like deferred decal. The amount of light being use as opacity for blending operation. Soft shadow map also allow smooth transitions between effects.
– Object shaders: Properties will be modified directly at GBuffer generation time in the shader of the object. So this require specific code in each shaders. User could use vertex painting to bring information for an effect.

Every tools will perform some material properties modification to simulate an effect, like darkening the diffuse and boosting the smoothness for wet surfaces. All the GBuffer modification must be done before the lighting pass to be taken into account.

Applying the material property modification for the GBuffer modification control could be done in two ways.  Most common case is to use hardware blending, but it could be too restrictive. The other case is to use read/write ability into the same textures (a.k.a prorgammable blending). Sadly this ability is not widely supported. The PS4 and Mantle support it for example, DX11 doesn’t (I don’t talk about intel’s pixel synchronization but simple read/writing the same pixel).

Delaying the GBuffer modification

To support every platform and to be able to do any customization of material properties, I perform the modification of material properties in an extra full screen pass. Effectively delaying the GBuffer modification. Rather than modifying the GBuffer, the different tools simply output an effect weight inside the GBuffer. This effect weight is read later in the extra pass to apply the effect. There is multiple benefit to do that:
– Applying only one time the effect could save performance for heavy effect
– Accumulating effect weights could allow to clamp it in the delayed pass in order to limit the strength of an effect
– Centralized place to deal with the effect. Easier to author.
Sadly it will require to store the effect weight in the GBuffer.
Read more of this post

DONTNOD Physically based rendering chart for Unreal Engine 4

With permission of Dontnod entertainmen

I get the permission from Dontnod entertainment to release the graphic chart I, Sophie Van de Velde (Lead environment) and Laurent Harduin (Lighter) made for the artists to help them with the physically based rendering (PBR) workflow present in the Unreal engine 4. This chart is an updated version of the previous chart I post on this blog DONTNOT specular and glossiness chart.

To save the chart, just right clik and chose save link target as… The chart is a PNG file.


(Real world pictures courtesy of Andrea Weidlich from “Exploring the potential of layerer BRDF models” siggraph asia 2009)

The chart has been design for Dontnod team and with Unreal engine 4 convention for textures based on the Disney “principled” BRDF use in the Unreal engine 4 [1]. The chart is use as predefined value that the artist color pick and use when creating textures. For the different meaning of the parameters except the Porosity you can refer to the Unreal engine 4 documentation:

For the details of some values, refer to the other article from this blog like feedding a physically based shading model or GDCEurope 2013 talk : The art and rendering of Remember Me.


The color is provide in sRGB 0-255.

The diffuse part of the base color (the one use by the non-metallic) must be in the range of the first gradient 50-243. There is some sample values of real world material in sRGB below the gradient. Some of these values are base on real world measured material (from misc sources, not done by us) and other are have been generated by Laurent Harduin. He take calibrated raw picture of representative material, take the luminance histogram in Photoshop and use the value of the medium axis for the luminance. Then he blur the picture and take one pixel inside the blurred region and use that as the color value. This explain why in few case like the clean cement the color and the luminance doesn’t match perfectly. We also lower a bit the value to take into account the invevitable specular present during the capture.

The reflectance part (the one use by metallic) must be in the range 186-255 (not present in the chart). Some example are provided below the grey square. Most of the time the metallic color of material match what the eye see.


Simple monochrome linear parameter. Range is 0-1 but the gradient is from 0-255. The yellow sphere below represent in-engine capture of a sphere and a cube.


The specular part of Disney “principled” BRDF is a GGX BRDF. It use a roughness parameter. This roughness is the “Disney roughness”, not the real GGX roughness. Disney Roughness = sqrt(Roughness). When use at runtime this Disney Roughness is transform to the GGX roughness with roughness = Disney Roughness * Disney Roughness.

The gradient display roughness from 0 for smooth (left) material to 1 for rough material (right).
The grey gradient are from 0 to 255 and red segments are displayed  every 1/10 with a sphere like object below to show the in-game result of the designated value.
The first row of real world image above represent no metallic object, the second row represent metallic object. Goal is to give artist a better feeling of what is roughness.
The first row of sphere like object represent metallic object, the second row represent non-metallic object.

Note: The roughness here is coupled with the BRDF used by the Unreal engine 4, it may not be compatible with other engine or offline renderer.


The Dontnod chart include an unusual parameter named Porosity. This parameter is the “open porosity” of a material. It can be used for driving weathering and aging effect (Pollution, rain, aging…). More details on its usage can be found in previous blog post: Water drop 3a – Physically based wet surfaces and Water drop 3b – Physically based wet surfaces. In practice Dontnod use it mainly with the dynamic wet formula provided in the  mentionned previous post.

The range is remapped from 0-1 to 0-70% of open porosity. There is real worl image to try to give a feeling of what the value mean. An extremely porous material is the clay (70%), but open porosity can vary a lot for same material, clay could also be only 50%.


From Kevin Hnat thesis [2]. French translation from top to bottom. Clay, chalk, sand, limestone, granite.

Note: The porosity parameter is not used in the BRDF formulation. More research need to be done on this topic and currently there is only one porosity BRDF paper available which doesn’t fit with the current need.


There is no chart for the reflectance value of the Unreal engine 4, just let the value by default and apply a cavity map on it.

Difference with the old chart

The previous chart was based on modfied Unreal engine 3 where I introduced a new physically based renderer based on Blinn-Phong BRDF. This new chart is based on the Disney “principled” BRDF use in the Unreal engine 4 which is based on the GGX BRDF. The glossiness of the previous chart and the roughness of this one do not match. Moreover, the range is inversed. Previous specular value for metalic can be reuse for Unreal engine 4 reflectance parameter. UE4 use a mapped range of 0-1 to 0.08, so you need to do the conversion. But in practice there is so little difference that’s it is not necessary to use the precise values.


[1] Burley, “Physically based shading at Disney”,
[2] Hnat,  thesis “Influence of surfaces micro-geometry on realistic rendering” in French,