Blinn-Phong

11 / 17
Learn core lighting terms (diffuse/specular/rim) on a simple sphere.

Phong specular requires computing a reflection vector. Blinn-Phong takes a faster route — it uses the half-vector instead:

Here's what the half-vector is, and how it differs from Phong.


What is the half-vector?

l points toward the light, v points toward the camera. Add them together and normalize — the result is the half-vector, pointing exactly halfway between l and v.

Phong asks "does the reflected ray reach the eye?" (dot(r, v)). Blinn-Phong instead asks "does the surface normal point toward the half-vector?" (dot(n, hV)). Both produce similar-looking highlights, but the half-vector is cheaper to compute and is the standard in real-time rendering.


pow controls highlight size

dot(n, hV) ranges from 0 to 1 (0% when the normal and half-vector are perpendicular, 100% when aligned). The pow exponent determines tightness: a high exponent produces a small, sharp highlight like a mirror; a low exponent spreads it wide like a matte surface.

48.0 gives a moderately tight highlight — visible but not pinpoint.


Diffuse + specular combined

baseCol * (0.12 + 0.88 * diff) is the diffuse layer (base color scaled by how much it faces the light). vec3(1.0) * spec adds a white specular highlight on top. Together they form the full Blinn-Phong result.


Try changing it

ChangeEffect
48.08.0Highlight spreads wide, matte-like surface
48.0128.0Highlight shrinks to a tight bright dot, glass-like
vec3(1.0) * specvec3(1.0, 0.8, 0.4) * specWarm yellow highlight
Light direction vec3(-0.4, 0.6, 0.7)vec3(0.8, 0.2, 0.7)Highlight shifts to the right side

Exercise

Replace hV = v with the correct half-vector hV = normalize(l + v) so the sphere shows a white specular highlight.

Answer Breakdown

Starting state: hV = v substitutes the view direction for the half-vector. This makes dot(n, hV) peak at the center of the sphere rather than at the lit area, producing a misplaced highlight.

The fix: normalize(l + v) averages the light and view directions. Now dot(n, hV) peaks where the surface faces both the light and the camera — exactly where a real highlight should appear.

Try changing 48.0 to 200.0 to see the highlight compress into a near-invisible pinpoint at very high glossiness.

GLSL Code Editor

Correct Code Preview

Current Code Preview