Stoatworks Labs

Tinsel

Fairy lights round anything, for Resolume

Stablev1.0.7Plugin & ModuleC++ / GLSL
Tinsel — Fairy lights round anything, for Resolume
Figures from Resolume's own demo media with their outlines lit, rendered by the plugin's own offline harness in a headless GL context — not a Resolume screen capture. Real frames through the real shipped shaders.

What it does

An FFGL effect for Resolume Arena and Avenue. It finds the outlines in whatever's on the layer, hangs a string of virtual lamps along them, and runs the sort of pattern an LED controller runs. Point it at a logo and it turns into a neon sign, a theatre marquee or a Christmas tree.

It's built on the same idea as an LED controller: a pattern never picks a colour. It decides where in the palette each lamp sits and how bright it is, and the palette turns the first of those into RGB. That's why twenty patterns and sixteen palettes are worth more than thirty-six of either. Comet on Christmas is a red-and-green chaser, Comet on Frost is a shooting star, and neither is just the other one in a different colour.

It also makes a pattern a pure function of (lamp, time), with no state and no history, which is what makes it testable. The pattern library exists twice, once in C++ and once in GLSL, and because the GLSL is a fragment rather than a whole shader, the effect and the test are built around the same text. So the harness checks what the plugin actually runs, not a copy of it.

Lamp Size is a radius in pixels rather than a fraction of the lamp spacing, and that's the difference between lamps and streaks. The strip is a field whose gradient varies across the frame, so a window measured in strip units is a dot where the field runs fast and a smear where it runs slowly. Wind the same control past half the lamp spacing and the lamps merge into one continuous glowing rope, which gets you the neon-sign look from one control instead of a second mode.

There's an OpenFX version for DaVinci Resolve, Vegas Pro, Nuke and Natron too, with the same patterns, palettes and controls. The temporal stability filter is rebuilt from a short window of previous frames, so any frame renders the same however the host gets to it.

  • Twenty patterns — chase, theater chase, comet, meteor, Larson scanner, colour wipe, twinkle, sparkle, glitter, fire flicker, breathe, strobe, dissolve, colour waves, fairy lights and more
  • Sixteen palettes, from Christmas and Candy Cane to Frost, Fire, Ocean and Cyberpunk, plus two driven from your own two colours
  • Detect on luma, alpha, chroma or both — chroma finds the boundary between two colours of equal brightness, which a luma edge detector is completely blind to and brand artwork is full of
  • Lamp Size in pixels: separate bulbs at one end of the control, a continuous neon rope at the other
  • Five strip layouts — spiral, angle, linear, radial and a randomly wired order
  • A temporal filter tuned for footage, deliberately asymmetric so an outline that drops out for a frame does not blink
  • An Edges view that shows the detected mask on its own, which is how the edge controls are actually set
  • Universal macOS bundle, a Windows x64 DLL, and an OpenFX bundle for macOS, Windows and Linux
  • Eight factory presets, from Warm Twinkle to Cyber Larson, on a dropdown that holds until you edit a control it covers

Where it stands

Built, measured and released, and now on the 1.0 line at v1.0.7. 1.0.0 also put the Pattern and Palette dropdowns in alphabetical order without upsetting any saved composition, because FFGL stores the value behind a dropdown entry rather than its position. The OpenFX build for Resolve, Vegas, Nuke and Natron arrived in v0.2.0. The pattern library exists twice, in C++ and in GLSL, and an offline harness runs the shader at one pixel per lamp and compares it with the C++: 527,100 comparisons across every pattern, time, intensity and spread, with no disagreements. That check has already caught a GPU-only bug, where a float modulo returned the lamp spacing instead of zero at an exact multiple and put out the brightest lamp in the pattern. All 31 controls are swept and shown to change the picture. It costs 0.55 ms a frame at 1080p and 2.36 ms at 4K, about a seventh of a 60fps frame. Both the macOS universal bundle and the Windows DLL build in CI; v1.0.4's Windows installer no longer touches the system PATH (the earlier one could overwrite it), v1.0.5 gives the effect a proper description in the field Resolume shows for it, v1.0.6 put SW in front of its name there, and v1.0.7 fixed the OpenFX build on Resolve's Fusion page, where every render used to fail. Still open: it's never been loaded into Resolume, so how the controls present in the host is untested, and the OpenFX build has only been run as a tool on Resolve's Fusion page (Resolve Studio 21.1, macOS). The OpenFX build now ships for Linux too, proven to load on Rocky 8 in CI, and that load test caught it failing on an undefined pthread_create first. The FFGL plugin is macOS and Windows only. The strip coordinate is also a field rather than an arc length, so a chase climbs a shape the way a string wound round a tree climbs it, and doesn't follow a letterform round its own curve. Contour tracing is planned for the next version.

Watch it running

Tinsel video thumbnail

Nothing loads from YouTube until you press play.Watch it there instead