2023.08.27·Lighting & power

Altar of Oba The code behind a pillar of light

664 addressable pixels on three buses, a Raspberry Pi at fifty frames a second, and one decision that made all of it tractable: the code never addresses a pixel, it addresses a place on the sculpture.

Altar of Oba stood in Black Rock City in 2023, a piece built with lead artist Dipo Doherty that paid homage to the ancient Benin culture and served as a pillar of color and light for the ideas that embody Afrofuturism.

My role was lighting and power. Dipo's vision was already there in the panels; the job was to give it a second life after dark, in light that answered the color he had painted rather than washing over the top of it. What follows is how that was actually built.

The eyes

The signature fixtures were made rather than bought: custom acrylic iridescent eyes, four of them, eleven inches across, two per face. Each carries two rings of the same diameter at different depths behind the acrylic, a 45 pixel iris and a 30 pixel ring of whites. Iridescent acrylic is a difficult material to light. It changes what it does depending on where you stand, so the trim had to read across the open playa and still leave the acrylic something to do up close.

In software an eye opens the way an eye opens. Both rings light only below a threshold that climbs through the eye's own bounds, so the lit area creeps up the circle like a lid lifting, holds at the top, then runs back down. While that happens the flood lights at the base fade out, moving the attention off the sculpture and onto the thing looking at you. It is about ten lines of geometry, and it only works because of the next part.

The prototype on the shop wall. The acrylic is doing most of the work; the ring behind it is only telling it what color to be.

A model of the pillar, in feet

The controller builds the sculpture before it builds a single effect. Twelve feet tall, two and a half wide, two deep, flaring a foot wider at the top and bottom corners, all of it in feet rather than pixel indices. Each of the four edge runs then places its 90 pixels along that outline at equal spacing, so a pixel's position in software is where its counterpart actually sits on the piece. The model knows what it cannot see, too: each five meter run left a tail of strip tucked inside the top, and those eight pixels are a named hidden segment, excluded on purpose rather than by accident.

On top of that sits a naming layer. One long run snakes through the structure, but nothing downstream ever says "pixels 42 through 21 of the right hand run." It says the top right of face A. Ranges compose into bigger ranges, so there is a name for a side, a face, a third of the height, both faces at once, all four eyes, just the irises, everything. Runs installed backwards are declared backwards once, in the model, and never thought about again.

A hand drawn design sheet: the pillar in elevation with its painted panels and two eyes, dimensioned 12 feet tall, 2.5 feet across the top and 4 feet 5 inches across the foot, beside a second drawing of the LED run marked in color bands, pinks and blues at the top, blues through the middle, greens and yellows at the foot
The sheet the numbers came from. The strip layout on the right is where the color bands were decided, months before any of it ran.

Color taken off the panels

A great deal of care went into the palette. Seven colors drive the whole piece, taken from the panels themselves: a green, a yellow, a red, a blue, a lighter blue, a pink and a purple. Every effect draws from that list, so the light complements the bold choices already on the piece rather than competing with them, and brings the whole thing back to life after dark.

The stripe patterns go further and give the pillar's three horizontal bands their own palettes, because the panels do not use one palette top to bottom either. Pinks, purples and a red through the top third. Blues and a lighter blue through the middle. Yellow, green and red at the foot. The bands scroll, so the piece reads as one object whose color story changes with height, rather than a tube with a rainbow running up it. Where patterns overlap, the blend weights toward the brighter of the two and keeps the brighter value rather than averaging them down. Two lights add. Two paints do not.

The pillar lit at night on the open playa, its edges outlined in green and red light, two large eyes glowing on the painted face, a spotlight at its foot and the lights of Black Rock City low on the horizon
The same palette on the piece itself, Black Rock City, 2023. Green and red on the trim, the panels answering underneath.

Effects written in space

