Strange, didn’t anyone ever notice this? All builtin specular shaders (both 2.6 and 3.x) have a bug causing lightsources located behind objects to produce highlights, which is physically impossible and can yield to strange artifacts (see snapshot/testcase).
In this snapshot/testcase, the light source on the left is located behind the plane, the light source on the right is in front of the plane. The former must not produce any highlight.
The problem is in the internal BlinnPhong shader. A specular highlight may only be produced if the light source is in front hemisphere of the object, in respect to its normal (i.e., dot(N,L)>0). This condition is tested/taken care of (by clamping to 0) for the diffuse part, but not for the specular part.
Well, as it turns out, it might be considered a bug, but fixing it will introduce artifacts, namely a sharp cutoff at grazing angles. It is a general problem of both Blinn-Phong and Phong models not being physically correct, but merely an approximation of reality.
Note that this problem does not occur for planar surfaces, which is why I didn’t notice it at first with my testcase.
The general approach to workaround the artifacts appears to be to multiply the specular term by the diffuse term saturate(dot(N,L)). However, this heavily distorts the shape of the highlight at small shininess values, as well as its intensity at grazing angles.
I found the use of
to be an acceptable compromise. However, one should keep in mind that it introduces a second (besides the one required for the halfway vector) square root.
If I have the time I’ll try to post some snapshots of the various possibilities, and their visual effects on both hightlight behaviour and artifact visibility.
PS: Hm, if this problem cannot be reproduced on Mac, I wonder how they worked around it. I’ll investigate this.
Thank you for this! I was pulling my hair out trying to figure out why the specular light was shining through. I made a copy of the default BlinnPhong model from Lighting.cginc and implemented the fix: