LUMA
User Guide

Define Patterns

How to build reusable, venue-portable light behaviors using Luma's visual node graph editor.

Step 4: Define Patterns

Patterns are the heart of Luma. They are reusable, venue-portable light behaviors defined as visual node graphs. If you have used Unreal Engine Blueprints, Blender shader nodes, or TouchDesigner, the concept is similar: you connect processing nodes with wires to build data flow pipelines that transform inputs (beats, audio, spatial position) into outputs (dimmer values, colors, movement).

The Signal: Luma's Core Data Type

Before diving into node types, you need to understand the Signal -- the fundamental data type that flows through the graph.

A Signal is a 3D tensor with three dimensions:

DimensionNameMeaning
NSpatialOne value per fixture in the selection. If you have selected 10 fixtures, N = 10. If your pattern does not care about individual fixtures (e.g., a single color for everyone), N = 1.
TTemporalTime samples across the pattern's duration. For animated effects, T might be 256 or more steps. For static values, T = 1.
CChannelData channels per sample. For a dimmer signal, C = 1 (just brightness). For a color signal, C = 4 (red, green, blue, alpha).

Think of it as a spreadsheet: rows are fixtures, columns are time steps, and each cell can hold multiple values.

Broadcasting

Broadcasting is key to how Signals work together. When you combine two signals of different sizes, the smaller one automatically expands to match:

  • A color signal with N=1 (one color for all fixtures) combined with a dimmer signal with N=10 (per-fixture brightness) will apply that same color to all 10 fixtures, each at their individual brightness.
  • A signal with T=1 (constant over time) combined with a signal with T=256 (animated) will repeat the constant value at every time step.

This is the same broadcasting concept used in NumPy and PyTorch, if you are familiar with those.

The Pattern Editor

The pattern editor presents a visual canvas where you place nodes and connect their ports with wires. Each node has:

  • Input ports (left side) -- Data flowing in
  • Output ports (right side) -- Data flowing out
  • Parameters (on the node body) -- Configuration knobs and settings

Data flows left to right. You wire an output port of one node to an input port of another to pass data between them.

Building a Pattern: Walkthrough

Here is a complete example of building a simple beat-synced dimmer hit from scratch.

Goal: All fixtures flash on every beat with a sharp attack and linear decay -- a classic "4 on the floor" pulse.

Every pattern starts with a Beat Clock and Audio Input node already on the canvas. You do not need to add these.

1. Add a Beat Envelope node

Connect Beat Clock's "Beat Grid" output to Beat Envelope's "Beat Grid" input. Set the envelope parameters:

ParameterValueEffect
Subdivision1Trigger on every beat
Attack0Instant rise to peak
Decay1Linear fade over the full beat
Sustain0No hold
Release0No tail

This produces a sawtooth shape: the signal jumps to 1.0 on each beat and ramps linearly down to 0.0 by the next beat.

2. Add a Select node

Set the tag expression to all. This targets every fixture in the venue.

3. Add an Apply Dimmer node

Connect the Select output to Apply Dimmer's "Selection" input, and the Beat Envelope output to Apply Dimmer's "Signal" input.

That is the complete graph. Three nodes (plus the two auto-added inputs), two wires. The result: every fixture in the venue flashes to full brightness on each beat and fades to black by the next beat.

Advanced Technique: Spatial Chases

A spatial chase is when lights activate in sequence across physical space -- like a wave of light sweeping from left to right across the room.

