render3d: the terrain's GPU maps paged round the camera while the tiles are on
At the cut the whole 4096 height, normal and photograph textures go, replaced by a coarse 2048 level (the CPU's tt_coarse uploaded; the normal and photograph blitted down on the GPU, the photograph mipmapped) and a pool of fine tiles in three array textures - heights, normals, photograph, each layer a tile with a one-texel border - addressed through a tt_n^2 page table (u_tp_page: slot + 1, 0 = the coarse level). The pool holds the tiles within the reach (900 m, or the fog wall's when nearer) and a ring, and is made again when the fog wall changes its size (terrain_pages_fog). Once a frame (tp_frame, beside tt_frame) tiles past the reach and two tiles go and the wanted ones come in nearest first, 8 a frame, written into a staging buffer kept for the process (two halves, one per frame in flight) and copied into their layers inside the frame's own command buffer - no submit of their own - with the page table re-uploaded only when it changed. tp_bind binds the pool (or 1-layer stand-in arrays while paging is off, u_tp_on = 0) for every program that reads the ground: terrain_bind_height (models, scatter, shadow_bind, grass), terrain_bind_prog, the sun pass and the shadow bake. grass_cull.comp reads through the same page table. R3D_VKMEM prints the pool's line. Tiles off, nothing changes. Compile-only: not run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
329439cf61
commit
617ac10c5a
15 changed files with 571 additions and 12 deletions
|
|
@ -253,6 +253,7 @@ function terrain_generate__t(render3d_st: mut Render3dState) -> void {
|
|||
|
||||
# The height field for shaders that place things on the ground (model.vert's u_ground)
|
||||
function terrain_bind_height(render3d_st: mut Render3dState, p: int) -> void {
|
||||
tp_bind(render3d_st, p)
|
||||
r3d_bind_2d(render3d_st, p, "u_ts_height", 5, render3d_st.ter_height_tex)
|
||||
r3d_bind_2d(render3d_st, p, "u_ter_normal", 6, render3d_st.ter_normal_tex)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_ts_half"), float(render3d_st.TERRAIN_HALF))
|
||||
|
|
@ -287,6 +288,7 @@ function terrain_bake_pass(render3d_st: mut Render3dState, p: int, target: int)
|
|||
gpu_depth_test(render3d_st, false)
|
||||
gpu_blend(render3d_st, false)
|
||||
gpu_use_program(render3d_st, p)
|
||||
tp_bind(render3d_st, p)
|
||||
r3d_bind_2d(render3d_st, p, "u_height", 0, render3d_st.ter_height_tex)
|
||||
r3d_bind_2d(render3d_st, p, "u_ter_normal", 7, render3d_st.ter_normal_tex)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_half"), float(render3d_st.TERRAIN_HALF))
|
||||
|
|
@ -400,6 +402,7 @@ function terrain_init(render3d_st: mut Render3dState) -> void {
|
|||
render3d_st.gvk_tag = was
|
||||
}
|
||||
function terrain_init__t(render3d_st: mut Render3dState) -> void {
|
||||
tp_dummies(render3d_st)
|
||||
for i in 0 .. TERRAIN_INIT_STEPS { terrain_init_step(render3d_st, i) }
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +476,7 @@ function terrain_draw_shadow(light_vp: floats) -> void {
|
|||
# selection can switch between them per patch without re-binding anything but the node.
|
||||
function terrain_bind_prog(render3d_st: mut Render3dState, p: int) -> void {
|
||||
gpu_use_program(render3d_st, p)
|
||||
tp_bind(render3d_st, p)
|
||||
r3d_bind_2d(render3d_st, p, "u_height", 0, render3d_st.ter_height_tex)
|
||||
r3d_bind_2d(render3d_st, p, "u_ter_normal", 7, render3d_st.ter_normal_tex)
|
||||
r3d_bind_2d(render3d_st, p, "u_grass_d", 1, render3d_st.ter_tex[0]); r3d_bind_2d(render3d_st, p, "u_grass_n", 2, render3d_st.ter_tex[1]); r3d_bind_2d(render3d_st, p, "u_grass_a", 3, render3d_st.ter_tex[2])
|
||||
|
|
@ -582,6 +586,7 @@ function terrain_sun_pass(render3d_st: mut Render3dState, w: int, h: int, depth:
|
|||
gpu_clear(render3d_st, GL_COLOR_BUFFER_BIT)
|
||||
let p = render3d_st.ter_sun_prog
|
||||
gpu_use_program(render3d_st, p)
|
||||
tp_bind(render3d_st, p)
|
||||
r3d_bind_2d(render3d_st, p, "u_height", 0, render3d_st.ter_height_tex)
|
||||
r3d_bind_2d(render3d_st, p, "u_ter_normal", 7, render3d_st.ter_normal_tex)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_half"), float(render3d_st.TERRAIN_HALF))
|
||||
|
|
@ -822,6 +827,7 @@ function terrain_unload(render3d_st: mut Render3dState) -> void {
|
|||
if render3d_st.ter_normal_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_normal_tex); render3d_st.ter_normal_tex = 0 }
|
||||
if render3d_st.ter_dem_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_dem_tex); render3d_st.ter_dem_tex = 0 }
|
||||
if render3d_st.ter_ortho_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_ortho_tex); render3d_st.ter_ortho_tex = 0 }
|
||||
tp_pool_free(render3d_st)
|
||||
if render3d_st.ter_heights != null { free(render3d_st.ter_heights); render3d_st.ter_heights = null }
|
||||
tt_close(render3d_st)
|
||||
if render3d_st.ter_ortho_px != null { free(render3d_st.ter_ortho_px); render3d_st.ter_ortho_px = null }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue