If we plot the escape times for points in this complex plane series, we end up in a world of burning ships.
The largest ship is located on the real axis at -1.75.

y [-0.08000000, 0.01000000]
drag to panshift + scroll or pinch to zoom
World overview
If we consider an escape radius of 2, the world also has a radius of 2, since any points starting outside of the world diverge right away.

y [-2.20000000, 2.20000000]
The ships are located near the real axis (y = 0) among negative real numbers.

y [-1.00000000, 0.50000000]
Zooming in closer to the ships in the bottom left

y [-0.32000000, 0.03000000]
The ship near -1.6 between the largest ship and the dark expanse.

y [-0.07400000, 0.01800000]
Small ships near the edge of darkness

y [-0.05200000, 0.01400000]
Zoomed in to the small ship near -1.57

y [-0.04000000, 0.00600000]
Small ship and disorder near the expanse, with curving spires.

y [-0.06000000, 0.00500000]
Left of the largest ship are some very small ships. The light ends at (-2, 0)

y [-0.14200000, 0.07200000]
Zoomed in to a small ship near -1.94

y [-0.00950000, 0.00200000]
Burning ship fractal equation
The equation using complex numbers is this:
It's similar to the Mandelbrot equation:
Except instead of squaring each number, we add the absolute values of the real and imaginary components together during each iteration and square the sum instead.
z is a complex number composed of real and imaginary numbers:
Fractal images are generated by changing the value of c:
If we convert to using x and y, the burning ship fractal equation reduces to:
A common way of exploring fractals is by putting different starting (x0, y0) numbers into the equation and making note of whether the series:
- diverges to infinity or stays within a limit
- if the series diverges, we make note of:
- the number of iterations until reaching the escape radius
- the distance from zero (0, 0) during the escape
Sub-structures
Beyond the main fleet, the fractal is filled with bridges, spirals, lattices, and nested mini-ships. Zooming into the masts and surrounding filaments uncovers strange new shapes at every scale.
Overview
At shallow magnifications, every pixel runs its own independent escape-time loop inside a WebGL fragment shader using native 32-bit GPU floats.
The mast of the largest ship

y [-0.06710000, -0.04940000]
Distant view when approaching the expanse along the real axis near x = -1.5

y [-0.00296972, 0.00066197]
The left edge of the world near x = -2.0

y [-0.02000000, 0.02000000]
Axis spire
A tall, twin-tipped spire with flared crossbars rises above a glowing horizon of smaller towers, casting a faint reflection into the dark below.

Solar-eclipse crescent bay
A pitch-black bay along the upper shoreline of the largest ship is rimmed by a white-hot corona and horizontal rays of amber light.

Deep zoom
Once the viewport narrows past 10-7, single-precision float32 shaders lose subpixel spacing. These views step up to 53-bit significand float64 workers, WebAssembly SIMD loops, and double-float (df64) WebGPU shaders to keep filaments razor-sharp down to the 10-15 IEEE 754 precision floor.
Spiked window
A bright, spiked frame branches outward at its corners, with smaller windows repeating along its edges.

Four-lobed rosette
Four rounded lobes surround a dark center. Smaller flower-like forms repeat through the surrounding filaments.

Glowing grid
Fine parallel threads cross at a glowing grid, tucked into a tiny region near the western tip of the fractal.

Ribbon junction
Sweeping ribbons meet in a bright knot, with delicate branches tracing their diagonal paths.

Twin whirlpools
Two bright cores face each other amid dense, curling filaments that repeat around them.

Ember bridge
Nested luminous diamonds form a glowing bridge between broad dark chambers.

Crossed cutlasses
Two narrow, glowing blades cross at a shallow angle around a small dark diamond, set against a background of dark, ribbed lace.

Gilded causeway
Parallel threads and striped vertical piers stretch across the dark background like a suspension bridge lit up at night.

Lightning bridge
A bright diagonal arc bridges a grid of thorny filaments, splitting into glowing Y-shaped forks at either end.

Hourglass pagoda
Curving, ladder-like ribs pinch inward like an hourglass around a bright four-pointed heart, with tiered arches stacked above and below.

Four-ship armada
Four dark ships sail in formation along a glowing horizon, each topped with a tall, lacy mast and anchored by a diamond-shaped reflection below.

Floating gossamer crest
A bright, butterfly-winged emblem hangs across the dark, held in place by fine diagonal threads of lace.

Spiked monstrance
Eight thorny spokes radiate from a blazing, rectangular crown suspended in the dark.

Imperial pearl court
A single bright pearl glows inside a thorny square frame, flanked on either side by sweeping, ribbed arches.

Five-star suspension vault
Five bright, eight-pointed star lanterns are linked along a diagonal truss between sweeping, web-like cables.

Spiked diamond medallion
A blazing, spiked diamond ring surrounds a bright central star, while delicate, thorny branches weave a diagonal lattice across the surrounding dark.

Diagonal starfighter squadron
Dozens of glowing, cross-winged starships fly in tight diagonal formation along faint amber trails across the dark.

Branching lightning spine
A blazing vertical spine cuts through the dark, sending out angled, thorny crossbars at regular intervals.

Abyssal zoom
Down in these abyssal depths past 10-16, standard 64-bit numbers can no longer tell neighboring pixels apart, and running custom big-number math for every pixel would bring the browser to a crawl. Instead, the renderer uses perturbation theory: it traces a single high-precision reference orbit through the center of the frame and measures how surrounding pixels drift from that path, patching any seams where the equation's absolute-value folds crease the geometry.
Aurora minaret skyline
Pointed spires rise from a blinding horizon into soft amber curtains of light, casting faint reflections into the dark water below.

Solar prominence arcade
A blazing double arc curves down the left horizon while delicate, nested loops of light arch out into the surrounding dark.

Crown-of-thorns halo
A jagged ring of thorny filaments encloses a dark moat, with a white-hot star burning at the center.

Dragon-wing sunflower
Four sweeping, coral-like arms meet at a bright, petal-ringed wheel that divides the dark into four wide bays.

Beaded eight-ray pulsar
Eight straight rays—each strung with tiny, flower-like clusters—shine outward from a white-hot core into the surrounding dark.

Harp causeway
Along a glowing causeway in the lower left, a row of striped, fork-tipped towers rises into the dark like the strings and pillars of a harp.

Barred spiral galaxy
Hundreds of tiny, four-pointed stars orbit in nested oval rings around a blazing, tilted core.

Diamond-rail star span
Paired tracks of light arch outward from a blazing central star, with a chain of dark diamond cutouts set between the rails.

Cloverleaf corona
A tiny dark ship drifts at the center of a blinding circular halo, ringed by scalloped gold lace and dark, clover-shaped coves.

Falcon-arcade wings
A tiny dark ship sits at the heart of a glowing, web-ringed sun, while four tall, ribbed wings sweep toward the top and bottom of the frame.

Spiderweb-palace core
Scalloped threads spin a delicate cobweb around an eight-pointed star in the lower right, with diamond-patterned ribbons trailing away into the dark.

Sierpinski lightning truss
A white-hot burst in the lower left sends jagged, branching bolts diagonally across the frame, carving dark triangular gaps between them.

Spear-tip star core
Twin ribbons of light wrap around a blazing star on the left and draw together into a needle-sharp point on the right.

Floating three-eye crown
A glowing horizontal crown with three dark, diamond-shaped eyes floats isolated in the dark.

Ember sigil
Two parallel diagonal bands of bright, cross-shaped sparks mirror each other across a textured field of dark embers and cutouts.

Twin-wing torch
A bright diagonal core burns between two symmetrical, snowflake-lace wings against the dark.

Braided eyelet compass
An eight-pointed star in the lower left sits inside a ring of diamond eyelets, connected to ribbed, tower-like struts along the upper left and lower right.

Lightning star cross
Four jagged, triangular trusses cross at a blazing central cluster, reaching outward between wide dark bays.

