Vertigo
The dolly zoom, for Resolume

What it does
An FFGL effect for Resolume Arena and Avenue. A dolly zoom is a camera move and a lens move arranged to cancel out: the camera tracks along its own axis while the focal length changes to hold one surface at the size it already was. That surface stays put, everything at any other distance moves, and it reads as the ground giving way rather than as a zoom. Hitchcock's cameraman worked it out for a stairwell in 1958 and it's been the shorthand for vertigo ever since.
It's a depth effect, and a video clip has no depth, so the question that matters is where the depth comes from. There are two quite different answers. Radial makes up a field: near on the optical axis and falling away to the frame corners, or the other way round. Nothing's read out of the picture, so the geometry is a closed form with no failure cases that doesn't care what's in the clip. It works on any footage at all, and what you get is the look of the shot. Luma and Alpha read a field out of the clip instead. Given real depth (a rendered depth pass, a matte, or a generated depth map baked into a channel) it does the actual reprojection, and the picture comes apart in depth the way the real move does. Given an ordinary clip it turns brightness into geometry, which is either a mistake or an effect depending on the clip.
The model's written in disparity rather than depth, and that's what makes it safe as well as tidy. Written in depth, the magnification has a pole where the camera reaches a surface. Written in disparity, with the field normalised to between nought and one and the dolly kept below one by construction, the denominator is always positive. There's no divide-by-zero guard anywhere in the plugin, and there doesn't need to be one for any setting a host can throw at it.
Two of its behaviours are exact, and both are measured. The anchor surface doesn't move at any dolly setting: it's measured at nought travel while the rest of the frame travels a fifth of the frame. And a scene with no depth is the identity. A dolly zoom on a painted backdrop does nothing however hard you drive the camera, and the maths works that out without being told. The browser demo has a preset for each, so you can check both without installing anything.
It also builds as an OpenFX plugin for DaVinci Resolve, Vegas Pro, Nuke and Natron from the same model. The dolly maths is compiled into both builds from one file rather than written twice.
- The real dolly-zoom reprojection, in disparity, with no pole for any setting a host can produce
- Radial depth invents its field and works on any clip — closed form, one texture fetch, no holes
- Luma and Alpha depth read a real field out of the picture, solved for with three fixed iterations per sample
- The anchor surface holds still at any dolly setting, measured at nought travel
- Two exact nulls: no camera move, and a scene with no depth — either returns the picture untouched
- The Dolly control is geometric in the parallax ratio, so equal travel either side of centre gives reciprocal shots
- Relief goes signed: past the middle it turns the depth inside out, which is the stairwell shot rather than the subject shot
- Smooth blurs the depth field and not the picture — an inverse-mapped parallax smears at a depth step rather than tearing, and softening the step is the repair
- Overscan buys back the frame that a push in gives away, with five edge modes for what shows past the picture
- Seven factory presets, from Vertigo through Stairwell to Slam
- Universal macOS bundle, a Windows x64 DLL, and an OpenFX build for macOS, Windows and Linux
Where it stands
Released, and now at v0.1.7. The three point releases since didn't change the picture: v0.1.5's Windows installer no longer touches the system PATH (the earlier one could overwrite it), v0.1.6 gives the effect a proper description in the field Resolume shows for it, and v0.1.7 shows it as SW Vertigo in Resolume's browser so the Stoatworks plugins sit together, with the ID a composition refers to unchanged. It runs in Resolume Arena: it was loaded and confirmed working on 2026-08-17, the day v0.1.0 shipped. The Windows build has had real use too. An operator has been running it on Windows 11, and the first thing they reported (factory presets seeming not to stick, because Resolume doesn't act on the value events a plugin raises and keeps pushing its own values back down) was fixed in v0.1.2. The harness drives the real plugin class in a headless GL context: the GLSL matches a separate C++ version across 180 parameter combinations to within nine tenths of an 8-bit level, the anchor surface holds at nought travel across 55 combinations while the rest of the frame moves a fifth of the frame, and the depth-map path's fixed-point solve matches the same solve in double across 45 more. All twelve controls are swept and shown to reach the picture, and the browser demo's copy of the shader is compared with the plugin's character for character. One bug worth owning up to got through the first of those checks and not the second: the relief control was scaling the depth field about the anchor rather than about the middle of its range, so it did nothing at all over half its travel, and the GPU and the C++ agreed perfectly on the same wrong answer. Still open: it's never been loaded into Resolve or any other OpenFX host, so that build has only met a probe harness and its real texture sizes and premultiplication behaviour are unconfirmed. The depth modes have never been given a genuine rendered depth pass either, only a radial card and a linear ramp. Nothing has been timed at all.
Watch it running
Nothing loads from YouTube until you press play.Watch it there instead