FluidEffect
Source:
FluidEffect.h
FluidEffect¶
src/light/effects/FluidEffect.h:28Inherits:
EffectBase
Effect: dye poured into a simulated fluid, carried by the flow the medium itself works out.
Prior art: Stam 1999, "Stable Fluids".

Fluid solves the medium, and light/fluid.h says why that algorithm and why Q16.16. Jets pour velocity and dye together, so light enters where the medium is being pushed. [draw::advect16] then carries the dye along the finished field and [draw::decay16] fades it.
Public Attributes¶
uint8_t jets = 2
: How many places light is poured in.
uint8_t force = 120
: How hard each jet pushes.
uint8_t swirl = 90
: How fast the jets sweep, which is what rolls up vortices.
uint8_t viscosity = 20
: How much the medium drags on itself.
uint8_t persistence = 150
: How long dye survives, as a half-life.
uint8_t iterations = 5
: Pressure-solve effort, and the cost knob.
Public Methods¶
virtual inline const char * tags() const override
: Catalog tags: this effect is the power-function showcase.
virtual inline Dim dimensions() const override
: Volumetric: a medium per slice, with the jets wandering in z.
virtual inline void defineControls() override
: Publish the jets, the medium's viscosity, the dye's half-life and the solver's effort.
virtual inline void prepare() override
: Size the medium, both dye planes and the dither error, clearing them when the shape changed.
virtual inline void tick() override
: Pour the jets, solve the medium, then carry the dye along the field it worked out.
inline std::size_t dyeSamples() const
: Test seam: how many dye samples both planes hold, since a rendered frame cannot show a stale plane.
inline uint16_t dyeAt(std::size_t i) const
: Test seam: read one dye sample across both planes, where past the end reads 0.
Public Static Attributes¶
constexpr uint8_t kMaxJets = 4
: The jet ceiling, and the width of the oscillator bank.
constexpr uint8_t kClocks = 4
: per jet: position, reach, aim, depth
More info¶
Cost is the honest problem¶
The solver is several passes over the grid a frame, and the pressure solve is iterations of them. So this is a desktop and P4 effect, and an S3 runs it on a small grid. The numbers per target are in performance.md rather than promised here.
The dye plane is 16-bit¶
A value multiplied by slightly less than one, many times a second, has nowhere to go at 8 bits. That is the same reason Trails carries a wide plane, and the two share the idiom.