A VR app renders a 3D 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 — this is the raw motion-to-photon latency problem.
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 image shift, not a re-render — using the head-orientation change since that frame was captured:
Δyaw = yaw(now) − yaw(captured)
shift_u = tan(Δyaw) / (2·tan(hFovX/2)) · strength
shift_v = tan(Δpitch) / (2·tan(hFovY/2)) · strength
sampled_uv = screen_uv + (shift_u, shift_v)
This is 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 (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 3D frame is actually rendered; lower it to simulate a heavy scene dropping frames.
- Head turn speed — how fast the simulated head sweeps left/right (you can also drag the canvas to look around manually).
- Reprojection strength — how much of the computed correction ATW actually applies, 0–100%.
- ATW toggle — turn it off to see raw stale-frame judder with zero correction.
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.