- C++ 71.2%
- C 15%
- Objective-C++ 4.3%
- Metal 4%
- CMake 3.1%
- Other 2.4%
|
|
||
|---|---|---|
| docs | Make the library dynamic and relocatable | |
| examples | Finish texture resampling | |
| geodesic | Add Geodesics | |
| include/ovoxel | Include depth and pick renders for splat | |
| src | Include depth and pick renders for splat | |
| tests | Add USD conversion utilities | |
| third_party | Finish texture resampling | |
| tools | Fix CMakeLists | |
| .gitignore | Add Geodesics | |
| CMakeLists.txt | Make the library dynamic and relocatable | |
| README.md | Add Geodesics | |
LabGeomVoxSplat
A standalone C++ library for sparse voxel octree (SVO) construction, ray tracing, and mesh LOD generation.
Combines a QEF-based mesh voxelizer with the Laine-Karras SVO ray traversal algorithm for fast GPU rendering on Metal (macOS/Silicon) and CUDA (Linux/Windows). This implementation follows the ovoxel algorithm from Trellis (see Provenance below).
Features
- Mesh → Voxels: Quadratic Error Function (QEF) voxelization with surface-preserving dual vertices
- SVO Ray Tracing: Stackless octree traversal (Laine & Karras 2010) on CPU, Metal, and CUDA
- Mesh Reconstruction: Dual contouring with coplanarity-aware quad splitting
- UV Unwrapping: Automatic atlas generation via xatlas
- Texture Baking: Rasterize surface colors onto UV atlas with dilation padding
- Material System: Extensible channel-based descriptors from "compact" (4 bytes) to "bananas" (32 bytes PBR)
- Surface Sampling: Pluggable interface for flat color, texture, MaterialX, or Gaussian splat sources
- LOD Pipeline: Voxelize at any resolution → reconstruct → unwrap → bake → export oct or ply
Geodesics
The optional geodesic subsystem (-DOVOXEL_BUILD_GEODESIC=ON, on by default) adds geodesic and planetary geometry, consolidated from the AridPlanet teaching technology. See geodesic/.
- goldberg: Geodesic-polyhedron sphere grids (icosahedral / Goldberg hex tessellations) with cell addressing, hex-frustum culling, and radial layers.
- Frames & precision: Floating-origin world frames and sphere-of-influence handover for planet-scale coordinates without precision loss.
- Spatial acceleration: Morton-key hex trees and Barnes–Hut for large-N queries; on-sphere pathfinding and nearest-neighbor search (gflann).
- Physics: Symplectic integration, Lorentz transforms, causality, and temporal epochs.
- orbital_mechanics: Keplerian orbits, bodies, forces, phases, and state propagation.
- planet_building: Procedural planet generation (C99).
- topomancy: Graph-topology toolkit (C99).
- OpenSubdiv bridge (optional,
-DGEODESIC_OPENSUBDIV_BRIDGE=ON): limit-surface evaluation over the grid.
Quick Start
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
Convert a mesh to SVO and render:
./ovoxel_convert -i model.ply -o model.oct -r 256
./ovoxel_viewer model.oct
Generate an LOD mesh with baked texture:
./ovoxel_convert -i model.ply -m lod.ply -r 128 --bake lod_texture.png
Build Options
| Option | Default | Description |
|---|---|---|
OVOXEL_BUILD_TOOLS |
ON | Build ovoxel_convert CLI |
OVOXEL_BUILD_TESTS |
ON | Build test suite |
OVOXEL_BUILD_EXAMPLES |
OFF | Build viewer (requires LabGL) |
OVOXEL_BACKEND |
auto | GPU backend: metal or cuda |
Library API
#include <ovoxel/ovoxel.h>
// Load a mesh
ovoxel::Mesh mesh = ovoxel::load_ply("input.ply");
// Voxelize
ovoxel::ConvertParams params;
params.voxel_size = {0.01f, 0.01f, 0.01f};
params.grid_min = {0, 0, 0};
params.grid_max = {256, 256, 256};
ovoxel::FlatColorSampler sampler(mesh.face_colors.data());
ovoxel::VoxelizeResult voxels = ovoxel::mesh_to_voxels(
vertices, num_verts, faces, num_faces, params, &sampler);
// Build SVO
ovoxel::VoxelGrid grid(256);
grid.populate(voxels, params);
ovoxel::SVO svo(grid);
grid.transfer_materials(svo);
svo.save("output.oct");
// Reconstruct mesh
ovoxel::ReconstructResult recon = ovoxel::voxels_to_mesh(voxels, params);
// UV unwrap + bake
ovoxel::UnwrapResult unwrapped = ovoxel::unwrap_mesh(recon, 1024);
ovoxel::BakeResult texture = ovoxel::bake_texture(unwrapped, vertex_colors, 1024);
ovoxel::dilate_texture(texture, 16);
ovoxel::write_texture_png("texture.png", texture);
Material Formats
The SVO leaf payload uses a descriptor-based channel system. Predefined presets:
| Preset | Stride | Channels | Use Case |
|---|---|---|---|
compact() |
0 (inline) | 32-bit packed normal+shade | CAD, 3D printing, maximum speed |
colored() |
8 bytes | RGBA8 color + octahedral normal | General rendering |
pbr() |
16 bytes | Color + normal + roughness + metallic | Production PBR |
bananas() |
32 bytes | Full float precision everything | Maximum quality |
The traversal kernel reads only the compact node array. Material data lives in a separate attribute buffer — one extra read on leaf hit, zero cost during traversal.
Surface Samplers
Pluggable color sources for voxelization:
// Per-face constant color (fastest)
ovoxel::FlatColorSampler flat(face_colors_ptr);
// UV-mapped texture lookup
ovoxel::TextureSampler tex;
tex.uvs = uv_data;
tex.faces = face_indices;
tex.pixels = rgba8_texture;
tex.tex_w = 1024; tex.tex_h = 1024;
// Pass to voxelizer
ovoxel::mesh_to_voxels(..., &tex);
Future samplers (interface defined, implementation pending):
MaterialXSampler— evaluate shader graphs at surface pointsSplatSampler— gather from Gaussian splat fieldsCompositeSampler— layer/blend multiple sources
Architecture
include/ovoxel/
├── ovoxel.h umbrella header
├── types.h linalg.h aliases, bit utilities
├── material.h channel descriptors, oct-normal encoding
├── svo.h SVO node format, build, traverse, serialize
├── sampler.h SurfaceSampler interface
├── qef.h mesh-to-voxel API
├── convert.h full pipeline: load, reconstruct, unwrap, bake
├── serialize.h Morton/Hilbert space-filling curves
└── render.h Metal/CUDA renderer interface
src/
├── svo.cpp SVO build + LZ4 IO + CPU ray traversal
├── qef.cpp QEF accumulation + constrained solve
├── sampler.cpp TextureSampler implementation
├── convert.cpp PLY loader, VoxelGrid, reconstruction, pipeline
├── unwrap.cpp xatlas integration
├── bake.cpp texture rasterization + dilation + PNG export
├── serialize.cpp Morton/Hilbert encode/decode
├── metal/ Metal compute traversal kernel + host dispatch
└── cuda/ CUDA compute traversal kernel
Dependencies
- linalg.h — linear algebra (bundled)
- LZ4 — SVO compression (bundled)
- xatlas — UV unwrapping (bundled)
- stb_image_write — PNG export (bundled)
- LabGL — viewer only (optional, for
OVOXEL_BUILD_EXAMPLES)
No external dependencies for the core library. C++17, CMake 3.21+.
Acknowledgements:
Voxelation algorithm and reconstruction follows TRELLIS' QEF-based voxelation, but differs significantly in details:
- TRELLIS/o-voxel — QEF voxelization (ported from Eigen/CUDA/Python to linalg.h/C++)
Bitterli's sparse-voxel-octrees teaches how to create and raycast very, very fast SVO structures. His data structures are used instead of TRELLIS'. The representation has been extensively modified to allow for material properties in voxels.
- sparse-voxel-octrees — Laine-Karras SVO traversal (Benedikt Bitterli)
Gorsten & Diakopolous' linalg is used for math instead of Eigen:
- linalg.h — single-header linear algebra
XAtlas is used for batteries-included texture atlasing in order to resample textures for meshes reconstructed from voxel data:
- xatlas — automatic UV atlas generation
License
MIT
Copyright (c) 2026 Nick Porcino