Fly through glassy minimal surface labyrinths, with a second maze behind every wall.
Triply periodic minimal surfaces such as the gyroid, sin x cos y + sin y cos z + sin z cos x = 0, split space into two interlocking labyrinths that never meet. Here the surface is thickened into a translucent sheet: each ray pays a Fresnel reflection at every face, is filtered and absorbed by the distance it travels inside, picks up the sheet's own amber glow, then carries on into the other labyrinth, whose air is tinted differently, so both mazes are visible at once. Thin walls show thin-film interference like a soap bubble, with colors that drift as the film's thickness swirls, while thick walls turn into smoky amber glass. The flight path is planned rather than scripted: Dijkstra searches a periodic grid of field samples for the route that stays deepest in the labyrinth from one cell to its copy a lattice step away, and because the world repeats, looping that route never ends. Frames are split across a small pool of Web Workers.
Try it. Drag to look around. Press space to cross into the other labyrinth, and S (or 1 to 4) to switch between the gyroid, Schwarz D, Schwarz P and Schoen I-WP surfaces. Drag the slider or press left and right to go from soap film to thick glass; up and down change speed.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a flight through a gyroid cave with JavaScript and the HTML canvas element, ray marched on the CPU. 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. Render into a small offscreen canvas (about 200 by 120 pixels) with an ImageData buffer, and draw it scaled up to fill the screen.
- The gyroid is the surface sin(x)cos(y) + sin(y)cos(z) + sin(z)cos(x) = 0. It splits space into two interlocking labyrinths. Treat the region where that expression is below a small thickness t (in absolute value) as rock, and everything else as air. Scaled by about 0.58 so it never overestimates, that gives the distance to the rock.
- Put the camera somewhere the gyroid value is large (deep inside a labyrinth). For each pixel, sphere trace a ray: step forward by the distance until it is tiny or the ray is too long.
- Shade hits with a normal from central differences, a light that travels with the camera and falls off with distance, and fog that fades to a dark color.
- Animate with requestAnimationFrame: move the camera forward slowly and turn it gently toward whichever direction has the most open space ahead.
Once that works, make it beautiful:
- Color the two labyrinths differently, so you can tell which side of the wall you are on.
- Make the walls glow from inside where they are thin: the wall's thickness is about 2t divided by the length of the gradient, so thin walls let more light through.
- Adapt the resolution to the frame time so it stays smooth.
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 translucent walls that show the other labyrinth behind them, other minimal surfaces like Schwarz P and D, or planning a smooth path through the maze with a graph search.