Phong Lighting Model

9 / 17
Implement the basic Phong lighting model to simulate ambient, diffuse, and specular highlights on object surfaces.

Combining ambient, diffuse, and specular into one complete lighting function comes down to this line:

Let's break it down.


The three components of Phong lighting

Phong is the classic real-time lighting model. It splits lighting into three separate terms, each computed independently and then summed:

Ambient: a fixed base brightness that never depends on direction — prevents back-facing surfaces from going completely black. A coefficient of 0.2 means the object always has at least 20% brightness.

Diffuse: the rough-surface scattering term. max(dot(normal, lightDir), 0.0) makes surfaces facing the light bright and surfaces facing away dark.

Specular: the mirror-like reflection term. pow(max(dot(viewDir, reflectDir), 0.0), shininess) produces a bright spot where the reflected ray points at the camera. Larger shininess means a smaller, sharper spot.


Moving light source

In this example the light orbits the sphere over time:

The light direction changes every frame, so the highlight, terminator line, and shadow all animate continuously.


Try changing it

ChangeEffect
shininess = 32.0 to 8.0Larger, softer highlight
shininess = 32.0 to 128.0Tiny, pinpoint highlight
ambientStrength = 0.2 to 0.05Darker shadows, stronger contrast
objectColor to vec3(0.9, 0.5, 0.1)Orange material

Exercise

The shininess value is already set in the exercise and the shader runs correctly. Try changing shininess to different values (4.0, 64.0, 256.0) and observe how the specular highlight responds.

Answer Breakdown

The full Phong combination:

Each term computed separately:

  • ambient = 0.2 * vec3(1.0) — fixed 20% white light floor
  • diffuse = max(dot(normal, lightDir), 0.0) * vec3(1.0) — direction-dependent scatter
  • specular = pow(max(dot(viewDir, reflectDir), 0.0), shininess) * vec3(1.0) — highlight

shininess = 32.0 is a medium-smooth starting point, similar to painted surfaces. Ranging from 4.0 to 256.0 covers everything from rubber to mirror.

Try changing specularStrength from 1.0 to 0.3 and see how much the highlight dims.

GLSL Code Editor

Correct Code Preview

Current Code Preview