Photorealistic light, computed by bouncing millions of random rays.
This is how film renderers make light look real. For each pixel, a ray bounces randomly around a lit room of matte, mirror, glass and glossy spheres, and at every matte bounce a shadow ray also checks the ceiling light directly, which lets the image converge in seconds. Samples add up in a floating point buffer, so soft shadows, color bleeding from the red and green walls, and the caustic under the glass ball all emerge on their own. The image starts noisy and sharpens as samples accumulate.
Try it. Drag to move the camera, which restarts the render. Click a sphere to cycle its material.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a progressive path tracer of a Cornell box with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Render into a small offscreen canvas (around 240 by 160) with ImageData and draw it scaled up to fill the window.
- Build the scene from planes and spheres: a room with a red left wall, a green right wall, white floor, ceiling and back wall, a square light in the ceiling, and two or three spheres on the floor.
- For each pixel, shoot a ray from a pinhole camera. When it hits a matte surface, bounce it in a random cosine-weighted direction and multiply the path's color by the surface color. When it hits the light, add the light's brightness. Stop after about five bounces.
- Keep a Float32Array with the running sum for every pixel. Each frame add one more sample per pixel (or as many as fit in about 12 ms) and display the average, so the noisy image visibly converges.
Once that works, make it beautiful:
- Add next event estimation: at every matte bounce, also pick a random point on the light, send a shadow ray to it, and add its contribution if nothing blocks it. Then ignore the light when a matte bounce hits it directly. The image will clean up dramatically.
- Give one sphere a mirror material and one sphere glass: refract with Snell's law and choose reflection or refraction using the Fresnel equations, so a caustic appears under it.
- Tone map with the ACES filmic curve and apply gamma before writing pixels, and show the samples per pixel in a corner.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as depth of field, rough metals and glossy plastic, or a simple denoiser that blurs only across similar surfaces.