Expand description
aquarelle — watercolor-style soft-bleed orb rendering on a
tiny_skia::Pixmap.
Originally written as the cel-anime night-scene texture set for the
orber abstract-mood-image generator,
the engine is independent of orber and only depends on
tiny-skia + palette + rand + rand_chacha. It takes a
center, radius, RGB color, and a u64 seed, and draws four
compositable elements onto a pixel buffer you already own.
§The four elements
- bleed — small same-color radial gradients scattered around the orb to fake a film grain / paper-bleed feel.
- bloom — a near-white core inside the inner ~30 % of the radius so the orb reads as a light source rather than a flat dot.
- offset — the gradient center is decoupled from the geometric center by up to 25 % of the radius. A perfectly concentric light source looks artificial; a slightly off-center one feels natural. The direction is seed-derived so calls are deterministic.
- halo — saturation of the outer falloff is boosted so the bleed reads as a film halation instead of a flat alpha fade.
Each is tunable in 0.0..=1.0 and they compose with source-over.
§Renderer-agnostic on purpose
aquarelle does not know what background is on the pixmap, what the rest of your scene looks like, or how you intend to encode the result. It just composites four watercolor layers onto the buffer you hand it. The caller decides the background fill, layout, and output format (PNG / WebP / SVG / animation frames / WebCodecs).
§Example
use aquarelle::{render_aquarelle_orb, AquarelleParams};
use tiny_skia::{Color, Pixmap};
let mut pix = Pixmap::new(128, 128).unwrap();
pix.fill(Color::from_rgba8(0, 0, 0, 255));
render_aquarelle_orb(
&mut pix,
(64.0, 64.0), // center
40.0, // radius
[200, 100, 50], // sRGB color
42, // seed (determinism)
AquarelleParams::default(),
);§Determinism
Identical (center, radius, color, seed, params) produce
byte-identical pixels. RNG state is seeded per call via
ChaCha8Rng::seed_from_u64(seed) and never touches thread_rng.
§Bleed pass (v0.2)
For callers that already have a rasterized image (e.g. ink lines on a
white background from blueprinter) and want to bleed the existing
pixels themselves, render_aquarelle_bleed_pass applies a
Gaussian-approximating box blur (3 passes) to the whole pixmap with a
halo saturation boost and a faint seed-derived paper-grain noise. The
original picture is then re-composited on top, so the bleed reads as
a halo underneath the existing strokes.
Structs§
- Aquarelle
Bleed Params - Knobs for
render_aquarelle_bleed_pass. All values are interpreted in their natural range and clamped internally; callers can pass raw slider values without pre-validation. - Aquarelle
Params - Intensities of the four aquarelle elements. Each value is interpreted
in
0.0..=1.0; out-of-range inputs are clamped internally so the caller can pass raw slider values without pre-validation.
Functions§
- render_
aquarelle_ bleed_ pass - Apply a watercolor bleed pass to an entire
pixmap. - render_
aquarelle_ orb - Composite one aquarelle orb onto
pixmapwith source-over blending.