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 (colors, movement, strobes).

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 scalar signal, C = 1 (a single value). 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 scalar signal with N=10 (per-fixture values) will apply that same color to all 10 fixtures, each scaled individually.
  • 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 flash from scratch.

Goal: All fixtures flash white 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 Gradient node

Connect the Beat Envelope output to the Gradient's "Signal" input. The default gradient maps 0 to black and 1 to white, which is exactly what we want: full white on the beat, fading to black.

3. Add an Apply Color node

Connect the Gradient output to Apply Color's "Signal" input. Apply Color receives the fixture selection automatically from the pattern's Selection argument (see Pattern Arguments below) -- you do not need to add a selection node to the graph.

That is the complete graph. Three nodes (plus the two auto-added inputs), two wires. The result: every fixture targeted by the pattern's selection argument flashes to full brightness on each beat and fades to black by the next beat. Apply Color automatically derives brightness from the color -- white means full on, black means off.

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. Get Attribute (attribute: rel_x) reads the pattern's fixture 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.
  2. Time Ramp connected to Beat Clock creates a signal that counts up by 1 for each beat.
  3. 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.
  4. Modulo (divisor: 1.0) -- Wraps the subtracted value to 0-1, creating a repeating sawtooth wave per fixture.
  5. 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.
  6. Gradient -- Maps the narrow pulse to a color (black at 0, white at 1).
  7. Apply Color -- Connect the Gradient 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. Apply Color derives brightness from the color automatically -- white is full on, black is off.

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 a Gradient (black to white) into Apply Color for kick-synced flashes (white = full on, black = off), or directly into Apply Strobe for kick-synced strobe.

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 color intensity (brighter colors), 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. Look At Position computes per-fixture pan and tilt angles so every moving head aims at the orbiting point (using the pattern's selection argument to know which fixtures to target).
  3. Smooth Movement limits the pan/tilt speed so heads move gracefully instead of snapping.
  4. 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 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
SelectionA group expression fieldChoose which fixtures to target each time the pattern is placed. This is the primary way fixtures are selected -- there is no "select" node in the graph.
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

Every pattern has a Selection argument by default. This is how you target fixtures: when you place the pattern on a timeline, you write a selection expression like front_wash, floor_ring & ~dj_booth, or all. The pattern's Apply nodes automatically receive the resolved fixture selection.

To add additional arguments, use a Pattern Args node in 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 group expression, a particular color, a particular intensity.

Pattern Preview

When browsing patterns in the Track Editor's pattern registry, you can hover over any pattern to see a live 3D preview. Luma pre-renders the pattern into a sequence of frames using your venue's current fixture layout and displays them in a miniature visualizer. This lets you see exactly what a pattern looks like before placing it on the timeline.

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