Skip to content

RipplesEffectModule

A 2D radial sine-wave ripple effect. Writes animated concentric coloured rings into a EffectsLayer each loop(). Introduced in Release 3, Sprint 1.


What it does

On each loop() call, RipplesEffectModule draws a single dancing sine-wave curve across the 2D pixel grid. The algorithm is a direct port of MoonLight's 3D Ripples effect projected onto a 2D display:

d       = |x − width/2| / 9.899495 × height
phase   = d / ripple_interval + time_interval
y       = floor(height/2 × (1 + sin(phase)))

For each x column exactly one pixel is lit at the computed y row. The buffer is cleared to black each frame so only the wave curve is visible. Colour cycles through a hue wheel over time (HSV, saturation and value at full), giving the wave a shifting rainbow colour similar to MoonLight's palette sampling.

Ripples effect demo


Controls

Parameter Source Default Description
layer setInput("layer", ...) EffectsLayer* to write into; width/height come from the layer
speed setProps / loadState 50 Animation speed (0 = stopped, 99 = fast)
interval setProps / loadState 128 Wavefront spacing — low = tight ripples, high = wide rings (1–255)
enabled auto (StatefulModule) true When false, loop() is skipped

layer is a data-flow input wired by the ModuleManager before setup() via the "inputs" field in state/modulemanager.json. speed and interval are persisted controls saved to state/<id>.json.


Platform notes

Uses sqrtf, sinf, fmodf. The module owns no pixel memory — allocation is in EffectsLayer. On ESP32, the FPU handles the per-pixel float math; ripple_interval and time_interval are hoisted out of the inner loop so only sqrtf + sinf run per pixel.


Test coverage

Live pipeline: test1 — Ripples pipeline — full DriverLayer + GridLayout + EffectsLayer + RipplesEffectModule pipeline verified on PC and ESP32; non-zero checksums asserted each run.

Source