Skip to content

BrightnessModifierModule

BrightnessModifierModule is a modifier — it generates a sine-wave pixel pattern whose amplitude is modulated by a brightness scalar it reads from the Key/Value Store each tick. Modifiers read from one source and write a modified version into their own EffectsLayer; they do not produce the primary effect, they alter it. This demonstrates cross-module communication via KvStore and multi-producer blending via DriverLayer.

Purpose

SineEffectModule publishes its current amplitude as a float under the key "brightness" after each loop(). BrightnessModifierModule reads that scalar and applies it as a multiplier to its own sine output. The two effects run at independent frequencies; their pixels are blended pixel-wise in a shared DriverLayer.

Controls

Key UI type Min Max Default Description
frequency slider 0 5 2 Sine wave spatial frequency
enabled toggle true When false, loop() is skipped

State is persisted to state/<id>.json across reboots.

Wiring

{
  "id": "brightness1",
  "type": "BrightnessModifierModule",
  "props": { "frequency": 2 },
  "inputs": { "layer": "<EffectsLayer id>" }
}

The module must be wired to a EffectsLayer before setup() is called. The KvStore key "brightness" must be published by another module (typically SineEffectModule) before loop() runs; if absent, a default of 1.0 is used.

KvStore dependency

Key Type Direction Default
"brightness" float read 1.0f

Published by SineEffectModule::loop(). Absent on the first tick if SineEffectModule has not yet run.

Multi-producer blending

To blend BrightnessModifierModule output with SineEffectModule output, wire both their EffectsLayers to a single DriverLayer using distinct input key names:

{
  "id": "consumer1",
  "type": "DriverLayer",
  "props": { "width": 16, "height": 16 },
  "inputs": {
    "source":  "<producer for SineEffectModule>",
    "source2": "<producer for BrightnessModifierModule>"
  }
}

DriverLayer.setInput accepts any key that begins with "source", allowing up to kMaxConsumerSources (8) producers to be wired via "source", "source2", … "source8".

Pixel formula

brightness = KvStore::instance().getFloat("brightness", 1.0f)
v          = sin(frequency * (x + y + tick))   // [-1, 1]
scaled     = brightness * (v + 1.0f) * 0.5f    // [0, brightness]
pixel      = (uint8_t)(scaled * 255.0f)

When brightness == 0 all pixels are black. When brightness == 1 the output is a full-range sine wave.

Test coverage

Brightness Modifier — frequency control, KvStore read, output scaling, multi-producer DriverLayer wiring.

Source