Search Unity

Source of surfaceReduction and grazingTerm formulas in lighting.hlsl?

Discussion in 'Shaders' started by abovenyquist, Jul 23, 2019.

  1. abovenyquist

    abovenyquist

    Joined:
    Feb 13, 2014
    Posts:
    14
    There's two formulas in lighting.hlsl that are a mystery to me; I'm hoping someone can shed light on them.

    1) The EnvironmentBRDF function is:

    half3 EnvironmentBRDF(BRDFData brdfData, half3 indirectDiffuse, half3 indirectSpecular, half fresnelTerm) {
    half3 c = indirectDiffuse * brdfData.diffuse;
    float surfaceReduction = 1.0 / (brdfData.roughness2 + 1.0);
    c += surfaceReduction * indirectSpecular * lerp(brdfData.specular, brdfData.grazingTerm, fresnelTerm);
    return c;
    }

    What is "surfaceReduction?" Where does the particular 1.0 / (brdfData.roughness2 + 1.0) for it come from? I've gone through some blogs and papers on Image Based Lighting, but can't seem to find that particular formula.

    2) outBRDFData.grazingTerm = saturate(smoothness + reflectivity);

    Where does that formula come from? It seems strange since smoothness and reflectivity don't seem to have the same "units."
     
  2. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    The grazing term would be to do with fresnel reflection; wherein reflectivity on the surface of objects increases at grazing angles. In this case it's simply a value that increases reflection intensity and sharpness at grazing view angles. Surface reduction, on the other hand, decreases the intensity of specular contribution as an object becomes more diffuse. This is more of an approximation, otherwise fully diffuse objects would be unrealistically bright.
     
  3. abovenyquist

    abovenyquist

    Joined:
    Feb 13, 2014
    Posts:
    14
    Thanks for your response!

    I should have been more clear -- I know what Fresnel reflection is, and know the usual terms for it. What I'm wondering about is the saturate(smoothness + reflectivity) expression. I haven't seen anything like that anywhere else. Adding smoothness to reflectivity doesn't make logical sense to me (but I may be overlooking something).

    Similarly, I get that the surfaceReduction formula is trying to reduce indirect specular reflections for rough objects; I'm wondering where the specific 1.0 / (brdfData.roughness2 + 1.0) came from. Again, I haven't found that formula anywhere else.
     
  4. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    I believe they were mentioned in a GDC/Unite talk about PBR shaders a few years ago (I can't find said talk right now), but from memory they're just approximations (like a lot of rendering). For the first one, smoothness is the inverse of roughness, and reflectivity is essentially a value relating to how metallic the object is. As such, for a non metallic object, it will still have a nice amount of reflection at the edges that decreases as an object becomes more diffuse, whereas a metallic surface will retain a constant reflection strength regardless. For the surface reduction, I believe that was just an observation they made between their initial BRDF and the source material; it was twice as bright when fully diffused, and decreased in an exponential manner.
     
  5. ekakiya

    ekakiya

    Joined:
    Jul 25, 2011
    Posts:
    79
    With offline renderer, we can treat each pixel of env map as a light, lit the surface by those lights and integrate them.
    With real-time renderer, we use half pre-calculation for those lights.
    Half pre-calculate when bake mipmaps of env maps, and the remaining real-time calculation are those grazing term things.

    You can find nice document in core/ImageBasedLighting.hlsl ,that is one of the referred file in LWRP/lighting.hlsl .