Because every pixel knows where it is, an effect can be a shape rather than a sequence. The clearest case is the helix: a curve spirals around the pillar just outside the corners, each pixel works out how far it sits from that curve at its own height, and brightness falls off as the cube of the distance. Nothing is drawn onto the strips. A lit object orbits the sculpture and the sculpture samples it. Four can run at once, two spinning each way, blended per pixel. The same effect crosses both faces, rides through the flare and lands on the eyes with no special case for any of them, which is what the model was for. Twenty three effects are built this way.

Two altars, one real, one in shadow

A thirty three item playlist runs the show on a loop, each item naming an effect, how long it holds, and how it gives way to the next. The transition machinery is the part I would keep in any future piece.

The controller builds the model of the pillar twice. One copy is what the sculpture is showing. The other is a shadow, and the incoming effect renders onto it in full, as though it were already playing. A transition merges the two pixel by pixel, and when it finishes the shadow is promoted and becomes the live one. The effect that was running in the dark never knew it was in the dark.

So transitions are geometry, three or four lines each. A wipe upward is a height threshold that climbs. A wipe from the center is the band around zero widening. A wipe downward is the same test flipped. Add a cosine to the climbing threshold and it overshoots and settles, and that is a different transition. Six exist, none longer than a paragraph, and no effect anywhere contains a line of transition code.

role lighting and power lead
artist Dipo Doherty, lead artist
where Black Rock City, Burning Man 2023
fixtures 4 custom iridescent acrylic eyes, 11in, fully addressable LED trim
pixels 664: 360 edge trim, 180 iris, 120 eye whites, 4 floods
buses 3 off one Raspberry Pi: 2 × PWM GPIO, 1 × SPI for the eyes
software Python, 23 effects, 6 transitions, a 33 item playlist
frame rate 50fps target, threaded output, per stage timing

664 pixels, three wires

The output side is where the elegance stops and the Raspberry Pi starts having opinions. A Pi has only so many pins that can clock WS281x timing reliably, so the pixels leave on three buses: face A and its two floods out one pin, face B and its two floods out another, and all 300 eye pixels on the SPI line, because that was the third channel available and the eyes were the run that could not afford to stutter. The eyes also arrived with their red and green swapped relative to the trim, being a different batch, so they carry their own channel order in the mapping. One line of code, and about an hour of standing in the dust wondering why the irises were wrong.

The open controller case on a workbench: a 12V 400W waterproof LED driver mounted in the lid, and in the body a Raspberry Pi with a rainbow ribbon cable, terminal blocks, a converter and the runs leaving through sealed glands in the wall
The whole of it. A 12V 400W driver in the lid, the Pi and its terminal blocks in the body, and every run leaving through a gland because the desert gets into anything left open.
What is in the controller box: mains into a 12V 400W sealed driver in the lid, which feeds a converter down to 5V for a heatsinked Raspberry Pi and feeds the terminal blocks for power. Three runs leave through sealed glands: face A on GPIO 18 and face B on GPIO 21, 182 pixels each of edge trim and floods, and the eyes on SPI MOSI at GPIO 10, 300 pixels of irises and whites
One box, three runs. Power down one side, data down the other, 664 pixels at the bottom.

Clocking that many pixels out is the real frame budget, not the maths. The next frame is built while the last one is still going down the wire, on its own thread, and the loop times each stage separately and prints them every tenth frame. The target is fifty frames a second and it takes what it can get.

Keeping it lit

The most useful thing I learned here has nothing to do with pattern design, and it cost most of an evening to find.

The rest is desert insurance. It runs as a system service that restarts on failure and comes up on boot, so the piece recovers from a power cut without anyone climbing it, and every start writes its own timestamped log. If a write to the pixel bus fails, the controller shuts every channel to black rather than leaving half a frame stuck on the strip: dark on purpose beats frozen. Development ran on the same code, with a 3D simulator on a laptop and stand-ins for the display and the pins when the hardware libraries are absent. A file watcher restarts the process whenever anything changes, which makes the loop on site: edit on the laptop, sync to the Pi, look up.