← Back to Designer

How It Works

How a simulated pool of water creates perfectly tessellating geometric patterns

Like I'm Five
Like I Have a PhD

The Big Idea

Imagine a perfectly square pool of water on a sunny day. You drop a stone in, and ripples spread out. When those ripples hit the walls, they bounce back. All these bouncing waves overlap and create a shimmering pattern of bright lines on the bottom of the pool — those wiggly, glowing lines you see in real swimming pools.

Those bright lines are called caustics. They happen because the wavy water surface acts like a bumpy lens, bending sunlight and focusing it into bright curves.

Here's the trick: the way waves bounce off the pool walls is exactly the same math as mirroring a picture. So if you take the pattern from one pool and mirror-flip copies of it next to each other, the edges line up perfectly. No seams. It tiles forever.

Left: waves bouncing in a square pool. Right: the bright lines (caustics) those waves create on the pool floor.

What Are "Modes"?

A pool can vibrate in different ways, just like a guitar string can play different notes. Each way of vibrating is called a mode. A simple mode might be one big wave sloshing back and forth. A more complicated mode has many smaller waves.

Each mode has two numbers: (m, n). Think of m as "how many bumps side to side" and n as "how many bumps top to bottom."

Three different modes: (1,0) sloshes left-right, (0,1) sloshes up-down, (1,1) has a checkerboard pattern.

When you click a cell in the mode grid, you're adding that vibration to the pool. You can mix many modes together, like mixing notes to make a chord. Different mixes make different patterns.

Understanding the Mode Grid

The mode grid is an 8×8 table. Each cell represents one possible vibration of the water. The two numbers (m, n) tell you:

m = bumps across →

How many wave peaks fit side to side. m=1 is one gentle hill. m=4 is four bumps packed in the same space.

n = bumps down ↓

How many wave peaks fit top to bottom. Same idea, but in the vertical direction.

Click any cell below to see what that single mode looks like as a wave surface (left) and as the caustic pattern it produces (right):

Click a cell

▲ peaks▼ valleys

Light pattern on pool floor

Notice the pattern: low numbers make big, simple shapes. High numbers make fine, detailed textures. Here are some intuitions:

(1,0) and (0,1)

The simplest waves — one bump in one direction. They create broad, sweeping caustic lines.

(1,1)

One bump in each direction at once — a single dome in the center. Creates a diamond/circle caustic.

(3,1) and (1,3)

Unequal numbers create elongated patterns — stretched in one direction. With 4-fold symmetry on, both get added together, creating a balanced design.

(4,4) and higher

High numbers create dense, intricate detail. These are the "fine filigree" that adds complexity to a pattern.

Mixing Modes = Mixing Notes

Think of each mode like a musical note. One note by itself sounds simple. But combine several notes and you get a chord — something richer and more complex. The same thing happens with water vibrations:

Click cells below to add/remove modes and see how they combine. The left shows individual waves added together, the right shows the resulting caustic pattern:

0 modes selected

▲ peaks▼ valleys

Light pattern on pool floor

Try this: Click (1,0), then (0,1), then (1,1). Watch how each new mode adds a new layer of detail to the pattern. This is exactly what the presets do — "Ripple" is just those three modes plus a couple more.

How the Pattern Appears

  1. You pick which vibrations to mix by clicking modes in the grid (or choosing a preset, which picks a nice combination for you).
  2. The computer simulates the water surface — adding up all your chosen waves to figure out the shape of the water at every point.
  3. It calculates where light focuses. Where the water curves a lot, light gets bent and concentrated into bright lines. Where it's flat, it stays dim. This is what you see as the pattern.
  4. It mirrors the tile into a 4×4 grid, flipping alternating copies, so you can see how the pattern repeats seamlessly.

The Controls

Depth

How deep the "pool" is. Deeper water means the light has more room to bend, so caustic lines get sharper and more dramatic.

Brightness

How bright the caustic lines appear. Turn it up to make the lines pop, turn it down for a subtler effect.

Sharpness

Whether the lines are thin and crisp or soft and glowing. High sharpness = thin precise lines. Low = softer halos.

4-Fold Symmetry

When on, if you add mode (2,3), it also adds (3,2). This guarantees the pattern looks the same if you rotate it 90°, giving it that kaleidoscope quality.

Why It Tiles Perfectly

Each wave mode uses cosines: cos(m · x) · cos(n · y). A cosine wave is like a smooth hill that's the same on the left side as the right side — it's symmetric. So if you mirror-flip the tile, the wave at the left edge matches the wave at the right edge of the next tile. It's automatic. No matter what combination of modes you pick, the tiling always works.

A cosine wave (top) is symmetric around its peak. Mirror a tile, and the edges always match (bottom).

Mathematical Foundation

The tool computes caustic envelopes of a light field refracted through a parametric water surface, where the surface is constructed as a superposition of eigenmodes of the 2D wave equation on a square domain with Neumann boundary conditions.

Standing Waves on a Square Domain

For a square pool with side length L and perfectly reflecting (Neumann) walls, the eigenmodes of the wave equation ∇²h = (1/c²) ∂²h/∂t² are:

