The lamp is not a single point light — its disc area is sampled at N fixed points (a Fibonacci-spiral disc distribution), and every screen fragment casts an independent ray-sphere test toward each sample against the spherical occluder in a GLSL fragment shader. The fraction of unblocked samples is that pixel's real brightness: fully blocked everywhere → umbra; partially blocked → penumbra gradient; unblocked → fully lit. No 2D geometry is reused — this is a genuine 3D ray/sphere visibility test per sample, per pixel.
umbra radius u = r_o − (r_L − r_o)·d2/d1
penumbra radius p = r_o + (r_L + r_o)·d2/d1
These match the closed-form similar-triangles result exactly, cross-checking the shader's Monte-Carlo-style sampling. Drag the pumpkin to reposition it (x/y); drag empty space to orbit, scroll to zoom.