Building an Interactive Fractal Explorer
Three Challenges
The Lab generates Mandelbrot and Julia images with adjustable parameters and viewports. Interactive fractal explorers raise three useful engineering questions: performance, numerical precision, and progressive detail. The techniques below describe ways to address them; the current Lab uses CPU raster generation.
Select a point in the Mandelbrot field and follow the repeated calculation that decides its color.
Try it yourself
- Move c with the plane or the Re(c) and Im(c) controls.
- Scrub Orbit step n; compare c = 0, c = −1 and c = 0.5 with Im(c) = 0.
Watch: Each image pixel chooses c while z starts at zero. The orbit panel shows repeated squaring and addition; crossing radius 2 establishes escape. A finite unescaped sample remains inconclusive.
GPU-Accelerated Rendering
An escape-time iteration can run in a WebGL fragment shader. Each pixel computes its own iteration count independently, making the Mandelbrot set well suited to parallel GPU execution. Actual rendering time depends on the device, image dimensions, iteration limit and chosen region.
// Fragment shader (GLSL) — core iteration
vec2 z = vec2(0.0);
for (int i = 0; i < MAX_ITER; i++) {
if (dot(z, z) > 4.0) { iter = i; break; }
z = vec2(
z.x*z.x - z.y*z.y + c.x,
2.0*z.x*z.y + c.y
);
}Deep Zoom Precision
Precision becomes an issue at deep zoom levels when adjacent pixel coordinates become too close for the chosen numeric representation. Perturbation methods address this by computing a high-precision reference orbit on the CPU and expressing nearby pixels as small differences from that reference. This is an advanced rendering technique, not a feature of the current Lab generator.
Progressive Rendering
Progressive rendering can start with a coarse grid and refine it in later passes. This gives a viewer an early approximation while expensive detail is still being computed. Color mappings can then translate iteration values into a palette. These are design options for a fractal explorer; the current Lab renders its raster result as a completed image.
z₀ = 0.250 + (0.150)i
c = -0.800 + (0.156)i
zₙ₊₁ = zₙ² + cThis starting point escapes after 72 steps.
Moving the crosshair tests one starting point. Moving c changes the recurrence at every pixel. Dark areas are unescaped samples in this finite test.
Try this Choose c = 0. The filled Julia set is the unit disk: starting magnitudes below 1 shrink, and those above 1 grow. Move the crosshair to compare both.
Vary the constant c, then inspect an orbit in its Julia set. Here the starting point varies while c stays fixed.
Try it yourself
- Choose c in the small parameter plane or use its real and imaginary controls.
- Set c = 0 and move the crosshair inside and outside the unit disk.
Watch: The main image varies z₀ while every pixel uses the same c. Changing c reshapes the whole field; moving the main crosshair only selects an orbit to inspect.
Related Concepts
Related Artworks
Explore Related Sections
More about the work:
