The equation that made surfaces look real. A colour is three added lights: a flat ambient floor, a diffuse body that brightens as the surface turns to face the lamp, and a specular spot that flares where the mirror bounce points at your eye. color = ambient + diffuse·max(0, N·L) + specular·max(0, R·V)^shininess. Down the center the vectors go in, the model shades, the lit colour comes out. The blue team builds and defends it; the red team tries to break it.
source Bui Tuong Phong, Illumination for Computer Generated Pictures, Communications of the ACM 18(6), 311–317 (1975) — doi:10.1145/360825.360839. Rendered, not quoted.
Every symbol is a unit vector at the surface point. N the normal, L toward the light, V toward the eye, R the reflection of L about N.
ambient = ka, a constant floor so shadows are not pure black. diffuse = kd·max(0, N·L): peaks at 1 when the light is straight down the normal, clamped to 0 once the light slips behind the surface (Lambert). specular = ks·max(0, R·V)n: a highlight that peaks when your eye sits on the mirror bounce and tightens as the shininess n climbs.
For the current light angle, the three terms and their sum:
| term | value | cap |
|---|
Gouraud (1971) computed one colour at each triangle corner and smeared it across the face — highlights landed only if they happened to hit a vertex, and slid or vanished between them.
Phong's move: carry the normal across the face and run this equation at every pixel. The highlight becomes a crisp round spot instead of a stretched smear. The corners lit the-gouraud-shading; Phong lights the-rasterized-fragment. Each sphere is the next one's premise.
The blue team's live check: sweep the light from front to behind the surface and confirm the diffuse term is never negative — the clamp is holding. If red drops the clamp, this badge is where it shows.
Feed the model four things: the surface normal N, the light L, the view V (all unit-length), and a scalar shininess n. Here N and V face the camera; the light angle θ is how far the lamp has swung off the normal.
| input | meaning | range |
|---|---|---|
| N | surface normal | unit |
| L | toward light, angle θ off N | unit |
| V | toward eye | unit |
| n | shininess (highlight tightness) | 1…256 |
A vector must be normalized or the dot products lie. That is what you feed the panel below.
ka=0.10 kd=0.75 ks=0.40 (fixed). N·L = — R·V = —
a Phong-shaded sphere, computed per pixel
Move either slider — every term is recomputed from the dot products on the spot, never looked up.
What the model produces, proven: a single intensity per surface point that is the sum of the three terms. Straight-on light with these coefficients gives 0.10 + 0.75 + 0.40 = 1.25 (clipped to white); swing the lamp behind and the diffuse and specular collapse to 0, leaving only the 0.10 ambient floor. Never a negative colour.
The blue team's witness (left) confirms the clamp holds; the red team (right) tries to make it go negative.
It also breaks quietly if you forget to normalize N, L, V — the dot products stop being cosines and every term is wrong. And computing R per pixel is the expensive path: Blinn's halfway vector H (1977) is cheaper and matches measured highlights better at grazing angles. Phong is the first equation that made shading believable — not the last word on light.
"Phong shading and Phong reflection are the same thing." Cut. The reflection model is this equation; Phong shading is the separate idea of interpolating normals per pixel. This sphere is the reflection model.
"R·V and the Blinn halfway N·H give identical highlights." Cut. They differ — a Blinn exponent near 4× the Phong one roughly matches, and only near the mirror. Not equal.
"Higher shininess means a brighter highlight." Kept, corrected. Higher n means a tighter highlight — the peak stays at 1, the falloff just steepens. Brightness is ks, not n.
The red team's move: delete the max(0, …) clamp on the diffuse term. Now a surface facing away from the light gets negative brightness — an impossible colour. The blue team's witness (window 7) is watching.
Drop the clamp and back-facing normals go negative — the witness sweeps the light, finds a diffuse value below zero, disagrees with the known floor, and turns red. Nothing is faked; the attack is real and it is caught.