Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

NdotL Lambert ambient light questions

Discussion in 'Shaders' started by IronMathbook, Nov 14, 2016.

  1. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I am very confused about the light fall off for Lambert. I know that
    NdotL returns values between 1 and 0 corresponding to 0&180 to 90 degrees. However there are values between 0 and -1 which are on the backside of the object.
    Everything below 0 is a flat color and is defined by ambient light
    If I use half Lambert NdotL*0.5 + 0.5 the fall off is softer however only pixels between 1 and 0 are effected. how in the world is half Lambert a light wrap if nothing is being wrapped.

    If a character is facing a light source and I am looking at the back of the character all is see is a flat color starting from where pixels are more than 90 degrees away from the light. If I uses half Lambert the backside is still one flat color. I expected to see more light creping around to the backside; this is the wrap I expected in the term light wrap.

    Is there a way to force pixels with values from say 0- 0.2 to reflect light
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    NdotL is the dot product between the normal and the light direction, which is the same as the cosine of the angle between these two vectors if they are normalized.

    Straight to the light, the value is 1. At 90 degrees it's 0. The typical way to do Lambert is:
    saturate(NdotL);
    This way values under 0 on the faces away from the light source are clamped to 0. This is also roughly how things are in the real world.

    If you use:
    0.5 + 0.5 * NdotL;
    You would expect the faces away from the light source to also be influenced. This however only works when shadows are disabled on the light source. Otherwise the front of the object will simply cast a shadow on the back of the object and it will still not be influenced by the light.
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,381
    Seems like what you what is an adaptive exposure, or something to fake it. You might try using a dot product of the view direction and light direction and either artificially increase the light brightness or apply some minor bias & scale to the ndotl as the vdotl increases.
     
    Blackhart likes this.
  4. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I understand that is is based on cosign. I was just uncertain if it was clamped or not; I suspected that it was. Is the clamping built into Unity because I would like to remove it. I think clamming it would produce better false ambient light; currently, using a solid color flattens geometry and is wrong unless there is very little ambient light.
    Self shadowing to that degree seems physically inaccurate in ambient light too.


    Messing around with vdotl sounds like a good idea.But I wonder if all dot products are clamped.
    I am surprised that no one has asked about this before.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,381
    Dot products are not clamped by default.
     
  6. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Oh okay. Then how or why is NdotL clamped? Is it due to using normalize or saturate. I wouldn't think so but I can't figure out any other way that it could get clamped unless Unity does it under the hood.
     
  7. Blackhart

    Blackhart

    Joined:
    May 2, 2015
    Posts:
    10
    Unity does it under the hood with the saturate function.

    Irradiance:

    Named ndotl as Lambertian isn't right. NdotL is a part of the irradiance calculation...
    To understand what irradiance is, look at my attached paint plan below.

    The irradiance calculation is: E = El
    • Irradiance, noted E, is the sum of energies of the photons passing through the material surface in one second - i.e, it's the sum of all the light irradiances.
    • El is the irradiance perpendicular to the light direction, commonly, it's the light color - i.e, if the light direction is parallele to the normal vector, El = light color.
    However, as you can see in my plan, the Light3 is behind the material surface. So, it can't illuminates the surface's point. To handle that, we include the N dot L term, which give us the cosine of the angle between the normal vector and the light direction.
    • If the dot result is between -1 and 0, the angle is between 180 and 90 degrees = the light is behind the material.
    • If the dot result is between 0 and 1, the angle is between 90 and 0 degrees = the light is in front of the material.
    Only lights in front of the material interest us, so we clamp the resulting value of the dot product between 0 and 1.

    Our final irradiance calculation is: E = El * saturate(N . L)

    With that, we can compute our irradiance!
    Confess our light 3 color is a plain white color : RGB = (1.0, 1.0, 1.0) and the dot result is -0.3 (>90 degrees <=> behind the material) clamped to 0.

    E3 = El3 * (N . L3) = white * dot result = (1.0, 1.0, 1.0) * 0 = (0, 0, 0).

    There is no irradiance from it !
    If we didn't clamp the dot result, our light will remove color, which is not possible in optical physics.

    Lambertian:

    Lambertian law's is based on the irradiance calculation. The defining characteristic of Lambertian surfaces is that outgoing radiance is proportional to irradiance. So, Lambertian diffuse calculation = Cdiff * E, where:
    • Cdiff is the diffuse color.
    • E is the irradiance seen above.

    To perform your desired result, you can compute the Lambertian reflection calculation. Which is: ((m + 8) / (8 * PI)) * pow(saturate(V . L), m) * Cspec * E, where:
    • m is the smoothness value.
    • V is the view direction.
    • L is the light direction.
    • Cspec is the specular color.
    • E is the irradiance seen above.
    @bgolus solution is also viable.

    Note: V . L computation is also named as halve vector.
     

    Attached Files:

    Last edited: Nov 18, 2016
    ashrafmajdee likes this.
  8. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    thanks I've been getting Lambert and irradiance confused

    "If we didn't clamp the dot result, our light will remove color"
    Is this a mathematical problem? Because in physics the color of the light would be due to it's wavelengths and color of the object would be due to the reflected wavelength. Assuming the light wavelength isn't the wavelength the object reflects
    The things that go on in shaders goes over my head. I had an option to take a class that uses things like dot, cross products and math closer to what we use here but I took a class with Taylor series instead.
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,381
    Dot products go negative.

    Color + Unclamped Dot Product = possibly subtracting from the color.
     
    Blackhart likes this.
  10. Blackhart

    Blackhart

    Joined:
    May 2, 2015
    Posts:
    10
    Yes, it's a mathematical problem. Lambertian is a non-photorealistic rendering technique then, there is no electromagnetic waves.

    Imagine we have 2 lights parallel respectively to N and -N - i.e Light1 is in front of the material (and so, illuminates him <=> dot result = 1) and light2 is behind the material (can't illuminates him <=> dot result = -1). The two lights have a plain white color.
    If we compute Lambertian law's, we have:
    Lambertian light1 + Lambertian light2 = (light1 white color * light1 dot result) + (light2 white color * light2 dot result) = (1, 1, 1) * 1 + (1, 1, 1) * -1 = (1, 1, 1) + (-1, -1, -1) = (0, 0, 0)
    We have a plain black material color instead of a plain white material color ... Light2 has remove color ! It's why we clamp the dot result.
     
    Last edited: Nov 19, 2016
  11. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Well I guess I could do the math differently though it wouldn't make it Lambertian anymore.
    This is why I wish we could do more than add multiply and divide. I started looking at the math behind photoshop blends.
    I am able to do stuff like color burn and screen but I am unable to use things like overlay if I don't want is etc statements.
    I will probably just rely more on global illumination and half Lambert or Oren–Nayar. I might still try bgolus solution.

    BTW there are two ways to do half Lambert
    NdotL*0.5 + 0.5
    or
    NdotL+0.5/1.5 I go this when I went searching for wrapped diffuse.