All Products
Unity 6 / URP  ·  C# / HLSL In Development

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.

Prototype flythrough — Surface Nets terrain streaming around the viewer in Unity 6.
Architecture rewrite

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

GPU-first Surface Nets meshing

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.

Infinite terrain with caves

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.

Seamless, balanced LOD

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.

Budgeted rendering and physics

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.

Measured performance

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.

178 average FPS
settled world
180 average FPS
10 m/s traversal
122 average FPS
150 m/s stress
58 1% low FPS
150 m/s stress

Scroll figures horizontally to inspect labels and values.

Frame-pacing comparison between the previous and optimized stitchers across settled, 10 meter-per-second, and 150 meter-per-second runs. In the stress test, average FPS increases from 108 to 122, one-percent low rises from 39 to 58 FPS, and the 99th-percentile frame time drops from 25.9 to 17.2 milliseconds.
Figure 1 — Frame pacing. The largest gain appears under extreme streaming load: average FPS improves by 13%, the 1% low by 51%, and P99 frame time by 34%. At 10 m/s, average FPS is effectively unchanged while the 1% low improves from 86 to 96 FPS.
Bar charts comparing one-percent-low frame rate, maximum LOD selection time, and managed allocation between the previous and optimized stitchers. The optimized implementation improves frame consistency and roughly halves worst-case selection time; stress-test allocation falls from 99.0 to 13.2 kilobytes per frame.
Figure 2 — Optimization impact. Factored transition data and index-only state selection cut the measured worst-case LOD selection time by roughly half in every scenario. During the 150 m/s run, managed allocation falls by 87%, from 99.0 to 13.2 KB per frame.
Time-series comparison of build backlog, GPU pipeline occupancy, and cumulative chunk throughput during the 150 meter-per-second stress test. The optimized stitcher keeps a smaller queue and completes 45,838 builds versus 43,682 for the previous stitcher.
Figure 3 — Stress-test dynamics. Average pending work drops from 34.9 to 18.5 chunks and the maximum queue from 121 to 68, while throughput rises from 728 to 764 completed builds per second. The optimized scheduler spends less time saturated despite moving the viewer nine kilometres in one minute.

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
SettledPrevious176.096.410.37 ms25.02 ms10.30
SettledOptimized177.8115.18.69 ms10.30 ms10.40
10 m/s traversalPrevious181.786.211.61 ms22.00 ms13.855.1
10 m/s traversalOptimized180.396.310.39 ms11.31 ms10.555.0
150 m/s stressPrevious107.938.525.95 ms22.67 ms99.0728.0
150 m/s stressOptimized121.958.217.17 ms10.77 ms13.2763.8
Historical benchmarks Earlier Surface Nets baseline and cave ablation
Historical progress-tracking data

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.

Historical frame-pacing results for the earlier SampleScene Surface Nets implementation with caves enabled and disabled. Average frame rates were 164 and 192 FPS while settled, 149 and 178 FPS at 10 meters per second, and approximately 111 FPS in both 150-meter-per-second stress tests.
Historical Figure 1 — Frame pacing. Earlier SampleScene measurements comparing cave-enabled and cave-disabled terrain before the current stitching implementation.
Historical cave-generation ablation comparing resident triangles, completed chunk builds per second, and average build backlog in the earlier SampleScene implementation.
Historical Figure 2 — Cave ablation. These runs isolated the geometry and streaming cost of cave generation in the earlier system.
Scenario Caves Avg FPS 1% low P99 frame Builds/s Avg triangles
SettledEnabled163.8110.39.06 ms01.87 M
SettledDisabled192.4153.36.52 ms00.35 M
10 m/s traversalEnabled148.762.815.91 ms238.31.90 M
10 m/s traversalDisabled177.769.514.39 ms227.60.34 M
150 m/s stressEnabled111.438.625.93 ms647.10.89 M
150 m/s stressDisabled111.137.226.88 ms671.00.46 M
LOD wireframes

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.

Development status

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.

Working now
  • GPU terrain generation
  • Infinite chunk streaming
  • Seamless octree LOD
  • Asynchronous colliders
To reimplement
  • Runtime terrain modification
  • Displacement bombing
  • Biome system