Files
effector/src/effects/warp.hpp
T
SiandClaude Opus 5.5 ce3a422f6a Add eight effects that throw something chaotic into the chain
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>
2026-09-23 20:36:09 +02:00

28 lines
1.0 KiB
C++

#pragma once
#include "core/effect.hpp"
namespace effector {
// Pushes every pixel along a smooth random noise field: a haze at low strength,
// melted paint at high. The swirl mode follows the field's contour lines,
// which turns the image into eddies instead of ripples.
// 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 WarpEffect : public Effect {
public:
std::string name() const override { return "warp"; }
std::string title() const override { return "Warp"; }
std::string description() const override {
return "Pushes every pixel along a smooth random noise field, from a gentle haze to "
"molten eddies.";
}
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