hmn(x, y, t) = Amn cos(mπx/L) cos(nπy/L) cos(ωmn t)

where ωmn = πc/L · √(m² + n²)

The Neumann condition ∂h/∂n = 0 at the walls is satisfied automatically by the cosine basis. The total surface height is:

h(x, y, t) = Σm,n Amn cos(mπx/L) cos(nπy/L) cos(ωmn t)

The amplitude normalization A_internal = A_slider · 0.15 / (m² + n²) compensates for the fact that higher-order modes have larger second derivatives per unit amplitude, ensuring roughly equal visual contribution to the caustic pattern across modes.

Caustic Computation via the Jacobian Determinant

For a planar light source (sun) at infinity, rays passing through a refractive surface with height field h(x,y) are deflected proportionally to the surface gradient. A ray entering at surface position (x, y) lands on the pool floor at:

x' = x + d · ∂h/∂x
y' = y + d · ∂h/∂y

where d is the effective depth (proportional to pool depth and refraction index)

The caustic intensity is the reciprocal of the Jacobian determinant of this ray mapping (x, y) → (x', y'). Where the Jacobian vanishes, rays converge to a point — infinite intensity in the geometric optics limit — producing a caustic.

J = | ∂x'/∂x   ∂x'/∂y |   =   | 1 + d · hxx    d · hxy   |
    | ∂y'/∂x   ∂y'/∂y |       |   d · hxy    1 + d · hyy |

det(J) = (1 + d · hxx)(1 + d · hyy) - (d · hxyCaustic intensity I = 1 / |det(J)|

The Hessian components are computed analytically from the modal decomposition:

hxx = -Σ Amn m² cos(mx) cos(ny) cos(ωt)
hxy =  Σ Amn m·n sin(mx) sin(ny) cos(ωt)
hyy = -Σ Amn n² cos(mx) cos(ny) cos(ωt)

(coordinates rescaled so L = π)
Baseline subtraction: Far from caustics, det(J) ≈ 1, so the raw intensity 1/|det(J)| ≈ 1 everywhere, producing uniform illumination. We subtract this baseline: I = 1/|det(J)| - 1, clamped to [0, ∞), so only the caustic peaks remain visible. The "brightness" parameter scales I, and "sharpness" applies a power-law remapping I1/γ where γ = 0.5 + 3s to control line width.

Why Mirror Tiling Is Seamless

This is the central insight connecting wave physics to tessellation geometry. Neumann boundary conditions on a square domain produce eigenfunctions in the cosine basis, which has even symmetry about each wall. Formally:

h(x, y) = h(-x, y) = h(x, -y)    (even reflection at each boundary)

Mirror tiling — reflecting the fundamental domain across its edges — produces exactly the same extension as the even periodic extension of the cosine series. The function and all its derivatives are continuous across tile boundaries, guaranteeing C seamlessness.

This is equivalent to saying the pattern lives in the p4m wallpaper group (when 4-fold symmetry is enabled) or pmm (when it's not). The fundamental domain is one tile; the group generators are reflections across the tile edges.

Neumann BCcos basis
(even symmetry)
HessianAnalytic 2nd
derivatives
Jacobiandet(I + d·H)
ray mapping
Caustics1/|det| - 1
bright lines
Mirror Tilepmm / p4m
wallpaper group

Rendering Pipeline

The entire caustic computation runs in a WebGL 2 fragment shader. Each pixel independently evaluates the modal sums for hxx, hxy, hyy, computes the Jacobian determinant, and maps the result to intensity. This is embarrassingly parallel and runs at 60fps even with 20+ active modes.

// Fragment shader pseudocode
for each mode (m, n, A, ω):
    a = A · 0.15 / (m² + n²) · cos(ω · t)
    Hxx += -a · m² · cos(mx) · cos(ny)
    Hxy +=  a · m·n · sin(mx) · sin(ny)
    Hyy += -a · n² · cos(mx) · cos(ny)

det = (1 + d·Hxx)(1 + d·Hyy) - (d·Hxy)²
I = clamp( (1/|det| - 1)1/γ · brightness, 0, 1 )

The shader outputs to a 512×512 tile canvas with preserveDrawingBuffer: true. A separate Canvas 2D context then copies this tile into a 4×4 grid using scale(-1, 1) and scale(1, -1) transforms on alternating tiles to achieve mirror reflection.

4-Fold Symmetry

When the 4-fold symmetry toggle is active, every mode (m, n) is paired with (n, m) at the same amplitude. Since swapping m and n in cos(mx)cos(ny) is equivalent to a 90° rotation (x ↔ y), this guarantees the surface — and therefore the caustic pattern — is invariant under the dihedral group D4. The resulting tessellation then belongs to the wallpaper group p4m rather than pmm.

Connection to Islamic Geometric Patterns

Traditional Islamic geometric patterns are constructed from circles and lines within a fundamental domain, then reflected and rotated to fill the plane — the same symmetry operations as our mirror tiling. The caustic lines produced by standing wave superposition are visually analogous to the interlacing lines of girih patterns: both are families of smooth curves governed by the same wallpaper group symmetries. The wave mode grid provides a physical parameterization of these symmetry-constrained line patterns.