Thorny reef medallion
A blazing oval medallion of lacy cells glows at the center where a fine horizontal thread crosses a wide diagonal lattice of thorny branches between two dark bays.

Star-kite constellation
A bright central star burns inside a tilted, kite-shaped ring of smaller four-pointed stars and snowflake-like clusters, set along a diagonal beam of amber light.

Celtic-knot arch bridge
A blazing core on the left sends a curved, thorny spine arching across a wide dark bay, surrounded by interlocking loops of golden lace.

Bowtie searchlight iris
A tiny dark ship sits at the center of a blinding bowtie flare, sending tiered beams of golden lace outward between two dark bays.

Spear-tip diamond court
Sweeping double-tracked rails curve around a blazing central cross, framing nested diamond eyelets to the left and right and V-shaped chevrons above and below.

Chthonic zoom
Here we descend impossibly deep, past the resolution limit of the physical world - Planck's constant: 10-34 - and the 10-38 underflow cliff where 32-bit floats collapse to zero. Beyond this limit, the engine pairs WebAssembly libmpdec arbitrary-precision decimals with 240-bit fixed-point Taylor series and detached-exponent perturbation math to keep filaments sharp without underflowing.
Suspended lantern tower
Ribbed towers reach in from top and bottom and flare out at the center into an eight-pointed, web-like lantern suspended between two dark voids.

Spiderweb cathedral
Sweeping, ladder-like arcs curve in from all four corners and meet at a glowing chain of tiny diamonds suspended over the dark.

Orbital girder oculus
Four arched, girder-like bridges converge on a glowing ring that frames a dark circular eye at the center.

Caustic prominence shoreline
A white-hot, jagged cliff meets a pitch-black sea, sending faint, arched ripples of light washing back across the amber shallows.

Parabolic plasma cascade
From a blinding crest near the top of the frame, nested arcs and jagged, thorny filaments pour downward like a waterfall of sparks.

Supernova ray-hub
Fine golden rays stream outward from a blinding oval core, ringed by dark, beaded shadow-spokes that reach into the surrounding ember dust.

Koch snowflake lagoon
A dark, star-shaped lagoon lies encircled by a glowing reef of crystalline, snowflake-like branches.

Snowflake plasma cross
Four glowing arms meet at a bright crossroads, with intricate, snowflake-like bastions filling each of the four corners.

Ember candelabra
A glowing candelabrum of branching crosses rises into the dark around a tiny black ship at its center.

Scalloped cobweb canopy
Two bright star clusters glow inside a mask-like arch near the bottom of the frame, while scalloped cobweb rings and double-tracked suspension cables fan outward across the dark.

Coral-lace chasm and twin knots
Two blazing oval knots glow within a dense thicket of coral-like lace on the right, while jagged, branching filaments reach diagonally across a dark chasm toward the upper left.

Sunburst eye mandala
Centered in the frame, a blazing tilted eye with a four-pointed star at its pupil radiates scalloped petals, diamond cutouts, and double-tracked ribs into the surrounding dark coves.

Figure-eight silk vortices
Two white-hot vortices glow at opposite ends of a figure-eight chamber, wrapped in sweeping contours of amber silk and dark, scalloped lace.

