Terrain texture bake: per-region coarse bake + near-camera page cache #811

Closed
opened 2026-10-17 18:10:01 +00:00 by sky_line · 1 comment
Owner

Terrain pixels re-fetch and blend all 4 terrain materials every frame (up to 16 texture fetches per pixel, x3 with hex tiling), and the terrain G-buffer shader needs 72 registers (112 with hex) against 48 for everything else.

Design

  1. Per-region coarse bake: the blended terrain (albedo, normal, ORM, emissive; hex tiling applied) baked per region at a moderate resolution, saved to disk keyed by a hash of the region's terrain data + materials, invalidated when either changes, loaded and sampled like any texture. Covers terrain beyond ~30-60 m with one fetch per map.
  2. Near-camera high-resolution cache: a clipmap or virtual-texture pages (terrain tiles baked on demand at the resolution their distance needs), re-baked incrementally as the camera moves, evicted under memory pressure. Detail textures repeat every few metres (~100-300 texels/m up close), so a whole-region bake can't carry near detail (65536^2 per region would be needed).
  3. The live terrain shader stays as the fallback for anything not baked yet: no holes, no popping.

Sharing baked tiles between segments was considered and dropped: tiles only match when composition and elevation blend weights match, which is rare outside flat uniform ground; the detail textures themselves are already shared.

Measure: terrain G-buffer time and registers vs the live path; VRAM use; bake cost when moving and when terrain is edited.

Context: measured on a GTX 1080 (Pascal) at 4K with the test-control channel and the shader clock (RenderVKShaderClockLighting) / pipeline stats (RenderVKPipelineStats). The frame is GPU-bound but not bandwidth-bound (memory controller ~36% busy on the 1080, ~14% on a 5090): it is latency / occupancy bound, so trading a little memory traffic for fewer registers and fewer dependent loads should help every GPU generation.

Terrain pixels re-fetch and blend all 4 terrain materials every frame (up to 16 texture fetches per pixel, x3 with hex tiling), and the terrain G-buffer shader needs 72 registers (112 with hex) against 48 for everything else. **Design** 1. **Per-region coarse bake**: the blended terrain (albedo, normal, ORM, emissive; hex tiling applied) baked per region at a moderate resolution, saved to disk keyed by a hash of the region's terrain data + materials, invalidated when either changes, loaded and sampled like any texture. Covers terrain beyond ~30-60 m with one fetch per map. 2. **Near-camera high-resolution cache**: a clipmap or virtual-texture pages (terrain tiles baked on demand at the resolution their distance needs), re-baked incrementally as the camera moves, evicted under memory pressure. Detail textures repeat every few metres (~100-300 texels/m up close), so a whole-region bake can't carry near detail (65536^2 per region would be needed). 3. The live terrain shader stays as the fallback for anything not baked yet: no holes, no popping. Sharing baked tiles between segments was considered and dropped: tiles only match when composition and elevation blend weights match, which is rare outside flat uniform ground; the detail textures themselves are already shared. Measure: terrain G-buffer time and registers vs the live path; VRAM use; bake cost when moving and when terrain is edited. Context: measured on a GTX 1080 (Pascal) at 4K with the test-control channel and the shader clock (RenderVKShaderClockLighting) / pipeline stats (RenderVKPipelineStats). The frame is GPU-bound but not bandwidth-bound (memory controller ~36% busy on the 1080, ~14% on a 5090): it is latency / occupancy bound, so trading a little memory traffic for fewer registers and fewer dependent loads should help every GPU generation.
sky_line added this to the Slipstream project 2026-10-17 18:10:01 +00:00
Author
Owner

Fixed in 1.4.1 (997c0ea315). Reopen if you still see it.

Fixed in 1.4.1 (997c0ea315). Reopen if you still see it.
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#811
No description provided.