Slit shift, channel split, pixel sort, corruption, shatter, warp, bit crush and feedback: tearing bands sideways, knocking the colour planes out of register, sorting runs of pixels, damaging blocks the way a broken stream does, breaking the picture into shards, pushing it along a noise field, mangling its bytes and laying it over itself again and again. All eight are pure transforms. None needs sources, so any of them can lead a chain, and like blur they start from a crop of a random source when they do and photographs are loaded. canvasFromSources holds that start once for them. Each draws its whole plan from the rng before touching a pixel, and pixel sort hands every line a seed of its own, so the parallel work never decides anything. The rotations in shatter and feedback take their sine and cosine from a short series of plain multiplications rather than libm, so a seed lands on the same pixels whatever the machine's maths library makes of std::sin. The tests hold every one of them to the same things -- a seed reproduces it, it runs without sources and as a later stage, a sliver of a canvas does not trip it, turned right down it leaves its input alone -- plus a check of what each actually does, and the registry now checks that no two effects declare the same param key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
27 lines
1020 B
C++
27 lines
1020 B
C++
#pragma once
|
|
|
|
#include "core/effect.hpp"
|
|
|
|
namespace effector {
|
|
|
|
// Tears its input apart: random bands of rows (or columns) are pushed sideways by a
|
|
// random distance each, the way a video signal loses its sync.
|
|
// A pure transform: it needs no source images, and leading a chain with
|
|
// sources loaded it starts from a crop of a randomly chosen one.
|
|
class SlitShiftEffect : public Effect {
|
|
public:
|
|
std::string name() const override { return "slitshift"; }
|
|
std::string title() const override { return "Slit shift"; }
|
|
std::string description() const override {
|
|
return "Tears random bands of its input sideways, like a video signal losing sync; "
|
|
"overlapping bands add their shifts up.";
|
|
}
|
|
const std::vector<ParamSpec>& params() const override;
|
|
bool needsSources() const override { return false; }
|
|
|
|
Image render(const std::vector<Image>& sources, int width, int height, Rng& rng,
|
|
const ParamValues& values) const override;
|
|
};
|
|
|
|
} // namespace effector
|