WaterRippleEffect
Source:
WaterRippleEffect.h
WaterRippleEffect¶
src/light/effects/WaterRippleEffect.h:30Inherits:
EffectBase
Effect: a propagating water surface where drops ripple, reflect and interfere.

Drops land and their rings spread outward, reflect off the edges and cross each other. The crossing is what a formula cannot fake, since two rings meeting have to add and cancel.
Prior art: Hugo Elias's water surface algorithm, the standard demoscene form.
Public Attributes¶
uint8_t speed = 60
: Simulation steps a second, which is how fast the water itself moves.
uint8_t dropRate = 24
: How often drops land, where 0 leaves the surface still.
uint8_t damping = 16
: How fast waves lose energy, so higher is calmer water.
uint8_t strength = 200
: How hard a drop hits.
bool colorByHeight = true
: Color the surface by height rather than by brightness alone.
uint8_t hueBase = 140
: Where in the palette the still surface sits.
uint8_t hueSpread = 110
: How far a crest and a trough reach from that.
Public Methods¶
virtual inline const char * tags() const override
: Catalog tags: this effect is the power-function showcase.
virtual inline Dim dimensions() const override
: Writes the z=0 slice, which extrude fills through a volume.
virtual inline void defineControls() override
: Publish the wave's speed and damping, the drops, and how height takes color.
virtual inline void prepare() override
: Size both height fields to the grid and reset the drop and step clocks.
virtual inline void tick() override
: Land any due drop, advance the surface on its own clock, then render it.
More info¶
The wave equation, discretized¶
Keep the surface height at this step and the previous one. The next height is the four neighbors averaged, minus the previous height, damped toward zero. That one line is the wave equation, so the ripple is emergent rather than drawn.
RipplesEffect draws expanding rings from a closed-form radius instead. That one is cheaper and always looks like clean circles, where this behaves like water.
Cost is two int16 buffers sized to the grid, and four neighbor reads a pixel a frame. The memory scales with the fixture, so a large wall is worth checking against the budget. Drop placement uses hashInt, so two devices put drops in the same places.