Skip to content

FluidEffect

Source: FluidEffect.h

FluidEffect

class FluidEffect
src/light/effects/FluidEffect.h:28

Inherits: EffectBase

Effect: dye poured into a simulated fluid, carried by the flow the medium itself works out.

Prior art: Stam 1999, "Stable Fluids".

FluidEffect card FluidEffect controls

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.