A double rainbow, dark band and fogbow computed from Snell's law and wave optics.
Nothing in this sky is painted. For 48 wavelengths the program traces 20,000 sunbeams through a spherical water drop with Snell's law, water's measured dispersion and Fresnel reflectance, and bins every exit direction by its angle from the shadow of your head. One internal reflection piles light up near 42 degrees, two near 51, and nothing can land in between, which is Alexander's dark band. Near each bow the traced caustic feeds Airy's wave theory, so shrinking the drops grows pastel supernumerary fringes and finally a broad white fogbow. The result is mapped through a stereographic lens onto a storm sky and reflected in the lake, and a cross-section view splats thousands of rays through one drop into a float buffer.
Try it. Drag the sky up or down to raise or lower the sun, and drag the slider (or use the wheel or left and right arrows) to change the drop size. Press Cross-section or the space bar to watch rays bend through a single drop, move the pointer over it to steer the highlighted ray, and switch between primary and secondary rays.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a physically based rainbow 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:
- Make a full-window canvas that stays sharp on high-DPI screens and resizes with the window.
- Write the refractive index of water as a function of wavelength (a Cauchy formula like n = 1.324 + 3300 / lambda^2, lambda in nm, is fine) and a function that turns a wavelength into an RGB color.
- For each of about 30 wavelengths, send 5,000 parallel rays into a unit sphere at impact parameters b from 0 to 1. Use Snell's law for the angles in and out, and compute the deviation after one internal reflection: D = 2(i - r) + (pi - 2r). Bin 180 - D (the angle from the antisolar point) into a histogram with 0.1 degree bins, weighting each ray by b.
- Paint a dark storm-blue sky. For every pixel, work out its angle from the antisolar point (put it below the horizon at the sun's elevation), look up the histogram, and add that color. A rainbow at 42 degrees should appear on its own.
Once that works, make it beautiful:
- Add two internal reflections too, and the secondary bow at 51 degrees, with its colors reversed, will appear along with the dark band between the bows.
- Weight rays with Fresnel's equations so the brightness is right, and blur by the half-degree disk of the sun.
- Draw the sky into a small offscreen canvas and scale it up, then add hills, a lake that reflects the bow, and light rain streaks.
- Let dragging up and down move the sun and watch the bow sink as it rises.
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 Airy theory for supernumerary bows and fogbows, a cross-section view of rays inside one drop, or ice crystal halos.