# Terrain fidelity Track A report **Date:** 2026-08-21 **Status:** REPORT ACCEPTED BY OWNER DIRECTION; A1/A2 IMPLEMENTED; A3 REJECTED This report answers Track A from the measured [`terrain and atmospheric rendering findings`](2026-08-21-terrain-and-atmospheric-rendering-findings.md). It cites that evidence rather than repeating its measurements, and it does not reopen the findings' three refuted claims. The project owner subsequently authorized implementation. No physics or collision behavior changed. ## A1 — #226 detail-texture overlay The complete source/size/tiling, blend, neutral point, distance units, setting gate, material-ordering contract, reverted-experiment analysis, and connected A/B/A evidence are in the [`#226 retail building/EnvCell detail-texturing port note`](2026-08-21-retail-building-detail-texturing-pseudocode.md). The report conclusions are: - The reachable user-visible target is **building shells and interior EnvCell geometry**, not outdoor terrain. The Options preference caller and `LScape::ChangeRegion` both install category state `(landscape=0, building=enabled, environment=enabled, ordinary=0)` through `SmartBox::SetDetailTexturing`. - The existing **Building Detail Textures** checkbox is the sole setting gate. No second option was added. Toggling it now visibly changes the connected Facility Hub scene without a restart. - The port keeps retail's `DEST_COLOR + ONE_MINUS_SRC_ALPHA` blend verbatim, including the measured slight brightening. `dst=ZERO` would be an opt-in visual correction, not parity; exposing both meanings behind the one retail checkbox would make that preference ambiguous. - The reverted experiment targeted landscape, built the wrong texture-array shape, used `base * detail * 2`, assumed 128 gray was neutral, and rejected the brightness change that the measured retail blend actually produces. ## A2 — terrain vertex normals **Verdict: parity gap. Retail smooths shared terrain vertices.** The decisive named-retail function is `CLandBlockStruct::calc_lighting` at `0x00531700` in [`acclient_2013_pseudo_c.txt`](named-retail/acclient_2013_pseudo_c.txt): 1. It zeroes one three-float accumulator for every shared landblock vertex. 2. From `0x00531774` through `0x005317F6`, it walks every terrain polygon and adds that polygon's plane normal (`CPolygon + 0x20..0x28`) to the accumulator of each of its three vertex IDs. 3. From `0x00531817` through `0x00531886`, it normalizes every accumulated vector, falling back to `(0, 0, 1)` only for a degenerate sum. 4. The following sunlight/ambient loop dots those normalized shared-vertex normals with `LScape::sunlight` and writes per-vertex lighting. That is incident-face normal averaging. **VM4 correction (2026-08-22):** the findings doc's premise that `TerrainUtils.GetNormal` produced a faceted render was wrong — that function only orients procedural scenery (`SceneryGenerator.cs:166`) and never fed the render normal. The rendered terrain mesh already had smooth central-difference normals (Phase 3b, `LandblockMesh`). The real change A2 made is central-difference smoothing → retail's split-aware incident-face average: a genuine, decomp-verified parity port, but a subtler visual change than either document implied (VM0 measured 11–14 % of pixels at mean |Δ| ≈ 1–1.5 on the same view). The approved port is in `LandblockMesh.BuildRetailVertexNormals`. It uses the same split hash and exact emitted triangle topology, accumulates each normalized incident face normal at the shared 9 x 9 height-sample vertex, and normalizes the sum. Tests independently reconstruct the average from emitted positions/indices and prove every position and index is unchanged. This is lighting-only parity: the 81 height samples, 128 triangles, split directions, terrain surface, collision triangles, walkability, and physics owners are byte-for-byte/topology-equivalent to the prior path. ## A3 — subdivision **Agree: the standing “not worth doing” recommendation survives.** The findings §4 already establishes that the 9 x 9 samples are height-table quantized, so subdivision cannot recover missing terrain detail; changing the surface would create physics divergence, while coplanar subdivision would only interpolate a surface whose retail-correct shared-vertex smoothing is now already present. No subdivision work is scheduled.