Standalone only. Hybrid/DC cut sharp residual 16.7 -> 6.25 cm and split creases ~100%, organic wall unchanged under hybrid, +4.4% mesh cost, W1/W8/W16 identical. Gate failed: hybrid open edges on 500/625 tagged tile borders; every method fails LOD0/LOD1 (no transition templates yet). Binaries and OBJ meshes not committed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
126 lines
12 KiB
Markdown
126 lines
12 KiB
Markdown
# World assembler M2 round 1: sharp-mesher decision spike
|
||
|
||
Date: 2026-10-10
|
||
Status: **Gate failed; no production mesher selected.** Hybrid is the leading candidate for an in-game follow-up, but it does not pass independent tile seams. Every candidate fails the tested LOD0/LOD1 seam.
|
||
|
||
## Decision
|
||
|
||
At 25 cm, feature-aware DC substantially reduces sharp-feature field residual and preserves hard normal splits. The hybrid also leaves the smooth cave-chamber wall on the MC path, where its measured residual matches MC. Its 8-worker mesh cost is about 4.4% above MC.
|
||
|
||
Those gains are not enough to choose it: hybrid fails all 500 tagged-shape independent tile-border cases, and DC everywhere fails all 625. MC passes all 625 same-LOD tile-border cases but retains large sharp-feature bevel residual and also fails every LOD transition case. No candidate passes both border gates. Hold architectural recipes until a real border/transition implementation passes.
|
||
|
||
Round 2 should take MC and hybrid into Unreal as opt-in, versioned recipe candidates. Hybrid is the primary quality candidate; MC is the baseline and organic fallback. Bring neighbor halo/ownership rules, a 2:1 transition template or equivalent, and actual collision cooking. Compare the five fixtures in-game with matched cameras, including same-LOD and LOD0/LOD1 borders. Keep DC-everywhere as a reference unless its organic quality and border results improve.
|
||
|
||
## Test setup
|
||
|
||
The standalone C++20 harness uses the plugin’s canonical marching-cubes lookup table and 25 cm cells. It builds a 32³-cell, 8 m tile for each fixture. The lattice phase sweep translates each analytic field by 0, 5, 10, 15, and 20 cm on each axis: 125 phases per fixture and method, 1,875 phase meshes total.
|
||
|
||
The fixtures are a union-of-boxes 90° corner, a box doorway with an analytic void, a one-metre riser, a cliff ledge/overhang, and a smooth spherical cave-chamber cavity. The chamber has negative density in solid rock and positive density in its air cavity, following the plugin sign convention. It is an analytic curved proxy, not a sampled native cave or SurfaceWorld patch.
|
||
|
||
The candidates are:
|
||
|
||
- **MC:** table-driven marching cubes with linear edge roots and interpolated central-difference field normals. This preserves MC geometry while giving it a fair smooth-normal path.
|
||
- **Hybrid:** untagged connected surface components use MC. Components connected to analytic sharp-plane feature tags use dual contouring.
|
||
- **DC:** dual contouring on every surface component, including the cave-chamber wall.
|
||
|
||
DC uses Hermite roots, a fixed-order 3×3 QEF solve, a small center penalty for rank-deficient constraints, cell-bound clamping, deterministic feature selection, and position quantization at 1/65,536 voxel. All candidates share a 0.01 mm positive bias for exact-zero lattice samples. No LOD transition template is implemented in this spike; independent fine/coarse half meshes are compared directly to expose that gate.
|
||
|
||
Phase and same-resolution seam sweeps use the five phase offsets above. Same-LOD borders compare independently generated 8 m tiles on either side of x=0. LOD borders compare an independently generated 25 cm half tile against an independently generated 50 cm half tile. Border contours are compared in both directions at five points per segment. A missing contour is recorded as unmatched; the topological audit counts geometric boundary and nonmanifold edges after merging the independent meshes.
|
||
|
||
## Surface residual and crease normals
|
||
|
||
The residual is the absolute analytic field value, in metres, sampled at each triangle’s three vertices, three edge midpoints, and centroid. The table shows the equal-weight mean of the 125 phase means and the maximum sample over all phases. Repeated vertex samples count repeatedly. This is a useful analytic-field residual, not a symmetric Hausdorff distance.
|
||
|
||
| Fixture | MC mean / max (cm) | Hybrid mean / max (cm) | DC mean / max (cm) |
|
||
|---|---:|---:|---:|
|
||
| 90° corner | 0.51 / 16.67 | 0.17 / 6.25 | 0.17 / 6.25 |
|
||
| Doorway | 0.99 / 16.67 | 0.41 / 12.50 | 0.41 / 12.50 |
|
||
| One-metre riser | 0.46 / 16.67 | 0.15 / 6.25 | 0.15 / 6.25 |
|
||
| Cliff ledge / overhang | 0.49 / 16.67 | 0.16 / 6.25 | 0.16 / 6.25 |
|
||
| Cave-chamber wall | 0.39 / 1.17 | 0.39 / 1.17 | 0.50 / 4.75 |
|
||
|
||
MC’s worst sharp residual is 16.67 cm at this phase sample, close to the expected 17.68 cm half-diagonal bevel bound. Hybrid/DC reduce the sharp residual while DC-everywhere is rougher on the smooth chamber than either MC path.
|
||
|
||
Crease split rate counts adjacent triangles with distinct analytic feature labels and face-normal angle above 30°. A split is counted when their average interpolated/vertex normals also differ by more than 30°.
|
||
|
||
| Fixture | MC split rate | Hybrid split rate | DC split rate |
|
||
|---|---:|---:|---:|
|
||
| 90° corner | 11.83% | 99.93% | 99.93% |
|
||
| Doorway | 24.31% | 100.00% | 100.00% |
|
||
| One-metre riser | 12.98% | 99.99% | 99.99% |
|
||
| Cliff ledge / overhang | 15.18% | 99.89% | 99.89% |
|
||
| Cave-chamber wall | no tagged crease | no tagged crease | no tagged crease |
|
||
|
||
## Topology and independent borders
|
||
|
||
The phase meshes themselves have no nonmanifold edges. MC has 0 open-edge meshes in 625 fixture/phase cases. Hybrid and DC each have 36 open-edge meshes in 625, summing to 116 open edges across those cases.
|
||
|
||
Independent-border results aggregate 625 fixture/phase cases per method. “Bad” means unmatched seam probes, boundary edges, or nonmanifold edges. No nonmanifold edges were found.
|
||
|
||
| Method | Same-LOD bad cases / 625 | Same-LOD open edges | Same-LOD unmatched probes | LOD0/LOD1 bad cases / 625 | LOD0/LOD1 open edges | LOD0/LOD1 unmatched probes |
|
||
|---|---:|---:|---:|---:|---:|---:|
|
||
| MC | 0 | 0 | 0 | 625 | 75,494 | 0 |
|
||
| Hybrid | 500 | 85,632 | 3,484 | 625 | 75,794 | 5,819 |
|
||
| DC | 625 | 101,440 | 3,609 | 625 | 75,790 | 6,128 |
|
||
|
||
MC’s same-LOD contour match is exact in all cases: zero measured contour distance and zero merged open edges. Hybrid passes only the 125 smooth chamber cases; its 500 tagged-shape cases have open edges. DC also fails the chamber border.
|
||
|
||
Every LOD0/LOD1 case has open boundary edges. For MC, the per-case maximum sampled contour distance has an 18.57 cm median, 26.41 cm 95th percentile, and 31.82 cm worst case; 39 of 625 cases exceed 25 cm. Hybrid has complete contour comparisons in only 130 cases; five of those exceed 25 cm, with a 560.47 cm worst finite comparison. DC has complete contour comparisons in only five cases, with a 560.47 cm worst finite comparison. The large finite outliers and unmatched probes are direct failures, not a pass hidden by averages. The spike has no transition templates, so these results are a transition gate, not a claim that any candidate’s final transition design has been tuned.
|
||
|
||
## Cost, determinism, and collision proxy
|
||
|
||
Each timing uses an already sampled 32³-cell field grid, three mesh builds, and the median build time. Field sampling, Unreal scheduling, upload, collision cooking, and rendering are excluded. All values below average the five fixtures.
|
||
|
||
| Worker count | MC mean ms/tile | Hybrid mean ms/tile | DC mean ms/tile |
|
||
|---:|---:|---:|---:|
|
||
| 1 | 16.308 | 17.375 | 16.269 |
|
||
| 8 | 14.275 | 14.907 | 13.996 |
|
||
| 16 | 14.555 | 15.291 | 14.129 |
|
||
|
||
At W8, hybrid is 4.4% slower and DC is 2.0% faster than MC. Mean triangle counts are 3,454.4 / 3,456.8 / 3,457.6 for MC / Hybrid / DC. Mean vertex counts are 1,728.8 / 3,469.2 / 1,985.6. Hybrid’s feature-split path therefore roughly doubles output vertices for negligible triangle change.
|
||
|
||
All 45 determinism rows (five fixtures × three methods × three worker counts) match the W1 reference for that fixture and method: zero cross-worker hash mismatches. W16 is a 16-worker software pool running with process affinity limited to eight logical CPUs.
|
||
|
||
The standalone collision proxy is the same emitted vertex/triangle mesh. All 45 proxy hashes match the visual mesh hash and report 0 m geometry delta. This verifies the candidate mesh handoff only; there is no independent collision simplification, Unreal physics cook, or contact test in round 1.
|
||
|
||
## Captures
|
||
|
||
The [contact sheet](results/captures/contact_sheet.jpg) is an offline orthographic rasterization of matched MC, Hybrid, and DC meshes for all five fixtures, plus one LOD seam view per method. It is 864 × 1,476 pixels. The 18 individual captures are 288 × 246 pixels. There are 19 JPEGs including the sheet; all are under 300 KB, and the largest is the 128,260-byte contact sheet. No viewer was launched.
|
||
|
||
Capture files:
|
||
|
||
- [90° corner — MC](results/captures/corner90_MC.jpg), [Hybrid](results/captures/corner90_Hybrid.jpg), [DC](results/captures/corner90_DC.jpg)
|
||
- [Doorway — MC](results/captures/doorway_MC.jpg), [Hybrid](results/captures/doorway_Hybrid.jpg), [DC](results/captures/doorway_DC.jpg)
|
||
- [One-metre riser — MC](results/captures/riser1m_MC.jpg), [Hybrid](results/captures/riser1m_Hybrid.jpg), [DC](results/captures/riser1m_DC.jpg)
|
||
- [Cliff ledge — MC](results/captures/cliff_overhang_MC.jpg), [Hybrid](results/captures/cliff_overhang_Hybrid.jpg), [DC](results/captures/cliff_overhang_DC.jpg)
|
||
- [Cave chamber — MC](results/captures/organic_cave_chamber_MC.jpg), [Hybrid](results/captures/organic_cave_chamber_Hybrid.jpg), [DC](results/captures/organic_cave_chamber_DC.jpg)
|
||
- [LOD seam — MC](results/captures/lodseam_MC.jpg), [Hybrid](results/captures/lodseam_Hybrid.jpg), [DC](results/captures/lodseam_DC.jpg)
|
||
|
||
## Run ledger and constraints
|
||
|
||
| Run/check | Result |
|
||
|---|---|
|
||
| Final MSVC C++20 build | Passed in 4.42 s, BelowNormal, affinity 0xFF00. |
|
||
| Final phase/cost/determinism/seam run | Passed in 114.208 s; 1,875 phase meshes and 1,875 independent seam cases, BelowNormal, affinity 0xFF00. |
|
||
| Final capture renderer | Passed in 2.61 s, BelowNormal, affinity 0xFF00; 19 files under the 300 KB cap. |
|
||
| Earlier phase run 1 | Exited normally in 31.14 s; exact-zero lattice degeneracies exposed topology defects. |
|
||
| Earlier phase run 2 | Exited normally in 31.11 s after adding the deterministic exact-zero bias; DC still had boundary defects. |
|
||
| Earlier phase run 3 | Exited normally in 35.07 s after splitting disconnected cell patches; remaining boundary defects kept it from acceptance. |
|
||
| Earlier phase run 4 | Exited normally in 36.55 s after making MC endpoint-gradient interpolation explicit; used for normal-split comparison. |
|
||
| Earlier seam run | Exited normally in 74.21 s, but clipped a shared mesh and did not test independently generated borders. It was superseded by the final independent-neighbor seam run. |
|
||
| Tool validation | One early PowerShell parser check used an invalid reference argument. Two later analysis-only PowerShell aggregation commands had syntax errors. All were corrected; none launched a mesher process. One early MSVC environment setup printed a nonfatal vswhere helper warning; compilation succeeded, and the final build emitted no warning. |
|
||
|
||
Every final build/test/render process used BelowNormal priority and affinity 0xFF00, limiting it to eight of the 16 logical processors. The build/test/render scripts enforce an 8 GB private-memory guard and 15-minute timeout. No process hit either limit, crashed, or needed a 0xC0000142 retry. The earlier phase runs above exited normally; their topology/seam measurements failed or were superseded as noted. No viewer or owner editor was opened. No owner project was built and no .uasset was touched.
|
||
|
||
## Files added for the spike
|
||
|
||
New implementation and launch files:
|
||
|
||
- [SharpMesherSpike.cpp](SharpMesherSpike.cpp)
|
||
- [BuildSharpMesherSpike.ps1](BuildSharpMesherSpike.ps1)
|
||
- [RunSharpMesherSpike.ps1](RunSharpMesherSpike.ps1)
|
||
- [RenderSharpMesherCaptures.ps1](RenderSharpMesherCaptures.ps1)
|
||
- [RenderSharpMesherCaptures.py](RenderSharpMesherCaptures.py)
|
||
|
||
The report, CSV measurements, exported OBJ meshes, offline captures, executable/object build outputs, and run logs are also in this WorldAssemblerM2 directory. No files under Source were changed.
|