Skip to main content

Module chunk_descriptors

Module chunk_descriptors 

Source
Expand description

CPU → GPU packing of chunk descriptors for the Phase 2 chunked quadtree (CEL-62).

ChunkGpu must match struct ChunkGpu in shaders/ChunkRealize.slang byte for byte (std430: 96 bytes, 16-byte aligned due to [f32;4] members). The size invariant is locked by the chunk_gpu_layout_is_96_bytes test.

§Instance buffer layout (Godot 3D MultiMesh + custom data)

Each instance is 16 f32 values (64 bytes) in Godot’s TRANSFORM_3D + custom_data format:

  • Floats 0–11: 3×4 transform matrix (3 rows of 4 floats; identity → vertex shader positions geometry from the vertex-pool texture, not from the instance transform)
  • Float 12 (INSTANCE_CUSTOM.r): slot index as f32; the shader reads this to index into the per-face vertex pool
  • Float 13 (INSTANCE_CUSTOM.g): per-chunk geomorph factor (Phase 5): 1 = full detail, 0 = coarse/parent resolution. The surface vertex shader blends the realized grid toward its even (parent) sublattice by this factor. It rides in the per-frame instance buffer (NOT the cached realize descriptor / atlas), so a moving camera only re-uploads this small buffer — the realize/bake passes stay fully cached.
  • Floats 14–15: zero (reserved custom channels b/a)

Structs§

ChunkGpu
One chunk’s GPU descriptor (std430, 96 bytes).
ChunkParams
Realize-batch parameters + embedded terrain, byte-identical to struct ChunkParams in shaders/ChunkRealize.slang / ChunkTileBake.slang (binding 1).

Functions§

interior_verts_per_chunk
Interior vertex count for one chunk at resolution res.
pack_chunks
Pack all visible chunks into a contiguous ChunkGpu byte buffer (one entry per chunk).
pack_instances
Pack per-instance data for the chunk MultiMesh into a byte buffer.
pack_params
Pack one ChunkParams (header + terrain + tile_res + bump + surface) into its buffer. surface_enabled/surface_height_scale drive the CPU-surface path (pass 0.0, 0.0 when the CPU surface is irrelevant).
per_slot_bytes
VRAM one resident chunk slot reserves across ALL the GPU pools: geometry verts_per_chunk(res) × 48 B (pos_tex rgba32f 16 + verts_tex 2×rgba16f 16 + verts_buf float4 16), the colour + normal detail atlases (tile_res² × 8 B), and the CPU-surface colour + height + normal storage buffers (tile_res² × 12 B — allocated unconditionally by ChunkGpu::ensure). The VRAM budget divides by this; forgetting the surface buffers (the old accounting) made the real allocation ~2× the configured budget at large tile_res.
skirt_verts_per_chunk
Number of skirt vertices appended after the interior grid (Phase 3): one ring vertex per edge position on each of the 3 edges (corners duplicated per edge so each edge owns its own skirt ring), 3*(res+1).
verts_per_chunk
Total vertex count for one chunk at resolution res = interior grid + perimeter skirt (Phase 3 crack fix). This is the per-slot stride of the vertex pool, the verts_tex/pos_tex sizing unit, and the realize dispatch count. The interior block (L < interior_verts_per_chunk(res)) is unchanged; skirt verts are appended at L >= interior_verts_per_chunk(res).