Stoatworks Labs

Porthole

Fisheye and defish for Resolume

Field provenv1.0.6Plugin & ModuleC++ / GLSL
Porthole — Fisheye and defish for Resolume
The repo's geometry test card through the default equidistant lens, rendered by the plugin's own offline harness in a headless GL context — not a Resolume screen capture. The grid shows the shape of the distortion, the rings confirm the map stays radial, and the frame stays full.

What it does

A lens projection warp for Resolume Arena and Avenue. Every output pixel stands for a ray at some angle off the optical axis. The lens model says where a ray at that angle lands on the image, and the picture is resampled to match. That's a different thing from bending the picture until it looks about right.

So the Projection control picks which lens rather than how strong. The slider is one continuous family that passes exactly through the five projections that have names: rectilinear, stereographic, equidistant, equisolid and orthographic. Everything in between is a proper projection too.

Three behaviours come out of modelling it that way without anyone adding them. Rectilinear does nothing at all, at any field of view, because a flat picture re-photographed through a flat lens is the same picture. Defish exactly undoes fish, because it's the same formula with source and destination swapped. And the frame always stays full, because the reference radius is a fixed point of the map: only the inside is redistributed, so the strength control changes the character of the warp instead of shrinking the picture into a black field.

There's no wet/dry mix, on purpose. Cross-fading two different geometries double-exposes the picture rather than easing between them, and Field of View at zero is already the null, where every projection agrees.

It's also an OpenFX plugin for DaVinci Resolve, Vegas Pro, Nuke and Natron. The OpenFX build links the same lens-family code the shader is measured against, so both hosts warp identically, and rectilinear stays a byte-for-byte identity in either.

  • Projection — one continuous family through rectilinear, stereographic, equidistant, equisolid and orthographic
  • Field of View up to 178°, which is the strength: at zero every projection agrees and nothing happens
  • Defish — the same lens run backwards, to take an existing fisheye picture flat again
  • Chromatic aberration modelled separately from distortion, growing with the square of the radius the way real glass does
  • Fit (diagonal, width, height or stretch), off-centre optical axis and two stops of zoom either way
  • Edge handling — transparent, black, clamp, mirror or wrap — and 1, 4 or 16 samples per pixel on a rotated grid, because a wide fisheye minifies its outer band hard
  • Universal macOS bundle, a Windows DLL, and an OpenFX bundle for macOS, Windows and Linux

Where it stands

Built, measured and released, and now on the 1.0 line at v1.0.6. The OpenFX build for Resolve, Vegas, Nuke and Natron, and the fix for the plugin failing to instantiate in the host, both arrived in v0.2.1. Since then, v1.0.2 fixed factory presets snapping straight back to Custom in Resolume (the host restates its own values, and the plugin was reading that echo as an operator taking over), v1.0.3 added a Linux OpenFX build, load-tested on a stock Rocky 8, v1.0.4 only changed the Windows installer, which no longer touches the system PATH (the earlier one could overwrite it), v1.0.5 gave the effect a proper description in the field Resolume shows, and v1.0.6 only changed the name Resolume lists it under, now "SW Porthole", so the Stoatworks plugins sit together in its browser. A warp is handy to test, since where a pixel went is a number rather than a matter of taste: the GLSL agrees with an independent C++ version of the same maths across 120 combinations to 0.6 of an 8-bit level (the test ramp's quantisation, not the maths), the fish-to-defish round trip lands within 0.001 of a level at moderate settings, 16 of the 64 combinations are too extreme to judge and say so rather than claiming a pass, and all ten parameters change the output. It's since been run inside Resolume on real content. Still open: performance has never been measured, and although Windows binaries are built and shipped in the release, the plugin has only been used in Resolume on macOS.

Watch it running

Porthole video thumbnail

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