just another mandelbrot explorer, focused on performance, written in rust
Create an Issue
or
Request a Feature
mandelbrust renders the Mandelbrot set at extreme depth using perturbation theory. Instead of iterating each pixel from scratch (which breaks down past ~10^15 zoom because double precision is not enough), it computes one high-precision reference orbit and then perturbs every other pixel relative to it using plain f64 math. Arbitrary depth at per-pixel cost that stays roughly the same whether you are at 1x or 10^100x.
The reference orbit uses arbitrary-precision fixed-point (configurable up to 256-bit or higher). Per-pixel deltas stay tiny, so f64 is fine. Glitch detection with automatic rebasing keeps things accurate when a pixel's delta drifts too far from the reference.
CUDA is optional. Compile with --features cuda and it will use your GPU if
available, otherwise falls back to CPU via Rayon with a hybrid GPU+CPU split.
The CUDA kernel compiles at runtime from source (NVRTC), no build script or
static linking needed.
- perturbation theory rendering for arbitrary zoom depth
- arbitrary-precision fixed-point reference orbit (configurable bits)
- f64 per-pixel delta iteration (always fast, never loses precision)
- glitch detection with automatic rebasing
- 13 color palettes (electric, deep-space, fire-ice, nebula, mono, viridis, ocean, sunset, cyberpunk, aurora, pastel, lava, rainbow)
- 3 normalization modes (power gamma curve, linear spread, classic banded)
- 6 named presets (cardioid, spiral, deep, elephant, snowflake, triple)
- optional CUDA GPU acceleration via NVRTC runtime compilation
- hybrid GPU+CPU rendering (default splits 80/20)
- parallel CPU rendering via Rayon
- benchmark mode with timing breakdown
- auto-named output files
- progress bar with ETA and throughput in Mpix/s
- smooth iteration count (
n + 1 - log2(log(|z|)))
mandelbrust [preset] [options]
No arguments defaults to the spiral at 100x zoom, 1920x1080, 1000 iterations.
mandelbrust spiral at 100x, 1080p
mandelbrust deep -w 3840 -i 15000 4K deep zoom
mandelbrust spiral --bench timing breakdown
mandelbrust spiral --norm classic banded coloring
mandelbrust --list-presets named locations
mandelbrust --list-palettes available palettes
Flags:
| flag | what |
|---|---|
-x, --re |
center real coordinate |
-y, --im |
center imaginary coordinate |
-z, --zoom |
zoom level |
-w, --width |
image width |
--height |
image height |
-i, --iter |
max iterations |
-o, --output |
output file (auto-named if omitted) |
-p, --palette |
color palette name |
--norm |
normalization: power, linear, classic |
-b, --bits |
fixed-point precision in bits |
--bench |
benchmark mode (high iter, no save) |
--quiet |
suppress all output except errors |
--cuda |
force GPU-only (requires --features cuda) |
--cpu |
force CPU-only (requires --features cuda) |
--list-presets |
show all named locations |
--list-palettes |
show all color palettes |
- cardioid - the main cardioid at 1x
- spiral - seahorse valley spirals at 100x
- deep - deep spiral minibrot at 10^14x
- elephant - elephant valley filaments
- snowflake - dendritic patterns
- triple - three intertwined spirals
- power - gamma curve, emphasizes low iterations (default)
- linear - even spread across the iteration range
- classic - banded modulo-50 coloring, retro look
Palettes: electric, deep-space, fire-ice, nebula, mono, viridis, ocean, sunset, cyberpunk, aurora, pastel, lava, rainbow
cargo build --release
cargo build --release --features cuda # with GPU supportThe CUDA feature requires the CUDA toolkit (nvrtc). On Arch: pacman -S cuda.
On Ubuntu: apt install nvidia-cuda-toolkit.
The standard Mandelbrot renderer iterates Z_{n+1} = Z_n^2 + C for each pixel until it escapes. At deep zoom, C values for adjacent pixels are nearly identical, and double precision can not distinguish them anymore.
Perturbation theory computes one reference orbit at high precision (fixed-point BigInt), then for each pixel tracks only the delta dz_n = Z_n(pixel) - Z_n(reference). The delta stays small enough for f64 even at extreme zoom. When the delta grows too large relative to the reference (glitch detection), it rebases by absorbing the current pixel value into the reference and restarting from iteration 0.
The smooth iteration count uses n + 1 - log2(log(|z|)), mapped to palette
colors through the chosen normalization.
GPLv3