Fractal coloring
Escape time
Given a starting point (x0, y0), we can give each point a color by calculating the number of iterations it takes for the series to diverge, and the distance from zero when escaping.
const ESCAPE_THRESHOLD = 4;
const MAX_ITERATIONS = 255;
function iterateUntilEscape(x0, y0) {
let x = 0, y = 0;
let numIterations = 0;
while ((x*x + y*y < ESCAPE_THRESHOLD) &&
(numIterations < MAX_ITERATIONS)) {
const x_next = x*x - y*y + x0;
const y_next = 2*Math.abs(x*y) + y0;
x = x_next;
y = y_next;
numIterations++;
}
return [numIterations, x*x + y*y];
}We'll set the RGBA colors of every pixel in the image based on the number of iterations. Here's an example of a fiery yellow/red color palette by scaling just the green and alpha values of each pixel. This simple mapping clips to the same yellow above 36 iterations, hiding differences in the brightest areas.
function getColor(numIterations) {
return [
255, // red
numIterations * 7, // green
0, // blue
numIterations * 15 // alpha
];
}Here's a general function for drawing fractals onto canvas elements. Changing the iterateUntilEscape function will change the drawn fractal.
function drawFractal(canvasEl, xRange, yRange, getColor) {
const canvasWidth = canvasEl.width;
const canvasHeight = canvasEl.height;
const context = canvasEl.getContext('2d');
const canvasImageData =
context.createImageData(canvasWidth, canvasHeight);
const image = canvasImageData.data;
for (let i = 0; i < canvasHeight; i++) {
for (let j = 0; j < canvasWidth; j++) {
const x0 = xRange[0] +
j*(xRange[1] - xRange[0]) / canvasWidth;
const y0 = yRange[0] +
i*(yRange[1] - yRange[0]) / canvasHeight;
const [numIterations, escapeDistance] =
iterateUntilEscape(x0, y0);
const pixelIndex = 4*i*canvasWidth + 4*j;
if (numIterations !== MAX_ITERATIONS) {
const mu = normalizedIterationCount(
numIterations, escapeDistance
);
const pixels = getColor({ numIterations, mu });
for (let p = 0; p < 4; p++) {
image[pixelIndex + p] = pixels[p];
}
}
}
}
context.putImageData(canvasImageData, 0, 0);
}Here's the largest ship colored based on number of iterations alone.

y [-0.08000000, 0.01000000]
To eliminate color banding, we can compute a normalized iteration count (μ) that subtracts a double-logarithmic fraction of how far past the escape radius the point landed, turning discrete iteration steps into a smooth, continuous gradient.
const ESCAPE_RADIUS = 2;
function normalizedIterationCount(
numIterations, escapeDistance
) {
const logDistance = 0.5 * Math.log(escapeDistance);
return numIterations + 1 -
Math.log(logDistance) / Math.log(ESCAPE_RADIUS);
}Here's the same image with smooth escape counts and an expanded yellow palette. The original fiery brightness stays intact, while clipped highlights spread from saturated yellow through lemon to pale yellow and ivory. Colors stay stable as you pan and zoom.

y [-0.08000000, 0.01000000]
Nebulabrot
While escape-time coloring only cares how long a point takes to escape, a Nebulabrot tracks every step along the way and brightens pixels that get visited the most. Adapted from the Buddhabrot technique for the Mandelbrot set, it layers three orbit-density histograms by mapping fast, medium, and slow-escaping trajectories to red, green, and blue color channels.
Tracing those paths fills the dark hull of the largest ship with blue light and dusty golden sails.

y [-0.08000000, 0.01000000]
Pulling back from the largest ship shows an ethereal line of ships along the real axis, leading toward a tall cloud of blue light at the edge of the main expanse.

y [-0.18200000, 0.08800000]
Deep inside the main dark expanse near (0, 0), where escape-time renders show only empty space, we now see glitchy desert dunes.

y [ 0.05000000, 0.65000000]
Further down and to the right inside the dark interior, a row of blades curve out of a bright white glow.

