Lambert Lighting (Sphere)
Adding basic diffuse shading to a sphere comes down to this line:
Let's break it down.
What is diffuse lighting
Diffuse lighting is the simplest lighting model — it simulates the way rough surfaces scatter light evenly in all directions. Wood, stone, and cloth all look this way.
The result is intuitive: surfaces facing the light are bright, sides taper off, and faces pointing away are dark.
What does dot(n, lightDir) mean
dot(n, lightDir) measures how well the surface normal and the light direction line up:
- Perfectly aligned (normal faces the light) → 1.0, 100% brightness
- Perpendicular (normal at 90° to the light) → 0.0, 0%
- Facing away → negative number, clamped to 0 (can't be darker than black)
max(..., 0.0) clamps negative values to 0, ensuring back-lit surfaces stay at zero rather than going negative.
Combining the brightness
The shader uses a blend formula:
0.15 is a base brightness floor (preventing a fully black shadow), and 0.85 * diff is the light contribution. Together, bright spots approach 100% while dark sides hold at 15%.
Try changing it
| Change | Effect |
|---|---|
0.15 to 0.4 | Darker side gets brighter, less contrast |
0.85 to 1.5 | Bright areas overexpose and turn white |
lightDir x from -0.4 to 0.8 | Light moves from left to right, flipping the shadow |
Exercise
The sphere in the exercise is a flat dark shape because diff = 0.0. Fill in the TODO to compute the correct diffuse value and give the sphere a proper light-to-dark gradient.
Answer Breakdown
Starting state: diff is hardcoded to 0.0, so the sphere shows only the base * 0.15 floor — a flat, dim circle.
The fix: compute dot(n, lightDir) and clamp it with max(..., 0.0). Where the normal aligns with the light direction, diff approaches 1.0, brightening that pixel.
Try replacing max(dot(n, lightDir), 0.0) with dot(n, lightDir) * 0.5 + 0.5 and see how the shadow side changes.