Stoatworks Labs

Photofinish

A photo-finish strip camera for Resolume

Betav0.1.0Plugin & ModuleC++ / GLSL
Photofinish — A photo-finish strip camera for Resolume
No screenshot — this one is configuration inside another application.

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, and the film moves past it, so the horizontal axis of its picture is time, not space. 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 is the whole plugin.

Nothing that follows is coded anywhere. An object b pixels wide, crossing the slit at v pixels per frame, photographed at c columns per frame, occupies b·c/v columns, and the effect's whole vocabulary is that expression at different speeds. Anything standing still becomes a horizontal streak, because it is 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 is not. 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: motion blur along the time axis, arrived at rather than added, which leaves the other axis untouched. 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 honest limit is that the plugin sees only 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 one frame was never over it in any frame the plugin was given. 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 honestly early. Every claim is checked against its closed form by an offline harness that drives the real plugin class in a headless GL context, and tools/verify.sh runs the lot against a fresh universal Release build: 99 assertions across twelve check suites, every tolerance derived from a lattice — one column, one row, one source frame, one 8-bit code value — rather than fitted to a rendered number. A moving object's rendered width matches b·c/v to within 0.016 of a column; an object at the film speed comes out at its own width to within 0.031 of a column at two resolutions, and one at twice the film speed at 0.5002 of it; a still picture renders as bitwise-constant streaks over more than two million samples at three rasters; the ring holds the right frames in the right order, bitwise; the same take from t=0 and from 499,217,238 ms is bit-identical; and the slit reads the column it says it does, bitwise, on both axes. Nine deliberately wrong models are all rejected, a one-character change to the shipped shader is caught, and all 13 controls measurably change the picture. Render cost on macOS is 0.17 ms/frame at 720p, 0.27 at 1080p and 0.96 at 4K. The bundle registers, instantiates and renders in the fleet's own oxbow host. It has not yet been loaded into Resolume on macOS. On Windows it has: a build of this source loads, registers and renders in Resolume Arena 7.27.1 on software rendering (win-lab, no GPU), with every parameter as declared; its time controls could not be shown moving on the gate's still picture, which a strip camera turns into identical streaks at any setting. It has never run on Intel or on a machine without a GPU. 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 is not aligned to the bar line. There is a browser demo, which is a port rather than the plugin; no factory presets and no OpenFX port. There is a user guide. Check it in your own rig before trusting it in a show.

Watch it running

Photofinish video thumbnail

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