Task 6 of 6
The payoff. A point is in shadow when something sits between it and the light —
and you already own the tool that answers that: march again, from the hit point
toward the light. Here's Inigo Quilez's beautiful upgrade: instead of a binary blocked/clear,
track how closely the shadow ray grazes the scene. The running minimum of
3 · d / t (distance over travel) is ≈1 when the ray stays clear, 0 when it's
blocked, and slides smoothly between when it grazes — a free penumbra.
The kernel takes a shadowOn switch so you can A/B it: with the light swung
low to the left, the left lobe casts a soft-edged shadow across the neck of the blob. One
more march, and a scene with no triangles anywhere gets real cinematography.
The driver also hands you a separation slider, which is task 2's point
made in one gesture: the program is a pure function of its controls, so dragging it re-runs
the whole thing. Slide the two centres together and smin welds them into a
single blob; pull them apart and the neck thins, necks down, and snaps. Solve the task
first — it defaults to the 0.55 the scene has always used — then drag it.
sh = Math.min(sh, 3.0 * d / st) — and scale the diffuse
term by it when shadowOn is 1.st = 0.06 so it clears its own surface(wx + lx·st, wy + ly·st, pz + lz·st), 32 stepssh = Math.min(sh, 3.0 * d / st), clamped ≥ 0st += Math.max(d, 0.02), then shade c = 0.15 + 0.85 * diff * shAt travel distance st, a field value d means the ray
passes within d of an occluder. The ratio d / st is the sine
of the "clearance angle" from the surface point — small angle, deep penumbra. The 3
just sets how sharp the shadow edge is.
let sh = 1.0;
let st = 0.06;
for (let j = 0; j < 32; j++) {
const d = sceneDist(wx + lx * st, wy + ly * st,
pz + lz * st, sep, r, k);
sh = Math.min(sh, 3.0 * d / st);
st += Math.max(d, 0.02);
}
sh = Math.max(sh, 0.0);
And remember to only apply it when
shadowOn > 0.5.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.