Stoatworks Labs

Photofinish

A photo-finish strip camera for Resolume

Betav0.1.0Plugin & ModuleC++ / GLSL
Photofinish — A photo-finish strip camera for Resolume
Photofinish

What it does

An FFGL effect for Resolume Arena and Avenue. A photo-finish camera has no two-dimensional frame. It has one column of sensor with the film moving past it, so the horizontal axis of its picture is time. Photofinish points that column, the slit, at your clip, samples it once per tick onto a ring of stored columns, and lays the ring out across the picture in time order. That's the whole plugin.

Nothing that follows is coded anywhere. An object b pixels wide, crossing the slit at v pixels per frame and photographed at c columns per frame, takes up b·c/v columns, and everything the effect does is that expression at different speeds. Anything standing still becomes a horizontal streak, because it's the same column written over and over. Anything moving is stretched or squashed by one over its speed. Something crossing at exactly the film speed comes out at its true proportions, which is why the winner looks normal and the crowd behind is smeared. And something crossing the other way comes out mirrored, the famous backwards runner, because its leading edge reaches the slit first and lands at the older end of the strip.

The one control that looks like an exception is Slit Width, and it isn't one. A slit wider than a pixel averages across the direction of travel, and since that direction is time in the output, the average is over the time an object takes to cross the slit. That's motion blur along the time axis, which comes out of the model rather than being added, and it leaves the other axis alone. A strip shorter than the picture is magnified in blocks rather than smoothed, because two neighbouring columns are two instants, and a blend of them is a moment nobody photographed.

Time Per Column is the film speed, from 0.5 ms to 500 ms, and the only rate in the plugin. Sync can instead make one whole sweep take a beat or a bar of Resolume's tempo. The slit can be moved, widened, leaned and turned to run down the picture rather than across it. The strip scrolls, builds up in place behind a marching seam, or fills once and holds, over black, the live clip or transparency.

The catch is that the plugin only sees the frames the host hands it. When the film runs faster than the frame rate, the columns in between are blended from the frames either side, and anything that crosses the slit in less than a frame was never over it in any frame the plugin got. FFGL has no way to ask for another.

  • A strip camera, not a warp: one column sampled per tick onto a ring, with the streaks, stretching and mirroring as consequences
  • Film speed from 0.5 ms to 500 ms per column, or one sweep per beat or bar
  • A slit you can move, widen from 1 to 64 pixels, lean to 45° and turn to run down the picture
  • Direction, to choose which way of travelling comes out mirrored
  • Scroll, Build with a marching seam, or fill Once and hold
  • Sub-frame columns blended between host frames, or nearest-frame for hard steps
  • A clock that survives days into a session, checked bit-for-bit at 499,217,238 ms
  • Universal macOS bundle and a Windows x64 DLL

Where it stands

v0.1.0, and early days. It hasn't been loaded into Resolume on macOS yet. On Windows it has: a build loads, registers and renders in Resolume Arena 7.27.1 on software rendering (no GPU), with every parameter as declared, but its time controls couldn't be shown moving on the host check's still picture, which a strip camera turns into identical streaks at any setting. The bundle also registers, instantiates and renders in the fleet's own oxbow host. Everything is checked against its closed form by an offline harness driving the real plugin class, and tools/verify.sh runs the lot against a fresh universal Release build: 99 assertions across twelve suites, with every tolerance derived from one column, one row, one source frame or one 8-bit code value rather than fitted to a result. A moving object's width matches b·c/v to within 0.016 of a column, a still picture renders as bit-for-bit constant streaks, the same take from t=0 and from 499,217,238 ms is bit-identical, nine models broken on purpose are all rejected, a one-character change to the shipped shader is caught, and all 13 controls change the picture. Render cost on macOS is 0.17 ms a frame at 720p, 0.27 at 1080p and 0.96 at 4K. It has never run on an Intel Mac or on any GPU but Apple Silicon's. The host's clock unit is inferred rather than observed, and Sync has only seen a synthetic 120 bpm. It sets a rate, not a phase, so a sweep isn't aligned to the bar line. There's a user guide and a browser demo, which is a port rather than the plugin, but no factory presets and no OpenFX port. Try it in your own rig before you trust it in a show.

Watch it running

Photofinish video thumbnail

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