Specular reflection, side on

Reflection lobe explorer

A perfect mirror sends the incoming ray out along one exact direction, R. Real surfaces spread it into a cone. Drag L or V in the diagram, then change the shininess to widen or tighten that cone and watch the highlight on the sphere respond. Drag the light all the way below the surface to see what the formula does when there is no light to reflect.

specular term ms ⊙ ls max(0, R·V)mh =
Side-on view of one surface point drag the L and V handles
Drag L or V around the hemisphere
N — surface normal L — toward the light R — mirror direction V — toward the viewer lobe — (R·V)mh
What the viewer sees mh = 32

The highlight is the set of points on the sphere whose own R happens to line up with V. Move the light and the highlight slides across the surface; it is a reflection of the source, not a mark on the object.

When R goes under the surface

Since R = 2(N·L)N − L, taking the dot product with N gives R·N = 2(N·L) − (N·L) = N·L. So R sits on the same side of the surface as L, always. Move the light behind the surface and the arithmetic keeps working perfectly — it just describes a ray travelling into the material, where no viewer can be.

Nothing in the specular term mentions N·L — it depends only on R and V. So the term does not collapse on its own, because R·V can still be positive while R is underground, and max(0, R·V)mh happily returns a highlight on a surface the light never reached. In this edge-on view the value works out to exactly R·V = −cos(θL + θV), so the phantom exists for the whole 90° window where θL + θV lies between 180° and 270°.

It is not a faint residue either. On a curved surface the normal varies, so some point always lands near R·V = 1: with this preset the phantom band peaks at about 0.95 just past the terminator, and even at mh = 128 it only falls to 0.93. Untick the gate to see it — a dashed red ray here, and a bright band on the dark side of the sphere. OpenGL kills it with an explicit factor f = 1 when N·L > 0 and 0 otherwise, applied to the specular term alone; that gate is a separate thing from the distance attenuation.

N · L
R · N (same value)
R · V
Specular applied
Lobe half-width
The same light at six shininess values click a sphere to jump to it

Shininess in OpenGL runs from 0 to 128. Larger values do not make a surface brighter — they concentrate the same energy into a smaller, sharper highlight, which is what the eye reads as "polished".

Material
Geometry

Angles are measured from the surface, so 90° is straight up along N. When the view angle matches the reflected ray exactly, R·V reaches 1 and the highlight peaks.

Diagram

With V locked to R the viewer rides along the mirror direction, so the specular term stays at its maximum no matter where the light moves. Push the light angle past 180° and it drops behind the surface — then turn the gate off to see what the raw formula does.