Skip to content

AuroraEffect

Source: AuroraEffect.h

AuroraEffect

class AuroraEffect
src/light/effects/AuroraEffect.h:31

Inherits: EffectBase

Effect: layered noise curtains in polar coordinates, each layer on its own oscillators.

Prior art: the shader vocabulary Stefan Petrick made recognizable in the LED world.

AuroraEffect card AuroraEffect controls

The shader idiom rather than a picture: no aurora is simulated. Layers of one field at different scales, moved by different oscillators, are composited. The interference between them reads as curtains folding through each other.

Public Attributes

uint8_t speed = 30 : Master rate: every layer's motion scales from this.

uint8_t scale = 40 : Noise cells across the grid. Low gives broad curtains, high gives fine detail.

uint8_t layers = 3 : How many fields are composited, and the main cost knob.

uint8_t warp = 60 : How far the field displaces its own sample angle.

uint8_t twist = 40 : How much the radius shears the angle, giving the curtains their lean.

uint8_t segments = 1 : Kaleidoscope fold. 1 leaves the composition unfolded.

uint8_t contrast = 140 : The visibility window. Higher gives fewer, sharper curtains.

uint8_t octaves = 2 : Detail within each layer, multiplying the cost knob.

PolarLut::Controls polar : The polar address: the table, its precision, and how a volumetric fixture maps to angle and radius.

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: the curtains have depth.

virtual inline void defineControls() override : Publish the layers, the field's shape, the visibility window and the polar address.

virtual inline void prepare() override : Build the polar address table for the current geometry.

virtual inline void tick() override : Composite every layer through the visibility window, one pixel at a time.

Public Static Attributes

constexpr uint8_t kMaxLayers = 4 : The compositing ceiling, and the width of the oscillator bank.

More info

Four power functions

PolarLut gives every pixel its angle and radius once, addressing the field around the center. OscillatorBank drives the motion, holding the layers' phases together so they keep their relationships. fbm8 over gradient noise is the field, giving each layer a broad shape and fine structure. A contrast window then decides what is visible, which is what separates a shader from a blur.

Palette and structure are separate

The strongest layer at each pixel wins, and its color comes from which layer won. So the palette controls the mood and the layers control the structure. Every palette gives a different aurora and none of them look wrong.

Cost: one fbm per layer per pixel, so layers is the cost knob and octaves multiplies it.