Grain is the third effect and the second that declares needsSources()
false, so it works as a filter stage in a cascade and can also lead one,
filling the canvas from a source the way blur does. Its knobs are the
amount a grain may push a pixel, the grain size in pixels, whether the
channels are drawn apart into coloured grain, and whether the response is
weighted towards the midtones — which it is by default, since film grains
least where it is least exposed. That last one means grain over an empty
canvas stays black unless the weighting is turned off.
Determinism comes from the same shape the scanlines effect uses: the
whole grain field is drawn serially from the Rng into one cell per grain
before any threading, and only the integer pixel arithmetic afterwards
runs under parallelFor.
The canvas fill blur used to keep to itself moves to
effects/source_fill.hpp unchanged, now that two effects want it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fills the canvas from one source, tiling it when it is smaller, then
applies a separable box blur repeated `passes` times to approximate a
gaussian. Params: radius, passes, direction and first_source, so the CLI
flags and the GUI widgets come out of the ParamSpecs as usual.
All random values (source index and crop offset) are drawn serially
before the parallel pixel work, so a seed reproduces the image exactly;
the box window clamps at both ends and the radius is clamped to the
canvas so an oversized radius cannot read out of bounds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Port of the Python prototype to C++20 with a CMake build:
- effector_core: GUI-free static library (effects, image IO via gdk-pixbuf,
declarative param specs, registry, portable seeded RNG, thread helper)
- scanlines effect: plans strips from the seeded RNG, then copies pixels in
parallel with memcpy and doubling horizontal tiling
- gtkmm 4 interface: native file dialogs, widgets generated from the param
specs, coalesced background renders, preview as a GDK memory texture
- CLI: flags generated from the effect registry, headless rendering with no
display required
- ctest suite covering the RNG, registry, effect geometry and image round trip
The Python prototype is kept under python-reference/.