Skip to main content

Module decompress

Module decompress 

Source
Expand description

GPU.2 — Vxl → (occupancy bitmap, colour offsets, packed colour array). Pure CPU; no wgpu deps in this module. Shape:

  • occupancy[x, y] is 8 contiguous u32 words covering z=0..256, one bit per voxel with z-innermost ordering. Bit position of voxel (x, y, z) is z + (x + y*vsid)*CHUNK_Z; the word index is (x + y*vsid)*8 + z/32 and the bit-in-word is z & 31. This packs each column’s 256 z-bits into 8 contiguous u32s so the GPU shader can rank-count solid voxels in O(8 popcount) instead of O(z) sequential bit fetches.
  • color_offsets[x + y*vsid] — u32 = base index into colors for that column’s voxels in ascending z. vsid*vsid + 1 entries; trailing sentinel = colors.len().
  • colors[..] — packed u32 per occupied voxel, ordered first by column index then by ascending z within the column.

The voxlap slab format interleaves floor and ceiling colour ranges across slab boundaries, with implicit “bedrock” voxels filling the gap between a slab’s textured floor and the next slab’s air-gap top. Bedrock has no per-voxel colour in the slab data — voxlap stores only textured surfaces.

Bedrock-as-solid (cliff-face fix): each MipUpload carries two bitmaps — occupancy (textured voxels only, for the colour rank) and solid_occupancy (textured surfaces plus the implicit bedrock interior below them). The marcher hit-tests solid_occupancy, so vertical wall/cliff faces are opaque; a bedrock hit (solid but uncoloured) inherits the colour of the textured surface above it. Bedrock is still stored as 1 bit, not a per-voxel colour, so the colour array stays O(textured voxels) — storing bedrock colours would balloon a vsid=128 chunk from ~80 KiB to ~10 MiB. The cost is one extra occupancy bitmap (occupancy storage doubles; colours unchanged).

(Originally “bedrock-as-air”, GPU.4: bedrock was dropped entirely, which left cliff faces transparent to the sky.)

This is O(textured voxels) work; not on the render hot path.

Structs§

ChunkUpload
CPU-decompressed chunk ready to upload to the GPU. Each field maps onto one storage buffer in GPU.3+; for GPU.2 the buffers also serve the read-back validator.
MipUpload
GPU.11 — one mip level of a chunk in the GPU upload shape. Mip-N has (vsid >> mip)² columns spanning z = 0..CHUNK_Z >> mip.

Constants§

BEDROCK_RGB
Historic sentinel BGRA for bedrock voxels — kept exported so callers that want voxlap-CPU bedrock parity can render their own pass. Not used by the default GPU decompressor: the “bedrock-as-air” refactor (GPU.4 prereq) skips bedrock entirely.
CHUNK_Z
Z-extent of every voxlap column — matches roxlap_formats’ private MAXZDIM (voxlap5.h:10). Re-declared here so this module stays a pure consumer of the public Vxl surface.
GPU_MAX_MIPS
GPU.11 — number of mip levels decompress_chunk builds per chunk (capped by the chunk’s own vsid / CHUNK_Z halving). Matches the CPU demo’s OpticastSettings::mip_levels = 6, so the GPU mip ladder reaches the same ray-depth as the CPU path (mip_scan_dist · 2⁵). The per-mip relative-offset tables in crate::scene::GridStaticMeta are sized to this.
OCC_WORDS_PER_COLUMN
Number of u32 words per column in the occupancy bitmap (CHUNK_Z bits packed 32-per-word). With CHUNK_Z = 256 this is exactly 8 — the rank-count loop in the GPU shader runs in 8 iterations max.

Functions§

decompress_chunk
Decompress a Vxl chunk into the GPU upload shape, building the full mip ladder (gpu_mip_count(vsid) levels). Caller guarantees vxl is shaped as a roxlap-scene chunk (vsid square). If vxl already carries at least that many mips (the common scene path — the bake generates 6), they are read directly; otherwise the chunk is cloned and re-mipped so the upload always carries a deterministic, vsid-uniform level count.
gpu_mip_count
GPU.11 — how many mip levels a chunk of side vsid actually yields under GPU_MAX_MIPS. Mirrors the stopping rule in Vxl::generate_mips (src_vsid > 1 && src_z > 1 && n < max) so the upload, the per-slot stride math in crate::scene, and the shader all agree on the level count for a given vsid. Always >= 1 (mip-0).
occ_words_per_column_for_mip
GPU.11 — number of occupancy u32 words per column at a given mip ((CHUNK_Z >> mip) bits packed 32-per-word, min 1). Mip-0 is OCC_WORDS_PER_COLUMN (= 8).