# Avoiding Mach band effect when using multiple lights

I wrote a simple Phong shader with two directional lights for a project, and noticed an unpleasant artifact in the lighting. Where both lights are illuminating the same region, dark bands appear at the light terminators where N.L reaches zero. At first I thought it must be a bug in my code, but a quick test revealed the Unity standard shader has the exact same problem.

My best guess is that this is some form of the Mach effect, and our retinas are overshooting where the brightness plateaus. Does anyone know any tricks to mitigate this effect?

EDIT FOR CLARITY:

Here are two more images to illustrate the effect better - one with my shader, and one with Unity's diffuse shader, with the lights at 90 degrees and all specular and ambient contributions removed.

You can clearly see the dark bands around the top right quadrant where one light's terminator intersects the other's area of effect (well, I can anyway, YMMV). I've run an eyedropper over it and confirmed it's a perceptual effect, the pixels do not in fact get darker.

• Is it rendered in linear colour space ? – PaulHK Dec 20 '17 at 12:46
• Do you actually have two lights 180 degrees apart? It should get dark at the light terminator but it wouldn't normally get light again on the other side unless you have two-sided lighting turned on and shadows turned off, or two lights on opposite sides. – Dan Hulme Dec 20 '17 at 13:28
• PaulHK, tried it with both and the effect persists, although it's a little less pronounced in linear. – russ Dec 20 '17 at 13:32
• Dan, check out the pics. The lights are more like 60 degrees apart, the problem is when one light's contribution reaches zero, it appears to have a negative contribution to the other light - probably just a perceptual artifact but still annoying. – russ Dec 20 '17 at 13:35
• Unfortunately, this is the correct result of the Lambertian lighting model. The physically valid way of getting rid of it is to replace your point light sources with area lights. Alternatively, if you don't care about correctness you could replace the $\max(n\cdot\ell,0)$ step with a different function that smooths over the kink at $n\cdot\ell=0$. – Rahul Dec 22 '17 at 2:11