MarchingWorld
A GPU-first procedural voxel terrain foundation built on Surface Nets. It streams an effectively infinite world of hills and caves around the viewer, with seamless LOD transitions and asynchronously baked physics.
From Marching Cubes to Surface Nets
MarchingWorld was rebuilt from the ground up around Surface Nets. Moving meshing onto compute shaders greatly improved generation performance and removed the need to implement the Marching Cubes-specific Transvoxel algorithm.
The current Transition-Ready Surface Nets stitcher computes fine and virtual-coarse boundary vertices during a chunk's initial generation, then stores the possible transition states as a compact, factored topology atlas. An LOD change now selects and composes index blocks instead of regenerating density or creating separate seam meshes. The result remains watertight while each retained chunk renders as one ordinary mesh and one draw call.
Working foundation
Compute shaders generate density, Surface Nets vertices, and quads without the CPU touching a voxel. Two-stage asynchronous readback transfers counters first, then only the vertex and index ranges actually used.
A seeded, position-pure density field produces deterministic hills, overhangs, and underground caves. Chunks stream around the viewer and all-air regions are rejected before spending GPU work.
An octree selects nearby detail and enforces a 2:1 balance between neighbors. A precomputed transition atlas keeps boundaries watertight, while index-only state changes avoid separate stitch meshes and extra draw calls.
Mesh uploads are budgeted per frame, GPU and chunk resources are pooled, and nearby collider meshes are cooked off the main thread. Steady-state streaming is designed to allocate almost nothing per frame.
Optimized stitching under load
Six matched 60-second runs compare the first Transition-Ready Surface Nets stitcher with its optimized implementation across a settled world, normal 10 m/s traversal, and an intentionally extreme 150 m/s streaming stress test. Cave generation was disabled in every run to isolate stitching and streaming behavior.
settled world
10 m/s traversal
150 m/s stress
150 m/s stress
Scroll figures horizontally to inspect labels and values.
Test conditions
Katana GF76 laptop running Unity 6.4.5f1 Editor, Direct3D 12 and URP at 2560 × 1440; Intel Core i5-11260H, RTX 3050 Laptop GPU (4 GB), and 16 GB DDR4 RAM. Terrain used 32-cell chunks, four LODs, 1 m voxels, a 1,000 m view distance, 24 base GPU build slots, two transition-priority slots, and cave generation disabled.
How to read the results
Every condition is a single run after a 10-second warm-up, so the figures report observed values and percentiles without confidence intervals. Unity's draw-call recorder was unavailable in these captures, so the architectural reduction to one draw call per retained chunk is not presented as a measured counter. These are current Editor measurements, not standalone-build results or a final performance target. Further optimization work is planned and will likely improve raw performance; however, reintroducing caves, terrain modification, biomes, displacement effects, and other planned systems may offset some of those gains.
| Scenario | Stitcher | Avg FPS | 1% low | P99 frame | Max selection | KB/frame | Builds/s |
|---|---|---|---|---|---|---|---|
| Settled | Previous | 176.0 | 96.4 | 10.37 ms | 25.02 ms | 10.3 | 0 |
| Settled | Optimized | 177.8 | 115.1 | 8.69 ms | 10.30 ms | 10.4 | 0 |
| 10 m/s traversal | Previous | 181.7 | 86.2 | 11.61 ms | 22.00 ms | 13.8 | 55.1 |
| 10 m/s traversal | Optimized | 180.3 | 96.3 | 10.39 ms | 11.31 ms | 10.5 | 55.0 |
| 150 m/s stress | Previous | 107.9 | 38.5 | 25.95 ms | 22.67 ms | 99.0 | 728.0 |
| 150 m/s stress | Optimized | 121.9 | 58.2 | 17.17 ms | 10.77 ms | 13.2 | 763.8 |
Historical benchmarks Earlier Surface Nets baseline and cave ablation
These SampleScene benchmarks were recorded to track development progress before the current Transition-Ready Surface Nets stitching architecture and its later optimization. They are retained as a development record, do not represent current performance, and should not be directly compared with the MainScene figures above.
Scroll figures horizontally to inspect labels and values.
| Scenario | Caves | Avg FPS | 1% low | P99 frame | Builds/s | Avg triangles |
|---|---|---|---|---|---|---|
| Settled | Enabled | 163.8 | 110.3 | 9.06 ms | 0 | 1.87 M |
| Settled | Disabled | 192.4 | 153.3 | 6.52 ms | 0 | 0.35 M |
| 10 m/s traversal | Enabled | 148.7 | 62.8 | 15.91 ms | 238.3 | 1.90 M |
| 10 m/s traversal | Disabled | 177.7 | 69.5 | 14.39 ms | 227.6 | 0.34 M |
| 150 m/s stress | Enabled | 111.4 | 38.6 | 25.93 ms | 647.1 | 0.89 M |
| 150 m/s stress | Disabled | 111.1 | 37.2 | 26.88 ms | 671.0 | 0.46 M |
Continuous detail, one surface
The wireframe makes the octree structure visible: dense geometry follows the viewer while progressively coarser chunks cover the distance. Transition cells reconcile those resolutions at their shared borders.
LOD distribution
The color-coded debug view isolates each resolution band; the neutral wireframe exposes the corresponding change in mesh density.
Transition boundary
A close view of the same problem: adjacent colors make the resolution boundary explicit, while the neutral view keeps the shared seam topology readable.
A faster foundation, with features to rebuild
The Surface Nets transition was a ground-up rewrite. The new streaming, meshing, LOD, and collider foundation is working, but higher-level systems from the Marching Cubes prototype were intentionally left behind and must now be reimplemented against the new density pipeline.
- GPU terrain generation
- Infinite chunk streaming
- Seamless octree LOD
- Asynchronous colliders
- Runtime terrain modification
- Displacement bombing
- Biome system