Don't render the world behind the opaque top bars: size the 3D viewport to the visible area #918

Open
opened 2026-10-21 18:00:32 +00:00 by sky_line · 0 comments
Owner

The menu bar and the navigation/favourites bar at the top of the window are fully opaque. They always cover the same strip of the 3D view, yet the world is rendered and lit underneath them every frame: G-buffer, deferred lighting, RT reflections, AO, TAA/upscaling and post-processing. That work is never seen.

Proposal

Size the world render to the area that is actually visible, and leave out the strip behind the top bar(s).

  • Render the world into a viewport that ends at the bottom edge of the opaque top bars. Measure the height from the UI each frame; it varies with UI scale, whether the navigation and favourites bars are shown, and fullscreen or mouselook UI hiding.
  • Adjust the projection so the visible image does not change. Use an off-centre frustum: same camera and field of view, with the top of the frustum moved down to the bar edge. Do not squash or re-centre the picture.
  • Shrink every screen-sized target and pass to match: G-buffer, lighting, RT reflections, AO, TAA/FSR history, bloom and post. Screen-space effects treat the new top edge as the frame edge, as they already treat the window edges.
  • When the bars change size or are hidden (mouselook, Ctrl+Alt+F1 / UI hidden), resize the way a window resize does. Reset history only when the size actually changes.
  • Snapshots taken from the main view (#873) need the full frame. Render those frames at full height, or return to the full viewport while a snapshot is being captured.

Expected gain

Work in proportion to the area removed, on the per-pixel passes only. With about 50 px of bars on a 1026 px window, that is roughly 5% of the per-pixel cost: an estimated 0.5–0.7 ms in a heavy scene on an RTX 5090, more on slower GPUs and at higher UI scale. Shadows, culling, RT scene builds and skinning are unaffected.

Out of scope for now

Other opaque UI, such as floaters and the bottom toolbar (whose buttons are transparent over the scene). A per-tile approach (coarsest variable-rate shading plus skipping RT and lighting tiles under opaque UI) can follow later if this pays off.

Verify

  • GPU timers before and after in the same spot.
  • The view looks the same, with no seam or stretch at the bar edge.
  • Toggling the navigation bar, UI scale, mouselook and hidden UI all resize cleanly.
  • Snapshots still capture the full frame.
The menu bar and the navigation/favourites bar at the top of the window are fully opaque. They always cover the same strip of the 3D view, yet the world is rendered and lit underneath them every frame: G-buffer, deferred lighting, RT reflections, AO, TAA/upscaling and post-processing. That work is never seen. ## Proposal Size the world render to the area that is actually visible, and leave out the strip behind the top bar(s). - Render the world into a viewport that ends at the bottom edge of the opaque top bars. Measure the height from the UI each frame; it varies with UI scale, whether the navigation and favourites bars are shown, and fullscreen or mouselook UI hiding. - Adjust the projection so the visible image does not change. Use an off-centre frustum: same camera and field of view, with the top of the frustum moved down to the bar edge. Do not squash or re-centre the picture. - Shrink every screen-sized target and pass to match: G-buffer, lighting, RT reflections, AO, TAA/FSR history, bloom and post. Screen-space effects treat the new top edge as the frame edge, as they already treat the window edges. - When the bars change size or are hidden (mouselook, Ctrl+Alt+F1 / UI hidden), resize the way a window resize does. Reset history only when the size actually changes. - Snapshots taken from the main view (#873) need the full frame. Render those frames at full height, or return to the full viewport while a snapshot is being captured. ## Expected gain Work in proportion to the area removed, on the per-pixel passes only. With about 50 px of bars on a 1026 px window, that is roughly 5% of the per-pixel cost: an estimated 0.5–0.7 ms in a heavy scene on an RTX 5090, more on slower GPUs and at higher UI scale. Shadows, culling, RT scene builds and skinning are unaffected. ## Out of scope for now Other opaque UI, such as floaters and the bottom toolbar (whose buttons are transparent over the scene). A per-tile approach (coarsest variable-rate shading plus skipping RT and lighting tiles under opaque UI) can follow later if this pays off. ## Verify - GPU timers before and after in the same spot. - The view looks the same, with no seam or stretch at the bar edge. - Toggling the navigation bar, UI scale, mouselook and hidden UI all resize cleanly. - Snapshots still capture the full frame.
sky_line added this to the Slipstream project 2026-10-21 18:00:33 +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#918
No description provided.