Compact sparse volumetric data format optimized for WebGPU real-time rendering.
Warning
This project is under active development. The data format and API are subject to change.
- 50%+ smaller volumes than NanoVDB (bunny: 64MB → 28MB)
- WebGPU-native data layout with WGSL shader library
- 32-bit addressing for better GPU compatibility
- Fast traversal with hierarchical raymarching (HDDA)
This repository includes:
picovdb.wgsl- WGSL shader librarypicovdb.ts- TypeScript loadersrc/main.zig- NanoVDB → PicoVDB converter
PicoVDB compresses NanoVDB files through:
- Rank query compression: Bit masks + counts eliminate inactive voxel storage
- 32-bit offsets: Replace 64-bit pointers with computed indices (limits to 4 billion active voxels)
- GPU-aligned structs: Minimize padding, maximize cache efficiency
// Include the library in your compute shader
// (concatenate picovdb.wgsl with your shader code)
@group(0) @binding(2) var<storage> picovdb_grids: array<PicoVDBGrid>;
@group(0) @binding(3) var<storage> picovdb_roots: array<PicoVDBRoot>;
@group(0) @binding(4) var<storage> picovdb_uppers: array<PicoVDBUpper>;
@group(0) @binding(5) var<storage> picovdb_lowers: array<PicoVDBLower>;
@group(0) @binding(6) var<storage> picovdb_leaves: array<PicoVDBLeaf>;
@group(0) @binding(7) var<storage> picovdb_buffer: array<u32>;
@compute @workgroup_size(16, 16)
fn main(@builtin(global_invocation_id) global_id: vec3u) {
let grid = picovdb_grids[0];
// Initialize read accessor
var accessor: PicoVDBReadAccessor;
picovdbReadAccessorInit(&accessor);
// Sample voxel data using HDDA traversal
var hit_t: f32;
var hit_value: f32;
let hit = picovdbHDDAZeroCrossing(
&accessor, grid, ray_origin, t_near, ray_direction, t_far, &hit_t, &hit_value
);
}# Build converter
zig build
# Convert NanoVDB to PicoVDB
./zig-out/bin/picovdb input.nvdb output.picovdb- OpenVDB - Industry standard sparse volume library
- NanoVDB - GPU-optimized sparse volumes
- WebGPU NanoVDB - WebGPU port of NanoVDB