The key insight is combining a time signal with a spatial position signal so that each fixture hits its peak at a different moment:

  1. Select (tag: all) outputs a Selection.
  2. Get Attribute (attribute: rel_x) reads the Selection and outputs a per-fixture signal where each fixture gets a value from 0.0 (leftmost) to 1.0 (rightmost) based on its physical X position.
  3. Time Ramp connected to Beat Clock creates a signal that counts up by 1 for each beat.
  4. Math (subtract) -- Subtract the spatial position (from Get Attribute) from the time ramp. Each fixture now has a time-shifted version of the ramp. The leftmost fixture (position 0.0) sees the ramp unchanged. The rightmost fixture (position 1.0) sees the ramp delayed by one unit.
  5. Modulo (divisor: 1.0) -- Wraps the subtracted value to 0-1, creating a repeating sawtooth wave per fixture.
  6. Falloff (width: 0.3) -- Turns the broad sawtooth into a narrow pulse. Each fixture now has a sharp pulse that hits at a different time.
  7. Apply Dimmer -- Connect the Select output and the Falloff output.

Result: A wave of light that sweeps across your fixtures in spatial order, repeating every beat. Because it uses rel_x (relative X position), it automatically adapts to any venue layout. Eight fixtures or eighty -- the chase just works.

Variations

  • For circular chases, use angular_position or angular_index instead of rel_x.
  • For vertical chases, use rel_y.
  • Adjust the Falloff width to control how wide the pulse is -- a narrow width creates a sharp spotlight effect, a wide width creates a broad wave.

Advanced Technique: Music-Reactive Colors

Chord-Driven Color

  1. Audio Input feeds into Harmony Analysis, which outputs a 12-channel chroma signal.
  2. Harmonic Palette maps the chroma probabilities to colors. When the music plays a C major chord, the output shifts toward red. A D chord shifts toward orange. The transitions are smooth because the chroma values are probabilistic, not hard switches.
  3. Apply Color sends the result to your fixtures.

Kick-Drum Reactive Strobes

  1. Audio Input feeds into Stem Splitter to separate the drums.
  2. The Drums output feeds into Frequency Amplitude set to the kick drum range (20-100 Hz).
  3. The amplitude signal drives Apply Dimmer or Apply Strobe for kick-synced intensity.

Harmonic Tension as Energy

  1. Harmony Analysis feeds into Harmonic Tension, which outputs a 0-1 "tension" value.
  2. High tension (complex chords, key changes) drives brightness, strobe rate, or movement speed.
  3. Low tension (clear major/minor chords) creates calm, gentle lighting.

Advanced Technique: Moving Head Choreography

Tracking a Point Orbiting the Room

  1. Orbit generates circular X, Y, Z coordinates (set center, radius, speed).
  2. Select targets fixtures with has_movement.
  3. Look At Position computes per-fixture pan and tilt angles so every moving head aims at the orbiting point.
  4. Smooth Movement limits the pan/tilt speed so heads move gracefully instead of snapping.
  5. Apply Position sends the smoothed pan/tilt to the fixtures.

Random Position Jumps on Each Beat

  1. Beat Envelope triggers on each beat.
  2. Random Position generates a new X, Y, Z target each time the beat envelope value changes.
  3. Look At Position computes pan/tilt for the new target.
  4. Apply Position sends the result.
  5. Apply Speed can freeze the heads between beats (connect a binary signal: 0 during sustain, 1 on beat hit).

Pattern Arguments

Patterns can expose configurable arguments -- parameters that appear when you place the pattern on a track's timeline. This makes a single pattern infinitely reusable.

Argument TypeWhat AppearsUse Case
ColorA color pickerThe same "Beat Pulse" pattern can be red, blue, green, or any color
ScalarA number sliderControl speed, intensity, width, or any numeric parameter
SelectionA tag expression fieldLet the user choose which fixtures to target each time the pattern is placed

To use pattern arguments, add a Pattern Args node to your graph. Define the arguments you want to expose (name, type, default value). The Pattern Args node's outputs become signals you can wire into the rest of your graph -- for example, wire a Color argument output into a Gradient node's color input.

When you later annotate a track, each annotation provides specific values for these arguments: a particular color, a particular intensity, a particular tag expression.

For a complete list of every node type, see the Node Reference.

Next Steps

With patterns defined, you are ready to annotate your tracks -- placing patterns on a timeline, layering them, and setting blend modes to choreograph your light show.

On this page