Visualizations
129 / 500

129 · Physics

Light & Shadow

Red, green and blue lights cast crisp, colored shadows through spinning shapes.

For each light, rays are cast toward every corner of every wall and shape, plus a hair to either side. The nearest hit for each ray, sorted by angle, outlines a visibility polygon: everything that light can see. Filling those polygons with radial gradients in additive mode lets colored lights mix where they overlap.

Try it. Move the pointer to carry a light. Click to drop it and pick up another.

  • Ray versus segment intersection
  • Visibility polygons
  • Radial gradients

View the source · one module, plus a small shared runtime for sizing, the animation loop and input

Build your own

Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.

Build a 2D lighting demo with colored lights and crisp shadows using 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 canvas that fills the window and resizes with it, with a dark background.
- Place about 12 slowly rotating polygons (triangles, squares, hexagons) around the room. Each frame, turn their edges plus the four walls of the window into a list of line segments.
- For a light at the pointer, compute its visibility polygon: for every segment endpoint, cast three rays from the light, one straight at it and two offset by about 0.0001 radians. Use ray versus segment intersection to find the nearest hit for each ray, sort the hits by angle, and connect them into a polygon.
- Fill that polygon with a radial gradient centered on the light that fades to transparent, then draw the shapes in near-black on top.

Once that works, make it beautiful:
- Use three lights, red, green and blue, and draw their polygons with globalCompositeOperation = "lighter" so they add up to white where they overlap and leave colored shadows where only some of them reach.
- Draw the lights into an offscreen light map, then multiply it over a subtle tiled floor so the light seems to land on a surface.
- Light the edges of each shape that face a light in that light's color, and draw each light as a small glowing orb.
- Let the lights wander when idle; the pointer carries one, and a click drops it and picks up another.

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 soft shadows from several samples per light, a small top-down game with line of sight, or mirrors that reflect the rays.
PreviousPaper MarblingInk drops, combs and styluses on a size bath, then a print pulled onto paper. NextDifference EngineBrass figure wheels tabulate a polynomial with nothing but addition and rippling carries.

Related visualizations

  • Checker ShadowIllusions Squares A and B are the exact same gray. Move the light and the shadow keeps lying.
  • Path Tracer3D Photorealistic light, computed by bouncing millions of random rays.
  • Shadow Sculpture3D One carved object casts three different shadows at once. Draw your own.
  • Near Light SpeedPhysics Drive a city street near light speed and see what relativity really does to the view.
  • Volumetric CloudsNature Raymarched cumulus with silver linings, light shafts and drifting shadows.
  • MiragePhysics Bent light over hot asphalt and cold sea: road puddles, floating cars, Fata Morgana.
  • Rainbow OpticsPhysics A double rainbow, dark band and fogbow computed from Snell's law and wave optics.
  • Optical BenchPhysics A blueprint ray tracer: prisms, lenses, mirrors and a fiber with real glass dispersion.
  • Prism PuzzleGames Split white light with rutile prisms to light colored targets. A search AI plays.

Use ← and → to move between demos. While the canvas has focus, keys go to the demo instead.

← More from Emergent Mind Labs