Fractal Explorer: Deep Zoom in the Browser

Fractal Explorer: Deep Zoom in the Browser

A single-page WebGPU app for exploring escape-time fractals as an instrument rather than a renderer: pan, zoom, switch formulas, and remix colors while the image stays live — all the way down to zooms of 1e100, far past where ordinary floating point stops working.

A deep zoom into a spiral of a Mandelbrot-family fractal, rendered in cream, teal, and violet
A spiral at zoom 1e5, auto-tuned to 1,344 iterations. The status bar tracks reference state, precision digits, and render resolution.

The precision wall

Every pixel in an escape-time fractal is a question: how many iterations does this point survive before escaping? The catch is this point. A 64-bit float carries about 16 significant digits, so once you have zoomed by a factor of 1e13 or so, neighboring pixels collapse onto the same representable number and the image dissolves into blocks.

The classic fix — and the one this app uses — is perturbation theory. The CPU computes one reference orbit at the zoom center using arbitrary-precision arithmetic (a custom binary floating-point helper, with precision that tracks zoom depth at roughly one bit per octave). The GPU then iterates only each pixel's tiny delta from that reference in fast f32, with the shader's internal scale normalized to dodge f32 underflow. One slow, exact orbit; millions of cheap corrections.

For the polynomial family the deltas use scaled rebasing perturbation, which stays exact at all depths — even when the reference orbit escapes. Mandelbrot at any power, Julia, Burning Ship, Tricorn, Celtic, Phoenix, and Spider all get exact delta recurrences with explicitly tracked binary exponents, so a delta can be 1e−100 of a pixel one moment and grow to escape magnitude the next without losing its footing. The remaining formulas (Nova, Magnet, Lambda, Mandelbox, Barnsley, Glynn, Tetration) fall back to first-order perturbation below a scale threshold.

The reference orbit depends only on the center and the formula — not the zoom — so it survives across zoom levels and is recomputed only when you drift too far, change formula, or outgrow its precision.

Staying interactive at 1e100

Deep zoom is worthless if every frame takes a second. The renderer treats frame time as a budget:

  • While you interact, it measures GPU cost per pixel and renders whole frames at whatever resolution fits the budget — so zooming holds full frame rate even at 1e100, just softer.
  • When you stop, the view refines to full resolution in tiles radiating out from the zoom anchor, a budgeted batch per frame, so refinement never blocks the UI.
  • Antialiasing runs last, as a second tiled sweep (four subpixel samples per pixel) after the sharp image is already up. Turning it on never slows interaction; edges simply smooth themselves afterward.

Iteration counts tune themselves too: auto-iterations scales the limit with zoom depth — a stretched power law at shallow zooms blending into a quadratic in log₁₀(zoom) at depth, around 2,500 iterations at 1e40 and 5,600 at 1e94 — with the slider acting as a quality factor rather than a chore.

Everything is a URL

The full view state — exact high-precision center, scale, formula, dynamics, palette — serializes into the URL hash after each interaction. Any place you find, including a 1e100 zoom that took twenty minutes of wandering, can be bookmarked, shared, or restored by reloading. The screenshot above is a URL.

Fourteen formulas, one path

Mandelbrot, Julia, Burning Ship, Tricorn, Celtic, Phoenix, Nova, Magnet I, Spider, Lambda, Mandelbox 2D, Barnsley I, Glynn, and Tetration variants, each with only its relevant parameters exposed, plus palettes, gamma/exposure, and orbit traps. One WebGPU path — no WebGL fallback, no workers — which keeps the whole renderer small enough to reason about.

The lasting lesson from this build: the hard part of deep zoom isn't the math, it's the choreography — deciding what to compute precisely, what to approximate, and what to defer, so that a hundred orders of magnitude feel like dragging a map.