A VR app renders a frame at its own GPU-bound rate (the render rate slider), but the headset display refreshes on its own fixed schedule. If the display simply held the last rendered frame while you keep turning your head, the world appears to "swim" or judder relative to your motion — that's the raw motion-to-photon latency problem, shown live in the left "raw" panel, which never corrects for head motion.
Asynchronous timewarp (ATW) fixes most of it cheaply: just before each display refresh, it takes the most recently rendered frame and warps it — a 2D pixel shift, not a re-render — using the head-orientation change since that frame was captured:
Δyaw = yaw(now) − yaw(captured)
shift_x = tan(Δyaw) / (2·tan(hFovX/2)) · width · strength
shift_y = tan(Δpitch) / (2·tan(hFovY/2)) · height · strength
displayed = lastCapturedFrame shifted by (shift_x, shift_y)
This is exactly what the right "ATW" panel does to the same captured raster the left panel shows untouched. It's a pure-rotation approximation: it corrects rotational judder almost perfectly, but it cannot invent pixels that were never rendered — content that rotates into view from off-frame shows up as a dark edge gap (most visible here when reprojection strength is high and the render rate is low). It also can't fix parallax error from head translation, only rotation — that's the residual angular error readout when strength is below 100%.
- App render rate — how often a fresh frame is actually captured; lower it to simulate a heavy scene dropping frames.
- Head turn speed — how fast the simulated head sweeps left/right (you can also drag either panel to look around manually).
- Reprojection strength — how much of the computed correction ATW actually applies, 0–100%.
- ATW toggle — turns the correction on the right panel off, so it matches the raw panel's judder exactly.
Real headsets (Oculus/Meta Quest, PSVR, SteamVR) all run a variant of this every display refresh — it's the single technique most responsible for VR feeling "locked to your head" even when the app itself can't hit full frame rate.