Expand description

Master branch online documentation is available at doc.icelk.dev.

Pipeline

First you need to get a Config. I suggest creating it like this:

let config = Config {
    iterations: 100_000_000,
    ..Config::poisson_saturne()
};

Multithreaded

Call render_parallel.

This benefits the most when the number of iterations is much higher than the dimensions of the image. The gap closes rapidly when the relation is < 25. This also consumes more memory, as we need a set of working images for each execution unit, usually the number of threads on your CPU. See Performance for more info.

Single-threaded

Create a Runtime. Then render and finally colorize.

Performance

The thing slowing the algorithm down with larger image dimensions is the cache size - and memory access. We basically do random access reads and writes on a often > 2 megapixel image. If the system memory is slow, this brings performance to a halt.

Colouring

When the iterations are executed, the magnitude of change is stored in a texture. When it’s time for colouring, this |Δp| is mapped to a palette. The brightness is determined by the number of visits to the pixel.

Re-exports

pub use config::ColorTransform;
pub use config::Colors;
pub use config::Config;
pub use config::RenderKind;
pub use config::View;
pub use primitives::EulerAxisRotation;
pub use primitives::FloatExt;
pub use primitives::Vec3;

Modules

The included attractors.
Configuration for rendering - how to get the next iteration, colouring, camera position, brightness, etc.
Mathematical primitives

Structs

Handle to threads and channels to render a config on multiple threads.
Stores data used by the algorithm.

Traits

A strange attractor.

Functions

Render according to config, with angle rotation around the attractor.
I recommend 16 for jobs_per_thread. If you get uneven images with low iteration counts, try 8.

Type Definitions

Convenience alias for an 16-bit RGBA image.