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. - Spiral
Bleed Params - 新「にじみ」(螺旋ブラー)の 4 軸パラメータ。各
0.0..=1.0。
Constants§
- AQUA_
BLEED_ WGSL - 共有「にじみ」WGSL フラグメント(48 タップ黄金角螺旋 + bloom/halo character)。
- AQUA_
BLUR_ TAPS - 螺旋ブラーのタップ数(WGSL
AQUA_BLUR_TAPSと一致)。 - AQUA_
GOLDEN_ ANGLE - 黄金角(rad、WGSL
AQUA_GOLDEN_ANGLEと一致)。値は orberorb.wgslと逐字一致させる (f32 の表現桁を超えるが WGSL/naga も同じ f32 に丸めるので値は一致=parity)。 - AQUA_
OFFSET_ BIAS - offset の disk 原点バイアス比(WGSL
AQUA_OFFSET_BIAS)。 - AQUA_
TAU - 2π(WGSL がホスト供給を前提とする
TAU=6.28318530718と同一 f32)。 - BLOOM_
MAX - bloom が白へ寄せる上限比(WGSL
BLOOM_MAX)。 - HALO_
SAT_ GAIN - halo の彩度ゲイン係数(WGSL
HALO_SAT_GAIN)。
Functions§
- aqua_
blurred_ coverage_ cpu - WGSL
blurred_coverageの CPU リファレンス。 - aqua_
character_ cpu - WGSL
aqua_characterの CPU リファレンス(ブラー後の色味補正。各軸0.0で恒等)。 - aqua_
hash21 - WGSL
hash21の CPU port。fractはv - v.floor()(f32::fractは符号付きで WGSLfractと異なるため使わない)。GPU の per-pixel ディザと同じ値を返す。 - aqua_
seed_ dir_ cpu - WGSL
aqua_seed_dirの CPU port。seed から決定論的な単位方向ベクトルを返す。 - 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.