A multithreaded fractal renderer in Rust
The live wasm-compiled release is accessible here. Due to some rust wasm compiler limitations, the web version is single threaded and therefore slower than the native version
Navigate to the cloned repo and execute
cargo run --release
The Mandelbrot set is the set of complex numbers
Computationally, for every pixel of the rendering area, the above equation is iterated a fixed number of times, and a pixel color is associated with the rate of divergence of the sequence. Typically the black color is associated with a converging point (whose norm stays within some fixed threshold after the iteration count), and a coloring scheme is chosen to clarify the renderings
Multiple optimisations can be implemented to speed up the sequence interation. Choosing
Further, we can pre-compute
let mut z = Complex::zero();
let mut z_sqr = Complex::zero();
let mut iter = 0;
loop {
z.i = 2. * z.r * z.i + c.i;
z.r = z_sqr.r - z_sqr.i + c.r;
z_sqr.r = z.r * z.r;
z_sqr.i = z.i * z.i;
iter += 1;
if iter >= max_iter || z_sqr.r + z_sqr.i > escape_radius_sqr {
break;
}
}
For deep zoom levels, the number of iterations has to be increased to maintain an appropriate level of details, which makes for slower rendering time and reduces the exploration smoothness. Multistage rendering works by splitting up a rendering task in
Regardless of the number of stages, the rendering time is bounded to double the rendering time of the final stage.
The fractal rendering is trivially parallelizable, since every pixel color can be computed independently of each other. The renderer maintains a thread pool sharing the work at every stage by rendering a fraction of the stage's pixels. Every animation frame, the canvas pauses the threads execution and interleaves their pixel buffers onto the canvas buffer to smoothly display progress.
The iterator uses f64
to compute the complex series, which leads to numerical precision issues for deep zoom levels. Typically after a zoom multiplier of
The renderer can be compiled to wasm by installing and running wasm-pack
wasm-pack build --target web --release
The wasm
compiler doesn't support yet the std::thread
library, therefore a single thread is used on web. For other targets, the thread count is set automatically to the cpu count