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.