Snapshots: temporal AA (TAA/FSR) by rendering a short jittered sequence on the offscreen surface #417

Closed
opened 2026-10-05 09:17:54 +00:00 by sky_line · 1 comment
Owner

Snapshots (the snapshot tool, high-res snapshots, upload/postcard/disk) are rendered without temporal antialiasing: no TAA resolve, no FSR. So they come out aliased (jaggies, specular shimmer frozen into the image, noisy RT/SSR/AO without temporal accumulation) compared with what's on screen, where TAA or FSR is on.

Current behaviour (code)

  • llcleanrenderervk.cpp ~13828: "Jitter only the on-screen main view: no resolve consumes an offscreen snapshot."
  • ~14050: "Offscreen renders (snapshots) are not jittered and resolve nothing". ensureTAA clears mTaaHistValid, so the main view's history also restarts after every snapshot (a brief shimmer on screen after taking one).
  • ~25112: mFsrRanLast is false on a snapshot; FSR's temporal state is not advanced by offscreen frames.
  • The snapshot path: LLViewerWindow::rawSnapshot (llviewerwindow.cpp ~5476) → LLVulkanContext::renderOffscreen(world, w, h, ...). Snapshots can be any size, including larger than the window and tiled high-res.

Proposal

Render the snapshot as a short temporal sequence on its own offscreen surface, building up TAA/FSR history before taking the result:

  1. Allocate snapshot-sized TAA history (or FSR context/resources at the snapshot's render and output sizes) separate from the main view's, so the live view's history is untouched (no on-screen shimmer after a snapshot).
  2. Render N frames (setting, e.g. 8-16) of the same frozen scene/camera with the jitter sequence (Halton), feeding TAA or FSR each frame. With a static camera and a frozen scene this converges to a supersampled, fully antialiased image, effectively accumulation AA. Also converges RT shadows / SSR / AO noise that relies on temporal accumulation.
  3. Freeze animation and time for the sequence (same world time / avatar poses / particles every sub-frame), so motion vectors are zero and nothing ghosts. Or deliberately allow motion blur as an option later.
  4. Take the final frame's resolved output (FSR output, or TAA resolve at the snapshot size) as the snapshot.
  5. Tiled high-res snapshots: do the sequence per tile with consistent jitter, or render at full res if VRAM allows. Mind the VRAM budget (#405): snapshot history targets are large at 4K-8K. Check the budget before allocating, and fall back to fewer frames, or to non-temporal AA (FXAA/SMAA), if it doesn't fit.
  6. Exposure / auto-exposure and bloom should match the live view; there's an existing FSR debug probe labelled SNAP for the "snapshot vs live wash-out" comparison.

Options / settings

  • RenderSnapshotTemporalFrames (0 = current behaviour, no temporal AA): number of accumulation frames.
  • A checkbox in the snapshot floater: "Antialias (slower)".
  • Respect the user's current AA/upscaler choice (TAA vs FSR), or always use plain TAA accumulation at native snapshot res for maximum quality (FSR's upscaling is pointless when you can render the snapshot at full res; its temporal AA is the useful part).

Done when

  • Snapshots with TAA/FSR on match (or beat) the on-screen antialiasing, with no ghosting.
  • Taking a snapshot no longer resets the live view's TAA/FSR history.
  • High-res / tiled snapshots work within the VRAM budget, with a sane fallback.
  • Snapshot time stays reasonable (frames × frame time; show progress for big ones).
Snapshots (the snapshot tool, high-res snapshots, upload/postcard/disk) are rendered **without temporal antialiasing**: no TAA resolve, no FSR. So they come out aliased (jaggies, specular shimmer frozen into the image, noisy RT/SSR/AO without temporal accumulation) compared with what's on screen, where TAA or FSR is on. ## Current behaviour (code) - `llcleanrenderervk.cpp` ~13828: "Jitter only the on-screen main view: no resolve consumes an offscreen snapshot." - ~14050: "Offscreen renders (snapshots) are not jittered and resolve nothing". `ensureTAA` clears `mTaaHistValid`, so **the main view's history also restarts** after every snapshot (a brief shimmer on screen after taking one). - ~25112: `mFsrRanLast` is false on a snapshot; FSR's temporal state is not advanced by offscreen frames. - The snapshot path: `LLViewerWindow::rawSnapshot` (`llviewerwindow.cpp` ~5476) → `LLVulkanContext::renderOffscreen(world, w, h, ...)`. Snapshots can be any size, including larger than the window and tiled high-res. ## Proposal Render the snapshot as a **short temporal sequence on its own offscreen surface**, building up TAA/FSR history before taking the result: 1. Allocate snapshot-sized TAA history (or FSR context/resources at the snapshot's render and output sizes) **separate from the main view's**, so the live view's history is untouched (no on-screen shimmer after a snapshot). 2. Render **N frames** (setting, e.g. 8-16) of the same frozen scene/camera with the jitter sequence (Halton), feeding TAA or FSR each frame. With a static camera and a frozen scene this converges to a supersampled, fully antialiased image, effectively accumulation AA. Also converges RT shadows / SSR / AO noise that relies on temporal accumulation. 3. Freeze animation and time for the sequence (same world time / avatar poses / particles every sub-frame), so motion vectors are zero and nothing ghosts. Or deliberately allow motion blur as an option later. 4. Take the final frame's resolved output (FSR output, or TAA resolve at the snapshot size) as the snapshot. 5. **Tiled high-res snapshots:** do the sequence per tile with consistent jitter, or render at full res if VRAM allows. Mind the VRAM budget (#405): snapshot history targets are large at 4K-8K. Check the budget before allocating, and fall back to fewer frames, or to non-temporal AA (FXAA/SMAA), if it doesn't fit. 6. Exposure / auto-exposure and bloom should match the live view; there's an existing FSR debug probe labelled SNAP for the "snapshot vs live wash-out" comparison. ## Options / settings - `RenderSnapshotTemporalFrames` (0 = current behaviour, no temporal AA): number of accumulation frames. - A checkbox in the snapshot floater: "Antialias (slower)". - Respect the user's current AA/upscaler choice (TAA vs FSR), or always use plain TAA accumulation at native snapshot res for maximum quality (FSR's upscaling is pointless when you can render the snapshot at full res; its temporal AA is the useful part). ## Done when - [ ] Snapshots with TAA/FSR on match (or beat) the on-screen antialiasing, with no ghosting. - [ ] Taking a snapshot no longer resets the live view's TAA/FSR history. - [ ] High-res / tiled snapshots work within the VRAM budget, with a sane fallback. - [ ] Snapshot time stays reasonable (frames × frame time; show progress for big ones).
sky_line added this to the 1.1.0 milestone 2026-10-05 17:02:31 +00:00
sky_line added this to the Slipstream project 2026-10-06 15:04:14 +00:00
Author
Owner

Solved by a different approach: snapshots render supersampled (32ff178571, d8befef87f) instead of a jittered TAA sequence, which removes the aliasing this ticket was about. Shipped in 1.2.0.

Solved by a different approach: snapshots render supersampled (32ff178571, d8befef87f) instead of a jittered TAA sequence, which removes the aliasing this ticket was about. Shipped in 1.2.0.
sky_line 2026-10-10 05:48:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#417
No description provided.