Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
70 lines
12 KiB
Markdown
70 lines
12 KiB
Markdown
# Research32 — Reframe for a 1 s whole view
|
||
|
||
## Work estimate
|
||
|
||
The strict minimum depends on how much zero surface the world contains. Marching Cubes can avoid cells proven to be entirely solid or air; for an arbitrary field without such proofs, it must consider every candidate cell. The table estimates the current dense path for the 2,130-tile Natural SW view. It counts lattice slots including the mesher’s one-sample normal halo on each side; halo and tile-boundary slots can repeat across tiles.
|
||
|
||
| LOD | Tiles | Cell step (voxels) | Candidate cells (M) | Density slots with halo (M) |
|
||
|---:|---:|---:|---:|---:|
|
||
| 0 | 512 | 1 | 16.777 | 21.952 |
|
||
| 1 | 448 | 2 | 14.680 | 19.208 |
|
||
| 2 | 320 | 8 | 1.311 | 2.195 |
|
||
| 3 | 208 | 16 | 0.852 | 1.427 |
|
||
| 4 | 240 | 32 | 0.983 | 1.646 |
|
||
| 5 | 144 | 64 | 0.590 | 0.988 |
|
||
| 6 | 96 | 128 | 0.393 | 0.658 |
|
||
| 7 | 96 | 256 | 0.393 | 0.658 |
|
||
| 8 | 66 | 512 | 0.270 | 0.453 |
|
||
| **Total** | **2,130** | — | **36.250** | **49.185** |
|
||
|
||
The calculation uses `n³` candidate cells and `(n+3)³` density slots per tile: 32 cells per axis at LOD0–1, then 16 at LOD2–8. The tile counts come from the L60 run; the mesher establishes the grid dimensions and halo. ([LOD counts](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l60/speed-matrix-natural-sw-run1.log:81>), [grid and halo](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp:434>))
|
||
|
||
This is a **dense-path budget, not an unavoidable floor or a count of actual calls for every generator**. LOD0–1 alone account for 41.16M of the 49.19M slots. Proof skips and caches can reduce actual evaluations: in L55’s representative LOD0 data, SW still evaluated 21.95M active lanes, while FI evaluated 5.49M but spent 29.7 worker-seconds on LOD0. The FI result says field cost matters as much as sample count. ([L55 counters](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux55/REPORT.md:41>), [L55 LOD0 worker time](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux55/REPORT.md:13>))
|
||
|
||
The real surface-oriented lower bound is closer to the number of cells near the zero set, roughly proportional to resolved surface area divided by cell area. That number depends on the generator, caves, edits, and chosen resolution; there is no surface-area census to calculate it here.
|
||
|
||
For a 1 s cold view, L55’s roughly 0.4–0.45 s shape setup leaves at most 0.55–0.60 s for tile work. At ideal W12 balance, that is about **6.6–7.2 worker-seconds**. SW’s 13.3 worker-seconds therefore needs about a **46%** work reduction; FI’s 50.2 needs about **87%**. That makes 1 s physically plausible after structural work reduction, but unlikely from more scheduling polish alone. ([L55 budget](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux55/REPORT.md:80>))
|
||
|
||
The current L60 medians are 1.30–1.33 s for profiles and motifs, 1.41 s for caves, 1.67 s for Natural SW, 1.70 s for Lattice, and 4.93 s for FI. Its FI near ring is already about 0.98 s. ([L60 matrix](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux60/REPORT.md:27>))
|
||
|
||
## External comparisons
|
||
|
||
Public **per-core SDF sampling plus meshing** numbers for the named shipped games are scarce; their performance figures are not directly comparable to this workload.
|
||
|
||
- **Teardown:** Its voxel volumes support CPU voxel collision and GPU ray-marched rendering; that is not CPU SDF-to-Marching-Cubes throughput. [Game Developer interview](https://www.gamedeveloper.com/design/how-beautiful-voxels-laid-the-way-for-i-teardown-s-i-heist-y-framework)
|
||
- **Dreams:** Alex Evans’s prototype slides describe a DX11 Marching Cubes approach and models containing 1–100,000 CSG edits. That is model complexity, not samples or meshes per second; it supplies no comparable final-game per-core figure. [Evans slides](https://www.slideshare.net/slideshow/umbra-ignite-2015-alex-evans-learning-from-failure-prototypes-rd-iteration-and-arriving-at-great-by-throwing-away-lots-of-almostgreat/52801357), [tooling discussion](https://www.gamedeveloper.com/design/how-media-molecule-designed-a-fun-and-robust-toolset-for-i-dreams-i-)
|
||
- **Enshrouded:** Keen confirms its proprietary Holistic Engine, but I found no public CPU meshing throughput. [Official FAQ](https://enshrouded.com/en-US/faq)
|
||
- **Astroneer:** Its developer identifies Marching Cubes for terrain deformation and discusses optimizing it, but gives no time or throughput. [Developer blog](https://blog.astroneer.space/p/going-faster/)
|
||
- **No Man’s Sky:** The official 5.0 notes say dual Marching Cubes increased terrain-generation speed and reduced memory, without quantifying the gain. [Official update](https://www.nomanssky.com/worlds-part-i-update/)
|
||
- **Transvoxel:** The algorithm has 256 regular cases and 512 transition cases grouped into 73 equivalence classes. These describe table size, not runtime. [Algorithm paper](https://transvoxel.org/Transvoxel.pdf)
|
||
|
||
Two imperfect CPU references help set scale. FastNoise2 reports 261.10M 3D Perlin samples/s and 52.43M cellular samples/s for AVX2 on an i7-7820X at 4.9 GHz with Clang-CL 10; it does not report thread scaling, and these are noise calls without meshing. [FastNoise2 benchmarks](https://github.com/Auburn/FastNoise2) A separate C++ block-world project reports roughly 1 ms for a 32³ block fill, greedy mesh, and visibility pass, with a nine-worker pool; that is block terrain, not smooth SDF/MC. [Project design notes](https://github.com/DanielWLiu07/voxel-engine/blob/main/docs/design.md) Voxel Plugin’s docs identify generator queries as nearly half of a flat-world generation example and describe large gains from conservative range analysis, but give no per-core rate. [Performance notes](https://docs.voxelplugin.com/1.2/technical-notes/performance-and-profiling)
|
||
|
||
## Ranked architecture changes
|
||
|
||
1. **Prove empty space by bounds, then mesh sparse active bricks.** Add conservative `RangeAtBox` queries for heightfields, features, passages, islands, and edits; recurse or subdivide only boxes whose density range includes zero. Start in `World::generateTile` and `UVoxelMarchingCubesMesher::GenerateMesh`, using the existing tile classification, proof-mask, and required-sample infrastructure. For a thin surface, this can avoid most of a tile’s volume; realized whole-view gain is unknown and will vary by generator. **Size: L/XL.** False bounds cause holes. Retain exact field samples at active cell corners and the normal halo; unknown bounds must fall back to dense evaluation. ([tile generation](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp:1997>), [mesher](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp:119>), [tile classification](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp:2344>))
|
||
|
||
2. **Give FI a fast exact field path.** Its LOD0 work dominates FI’s cost. `NativeFloatingIslandDensityAt` calls the island field, which includes trigonometric roughness and lobe work; its column cache is already active and uses a 16,384-entry, four-way shared cache. First attribute time to field operations, cache hits/conflicts, and tile-local reuse. Then try a layout-built spatial index and batched exact evaluation so distant islands are not queried for every point. **Size: M/L.** Potentially large for FI, but current substage data do not support a saving estimate. Preserve expression order and output on the scalar path; changing math or field values can break Clang/GCC/MSVC agreement. ([FI evaluator](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:6280>), [FI cache](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/FloatingIslandsInternal.h:501>))
|
||
|
||
3. **Use progressive proxies and velocity-aware priority for streaming.** Show a coarse representation for distant tiles early, generate near tiles in view and travel direction first, and replace proxies with the final MC mesh. This can improve VR readiness and high-speed travel; it saves **no worker-seconds** if every final tile is still generated. Measure time-to-visible coverage separately from full mesh completion. **Size: M.** The viewer already has desired-tile filters and staged neighborhood/full-detail readiness, so this builds on existing scheduling. ([viewer scheduling](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Source/StandaloneViewer.cpp:2908>))
|
||
|
||
Other ideas rank lower:
|
||
|
||
- **SIMD-first field sampling:** The X8 API has scalar fallbacks for native field paths. Batch only proven-active samples and preserve the same arithmetic order, with contraction off and cross-compiler checks. It could speed the field portion, but it cannot remove the dense candidate-cell count. **Size: M/L.** ([X8 path](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:3157>))
|
||
- **Far-field sample reuse:** Reuse exact samples across tiles or cache a coarser regional field. The world already creates shared column caches, and clipmap rings largely occupy different regions, limiting parent/child reuse. Far repair and cap work are measurable, but do not remove them without silhouette and interior-view evidence. **Size: M/L.** ([shared caches](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp:2013>), [far refinements](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp:389>))
|
||
- **Cache shape setup per layout:** Compilation and caches already live for the active `World`; a persistent derived cache could reduce repeat-load cold setup, but not the large tile drain. **Size: M.** ([shape compilation](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/VoxelForgeCore.cpp:1394>))
|
||
- **Replace Marching Cubes or move work to GPU:** Surface Nets might reduce some mesh construction, but retains field sampling and changes geometry/topology. Dual Contouring adds floating-point solving and determinism risk. GPU fixed-point could be deterministic in principle, but porting the fields and avoiding readback costs is a large rewrite. Neither is my first step. **Size: L/XL.**
|
||
|
||
## Recommended path
|
||
|
||
1. Prototype conservative sparse evaluation on a simple profile. First measure active cells and field calls by LOD, then compare final mesh, payload, and topology against dense generation across W1/W8/W12 and compilers. Keep the normal halo and seam samples exact.
|
||
2. In parallel, instrument FI LOD0’s evaluator and cache. Its 29.7 LOD0 worker-seconds alone exceed the entire approximately 6.6 worker-second FI budget, even if all other tiles were free. Use the measurements to choose between spatial pruning, tile-local reuse, and a batch evaluator before changing island math.
|
||
3. Add or refine coarse-first rendering and velocity-aware queue priority for VR. Keep the full-view timer separate so proxy readiness is not mistaken for total work saved.
|
||
|
||
For sparse traversal, skipped samples will change a dense density-grid hash if that hash includes unevaluated space. Keep deterministic field values wherever sampled, and gate on exact mesh/payload/topology plus conservative-proof audits. Preserve the one-sample halo, boundary agreement, worker-count/compiler comparisons, and far-horizon silhouette checks; do not infer safety from tile visibility alone. ([R31 proof/visibility cautions](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Research31/REPORT.md:64>))
|
||
|
||
## Uncertainties
|
||
|
||
The 49.2M figure is a dense slot count for the representative 2,130-tile configuration, not a unique-point count or actual calls for every generator. The profile variants use 1,986 tiles, and existing proofs reduce some generators’ sampling. There is no same-run per-generator sample/cell census or public per-core game benchmark to establish an apples-to-apples target. Far-field visibility and the quality error allowed by a sparse representation also need measured visual gates.
|
||
|
||
Read-only review only; no scripts, tests, builds, binaries, or tree changes were made. |