y [-0.43000000, -0.01000000]
Fractal rendering
Zooming deeper into the fractal crosses several hardware number limits. Each time a floating-point format runs out of significand bits to separate neighboring pixels—or runs out of exponent bits and underflows to zero—the renderer switches its coordinate representation and orbit math to keep the image sharp.
| Zoom level | What happens | How the renderer adapts |
|---|---|---|
| Overview 100 to 10-6 | 32-bit GPU floats (float32, 24 significand bits) easily distinguish neighboring pixels. | Runs a direct escape-time loop per pixel in a single-pass WebGL fragment shader (255 iterations), with a 2D canvas worker pool for fallback and Nebulabrot accumulation. |
| Deep zoom 10-7 to 10-15 | float32 loses subpixel spacing, quantizing smooth curves into staircase blocks. | Promotes the camera to decimal strings, scales the iteration budget with depth (up to 20,000), and switches to paired-float (df64) WebGPU shaders and 64-bit (float64) WebAssembly SIMD workers. |
| Abyssal zoom 10-16 to 10-38 | 64-bit float64 (53 significand bits) can no longer tell adjacent pixel coordinates apart, though small pixel offsets still fit in hardware floats. | Traces one high-precision reference orbit through the center of the view and evolves per-pixel deltas with perturbation theory and 4th-order Taylor series, repairing absolute-value fold seams with local anchor orbits and 240-bit fixed-point (fp240) WASM. |
| Chthonic zoom 10-38 to 10-300 | 32-bit floats underflow to zero at 10-38, and 240-bit fixed-point runs out of fractional bits past 10-45. | Detaches a shared binary exponent (FloatExp) so GPU perturbation deltas stay scaled near 1, while reference orbits and seam repairs step up to multi-limb fixed-point WASM and C libmpdec arbitrary-precision decimals. |
| The darkest depths 10-300 and below | 64-bit JavaScript Number underflows to zero near 10-308, collapsing standard floating-point pixel deltas. | Replaces floating-point pixel spacing with rational offsets over multi-thousand-digit decimals and extracts rescaled FloatExp mantissas straight from fixed-point BigInts alongside libmpdec WASM workers. |
To render past 10-16 in real time, the engine relies on perturbation theory: instead of running slow arbitrary-precision math for every pixel, it traces a single high-precision reference orbit through the center of the view and tracks each pixel's tiny offset from that path in fast hardware floats. When the absolute-value fold causes a pixel's path to split away from the central orbit across zero, the renderer adds extra local reference points to keep the image free of seams.
To keep navigation responsive while deep frames compute, the canvas reprojects the previous frame during pan and zoom gestures, draws a quick low-resolution preview before filling in full detail, and only antialiases sharp edges.
Jacobian skew
In the Mandelbrot set, each step of the equation scales and rotates space evenly in every direction, so deep mini-sets and spirals keep their natural proportions at a 1:1 aspect ratio. In the Burning Ship, taking absolute values folds the plane across the axes on each step. As an orbit bounces through those folds, space gets stretched along one direction and squished along the other.
Because of this uneven stretching, most deep mini-ships, rings, and spirals away from the main axes look squashed into thin diagonal streaks. By tracking how much an orbit stretches space in x and y (its Jacobian matrix) and applying the opposite stretch to the camera, we can unskew the view and reveal the shapes hiding inside the streaks:
Armada rigging mini-ship
High in the rigging east of the largest ship, repeated folds stretch this mini-ship 13× along a steep diagonal, flattening its hull into a thin dark slit. Unskewing the view restores the upright ship and the radial web of arches around it.


Eastern sail sunflower crown
Inside the upper-right eastern sail, a ring of filaments is stretched nearly tenfold into diagonal streaks of fire around a narrow splinter. Unskewing opens those streaks into a circular eight-petalled flower framing a tiny central ship.


Scalloped medallion ring
Deeper in the rigging, twenty-three steps of folding compress a circular medallion almost 9× into a dense wall of diagonal stripes. Unskewing reveals eight heart-shaped bays and concentric scalloped rings around the center.


About
All fractals on the page are interactive and rendered when they're in view. Every image can be expanded into full-screen mode using the button in its bottom-right corner. Full-screen views also display live complex-plane coordinates and let you undo camera steps or reset to the starting view.
As you zoom deeper, each canvas automatically switches to more sophisticated rendering pipelines to stay fast and avoid pixelation. Shallow views run per-pixel escape loops in 32-bit WebGL fragment shaders.
Zooming past 10-7 switches to 64-bit WebAssembly workers and double-float WebGPU shaders. Beyond 10-16, the renderer switches to perturbation theory and arbitrary-precision decimal math so you can keep zooming without losing detail.
Fractal image controls when hovering
- shift + scroll zoom in/out
- pinch zoom in/out
- click + drag pan the view
- cmd + z undo the last camera action
- fullscreen button / esc enter or exit full-screen mode
- cmd + \ toggle zen mode in fullscreen
Source code

