Flenser
A liquid light show, for Resolume

What it does
A liquid light show is two watch glasses clamped face to face with a few millilitres of oil, water, alcohol and dye between them, sitting on the stage of an overhead projector. The lamp's underneath, the lens is on top, and the operator squeezes the glasses and lets the heat do the rest. It's the look of a 1967 ballroom and of every Optikinetics Solar rig since, and it's one of the few effects here that was a physical thing before it was a shader. Flenser models the physics rather than the appearance, and four behaviours follow from that.
The colour is subtractive, and that's most of the difference. Every cell is a dye filter, so light going through two of them gets multiplied twice: cyan over magenta is blue, cyan over yellow is green, and all three together are nearly black. Nearly every blob effect adds instead, and adding is what makes them look like lava lamps: the crossings come out white and the whole picture reads as glowing plastic. Here the crossings are darker than the cells that made them, and a different colour.
Every cell's edge is a lens. The meniscus at an oil-water boundary is the only part of the wheel doing any serious optics: it shifts what's behind it, splits it slightly by wavelength, and throws a bright caustic just inside a dark rim. The middle of a cell is flat oil between two flat glasses and bends next to nothing, which is why the refraction here is a band round the edge rather than a whole-cell distortion. Take the dye out altogether (Saturation at zero, which is clear water) and every mark left on the picture is that.
It comes in two versions. Flenser is a source: the wheel with its own lamp behind it, a Fresnel hot spot, a colour temperature and a round gate you can open out to full frame or close down to the clock glass it started as. Flenser Lamp is an effect that puts your clip where the lamp was, so your footage is what shines through the oil, gets dyed by it, and bends at every meniscus. Both share the same eight presets, from Overhead Projector through Ink in Water to Alcohol Burn.
Everything is a pure function of position and time, with no feedback buffer, accumulator or frame history. That limit's there for a reason: any frame renders on its own, scrubbing shows the wheel at that moment instead of restarting it, and the GLSL half of the model can be measured against the C++ half, which is what the OpenFX build runs. The one exception is Simmer, a bounded feedback buffer that leaves a trail behind a moving cell. It's in the Resolume build and not the OpenFX one, because a host that renders frames out of order can't match its own preview with one.
It also builds as OpenFX plugins for DaVinci Resolve, Vegas Pro, Nuke and Natron, a generator and a filter in one bundle, on macOS, Windows and Linux, driven by the same Oil.cpp.
- Two plugins from one model — the wheel on its own, and the wheel with your clip as its lamp
- Subtractive dye: overlapping cells multiply, so two colours crossing go darker and change hue
- Six dye sets — the food-colouring pack, the subtractive primaries, the hot end only, continuous, duotone and mono
- Merge takes the wheel from separate hard-edged beads to pools joined by a proper meniscus fillet
- A meniscus at every cell edge: refraction, chromatic dispersion, a dark rim and a bright caustic
- Churn deforms the cells as a fraction of the noise's own wavelength, so it cannot fold the field however hard it is driven
- A projector behind the glass — Fresnel hot spot, tungsten-to-halide colour temperature, and a round gate that switches off cleanly at the top of its travel
- Four ways to meet the clip: project through the oil, lay the lit oil over it, or take only its brightness and let the dye supply the colour
- Simmer, a feedback trail that cannot run away — a ceiling rather than a gain (Resolume only)
- Eight factory presets, shared by all four plugins from one table
- Universal macOS bundle, a Windows x64 DLL, and OpenFX builds for macOS, Windows and Linux
Where it stands
Released at v0.1.6. The last two point releases changed nothing in the Resolume picture: v0.1.5 put SW in front of both names in Resolume's browser, and v0.1.6 fixed the OpenFX build on Resolve's Fusion page, where every render used to fail. What's checked is checked properly, by a harness driving the real plugin in a headless GL context. The model exists twice, in GLSL for the GPU and in C++ for the OpenFX build, and the two agree to within 5e-4 across 1,625,010 values covering every control. Both builds leave a picture untouched when the wheel is clear (0 of 230,400 bytes different through the Resolume build, 0 of 921,600 through the OpenFX one in a probe host), all 33 controls reach the picture in both bundles, and the eight presets hold up against three different host behaviours in both. Building it the wrong way first caught two bugs that both looked plausible on screen: a rim drawn from the merged field instead of each cell's own boundary, which turns a dozen cells into one flat shape with a single outline round the pile, and a churn measured as a distance rather than as a fraction of the noise's wavelength, which folds the field and turns every cell into a nest of contour lines. Still open, and it's the important bit: as of v0.1.2 both Resolume plugins load and register in Arena 7.27.1 on Windows, on a machine with no graphics card, which says the plugin is correct and nothing about how fast it is. In Resolve it's only been run on the Fusion page (Resolve Studio 21.1, macOS), where v0.1.6 renders and the generator animates, and two of the defects fixed before v0.1.2 were found by somebody running it on a real rig, not by any measurement here. The measurements above run the plugin directly or run the OpenFX bundle through a probe. The Resolume build has never been loaded on macOS, the Windows OpenFX build has never rendered in a host, and the Linux one is only proved to load on Rocky 8 by a dlopen and two entry-point calls, which isn't a render. Nothing has been through a show.
Watch it running
Nothing loads from YouTube until you press play.Watch it there instead