<p>Unfortunately, the iridescence model is not made to be applied to a diffuse term. Pascal and I made it for microfacet models only (that is the specular term).</p>

<p>One way to understand how to include it to a game engine might be to look at Unity's HDRP implementation.</p>

<p>In the Lit.hlsl to see how to incorporate the iridescence Fresnel into a specular + diffuse BRDF:</p>

<p><a href="https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" rel="nofollow noreferrer">https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl</a></p>

<pre><code>PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData) {

    [...]

    if (bsdfData.iridescenceMask &gt; 0.0)
    {
        bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData.iridescenceThickness, bsdfData.fresnel0), bsdfData.iridescenceMask);
    }
}
</code></pre>

<p>See the implementation of the <code>EvalIridescence</code> in BSDF.hlsl:</p>

<p><a href="https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/30f1b16c8094ca133c165e56380ebb7ab9e7c0d9/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl" rel="nofollow noreferrer">https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/30f1b16c8094ca133c165e56380ebb7ab9e7c0d9/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl</a></p>

<p>What they are doing is to blend the standard Fresnel term with the iridescence one based on a iridescence mask value.</p>

<p>I hope this is helpfull.</p>

CC BY-SA 4.0
2019-02-01T09:42:44.870Z
2019-02-01T09:42:44.870Z
Laurent Belcour
<p>I'm trying to integrate the thin-film interference effect described in the paper "Belcour, L., &amp; Barla, P. (2017). A practical extension to microfacet theory for the modeling of varying iridescence." (<a href="https://hal.archives-ouvertes.fr/hal-01518344/document" rel="nofollow noreferrer">https://hal.archives-ouvertes.fr/hal-01518344/document</a>) into my material model, which is based on google/Filament's material model (<a href="https://google.github.io/filament/Filament.md.html" rel="nofollow noreferrer">https://google.github.io/filament/Filament.md.html</a>).</p>

<p>However I'm having trouble trying to understand the way to add them together. Let's say I'm shading a pixel, direct lighting goes like this:</p>

<pre><code>vec3 Fr = specularLobe();   // D * F * V
vec3 Fd = diffuseLobe();    // 1 / PI * diffuseColor

return (Fd + Fr) * light.color * light.attenuation * NoL;
</code></pre>

<p>And on the other side, indirect lighting goes like this...</p>

<pre><code>vec3 Fd = diffuseIrradiance() * diffuseColor;
vec3 Fr = specularIrradiance() * DFG();

return (Fd + Fr);
</code></pre>

<p>Now, if I want to add the thin film/iridescence layer on top of the base material, in what way does it take into account to bottom layer for all the lighting?</p>

<p>I've been looking at this implementation in UE4 (<a href="https://polycount.com/discussion/comment/2604578#Comment_2604578" rel="nofollow noreferrer">https://polycount.com/discussion/comment/2604578#Comment_2604578</a>), but they seem to input the result of the BRDF calculation directly into the 'Base Color' of the material, which I really don't think it is what I'm looking for, correct me if I'm wrong...</p>

<p><a href="https://i.sstatic.net/TMqe1.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/TMqe1.png" alt="UE4-editor-example"></a> </p>

<p>In this other implementation in Unity (<a href="https://github.com/Xerxes1138/Iridescence/blob/master/Iridescence.shader" rel="nofollow noreferrer">https://github.com/Xerxes1138/Iridescence/blob/master/Iridescence.shader</a>) they seem to account for iridescence in both IBL and direct lighting separately, but the layer base is not taken much into account as far as I know.</p>

<p>Finally, in the paper itself, the following statement is made:</p>

<blockquote>
  <p>Our extension consists in replacing the classic Fresnel reflectance
  term, F , by a more complex term, R accounting for all inter-reflections
  inside the thin-film layer, including constructive and destructive
  interference effects.</p>
</blockquote>

<p>From this I understand that simply by replacing the Fresnel Reflectance with the Airy Reflectance function should do the trick, but again, I'm not sure which would be the appropriate approach to being as physically correct as possible.</p>

<p>(The original supp-code from the paper can be obtained from: <a href="https://hal.inria.fr/hal-01518344v2/file/supplemental-code%20%282%29.zip" rel="nofollow noreferrer">https://hal.inria.fr/hal-01518344v2/file/supplemental-code%20%282%29.zip</a>)</p>

<p>Thanks for the help!</p>

<lighting><pbr><rasterizer><material><fresnel>
Iridescence/Thin-film interference integration as a layer
avilapa
# Iridescence/Thin-film interference integration as a layer

(Asked by: username_0 on 2019-01-30)

I'm trying to integrate the thin-film interference effect described in the paper "username_1, L., & Barla, P. (2017). A practical extension to microfacet theory for the modeling of varying iridescence." (<https://hal.archives-ouvertes.fr/hal-01518344/document>) into my material model, which is based on google/Filament's material model (<https://google.github.io/filament/Filament.md.html>).

However I'm having trouble trying to understand the way to add them together. Let's say I'm shading a pixel, direct lighting goes like this:

```
vec3 Fr = specularLobe();   // D * F * V
vec3 Fd = diffuseLobe();    // 1 / PI * diffuseColor

return (Fd + Fr) * light.color * light.attenuation * NoL;

```

And on the other side, indirect lighting goes like this...

```
vec3 Fd = diffuseIrradiance() * diffuseColor;
vec3 Fr = specularIrradiance() * DFG();

return (Fd + Fr);

```

Now, if I want to add the thin film/iridescence layer on top of the base material, in what way does it take into account to bottom layer for all the lighting?

I've been looking at this implementation in UE4 (<https://polycount.com/discussion/comment/2604578#Comment_2604578>), but they seem to input the result of the BRDF calculation directly into the 'Base Color' of the material, which I really don't think it is what I'm looking for, correct me if I'm wrong...

[![UE4-editor-example](https://i.sstatic.net/TMqe1.png)](https://i.sstatic.net/TMqe1.png)

In this other implementation in Unity (<https://github.com/Xerxes1138/Iridescence/blob/master/Iridescence.shader>) they seem to account for iridescence in both IBL and direct lighting separately, but the layer base is not taken much into account as far as I know.

Finally, in the paper itself, the following statement is made:

> Our extension consists in replacing the classic Fresnel reflectance
> term, F , by a more complex term, R accounting for all inter-reflections
> inside the thin-film layer, including constructive and destructive
> interference effects.

From this I understand that simply by replacing the Fresnel Reflectance with the Airy Reflectance function should do the trick, but again, I'm not sure which would be the appropriate approach to being as physically correct as possible.

(The original supp-code from the paper can be obtained from: <https://hal.inria.fr/hal-01518344v2/file/supplemental-code%20%282%29.zip>)

Thanks for the help!

**Tags:** lighting, pbr, rasterizer, material, fresnel


---

## 1 answers

### Answer by username_1 on 2019-02-01. Score: 3 | Accepted answer

Unfortunately, the iridescence model is not made to be applied to a diffuse term. Pascal and I made it for microfacet models only (that is the specular term).

One way to understand how to include it to a game engine might be to look at Unity's HDRP implementation.

In the Lit.hlsl to see how to incorporate the iridescence Fresnel into a specular + diffuse BRDF:

<https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl>

```
PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData) {

    [...]

    if (bsdfData.iridescenceMask > 0.0)
    {
        bsdfData.fresnel0 = lerp(bsdfData.fresnel0, EvalIridescence(topIor, viewAngle, bsdfData.iridescenceThickness, bsdfData.fresnel0), bsdfData.iridescenceMask);
    }
}

```

See the implementation of the `EvalIridescence` in BSDF.hlsl:

<https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/30f1b16c8094ca133c165e56380ebb7ab9e7c0d9/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl>

What they are doing is to blend the standard Fresnel term with the iridescence one based on a iridescence mask value.

I hope this is helpfull.


---

