docs(vm4): every Campaign AR document says what its evidence shows
Dated 'VM4 correction' notes, not silent rewrites: - AR plan: NoOpRenderPackProductionIntegrationTests is a 2x2 recording- device fixture, not a production pin; the real invariance is VM0's. Both '14,928/14,928 zero skips' totals qualified: hermetic lane filter. - Stage-2 connected report: the dense-town CPU figures ran under the automation observer (9.8 MB/frame alloc) and say nothing about the owner's hitch on the product; clean numbers are VM0's. - Track A report + findings doc: TerrainUtils.GetNormal only orients scenery; the render normals were already smooth; A2 replaced central differences with retail's incident-face average (the reviewer's own premise error). - Findings doc: 'retail brightens' is the fallback path only; real hardware runs the single-pass lerp (VM2). LandscapeDetailTextures = 0 answers the landscape open question. VM0 production table added as the baseline. - Completion audit retail-path row and the review's F1/F2/F3/F5 headers annotated with their closures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
dcdd102824
commit
6e76314b08
7 changed files with 117 additions and 30 deletions
|
|
@ -342,7 +342,10 @@ Current authored-celestial Stage 1 automated gate (2026-08-22):
|
|||
including all source, tests, tools, and SDK samples, builds with **0 warnings
|
||||
and 0 errors** after that restore.
|
||||
- The repository-owned fresh-process hermetic gate passes
|
||||
**14,928/14,928** tests with zero skips or failures across 14 assemblies;
|
||||
**14,928/14,928** tests with zero skips or failures across 14 assemblies
|
||||
**under the repository's hermetic lane filter** (Manual/Timing/Live/
|
||||
InstalledDat/Diagnostic lanes excluded; a raw `dotnet test AcDream.slnx`
|
||||
reports those lanes as skips/failures by design — VM4 correction);
|
||||
`AcDream.App.Tests` contributes **5,823/5,823**. Evidence is under
|
||||
`artifacts/atmospheric-rendering/stage1-moon-release-gate/`.
|
||||
- The App total includes the 9,500-caster 256-frame zero-managed-allocation
|
||||
|
|
@ -363,7 +366,8 @@ Recorded pre-moon automated checkpoint (not a current moon-scope completion
|
|||
claim):
|
||||
|
||||
- The repository-owned fresh-process Release test stage passes
|
||||
**14,880/14,880** tests with zero skips or failures across 14 assemblies.
|
||||
**14,880/14,880** tests with zero skips or failures across 14 assemblies
|
||||
(hermetic lane filter, as above).
|
||||
`AcDream.App.Tests` contributes **5,783/5,783**; campaign-focused App cases
|
||||
cover descriptor/asset/SPIR-V
|
||||
validation, pack-off/no-op invariants, atomic asynchronous candidate swaps,
|
||||
|
|
@ -760,10 +764,16 @@ require their own rows.
|
|||
acdream's default path has a stricter gate: zero new enhancement passes,
|
||||
images, buffers, submissions, or shader variants, with CPU/GPU deltas within
|
||||
the existing run-to-run noise envelope and deterministic reference captures
|
||||
unchanged. `NoOpRenderPackProductionIntegrationTests` pins the pre-campaign
|
||||
pass list, pipeline set, draw/dispatch tuple, framebuffer SHA-256, and complete
|
||||
resource ledger; the matrix's six physical retail rows independently record
|
||||
zero pack work at all three resolutions and both pacing modes.
|
||||
unchanged. `NoOpRenderPackProductionIntegrationTests` pins the pass list,
|
||||
pipeline set, draw/dispatch tuple, framebuffer SHA-256, and resource ledger of a
|
||||
**2x2 synthetic, one-draw composition fixture on a recording device that does
|
||||
not rasterize** — it proves the controller arm adds nothing to that shape, not
|
||||
that the production frame is unchanged. The matrix's six physical retail rows
|
||||
record zero pack work at all three resolutions and both pacing modes. The
|
||||
actual pack-off pixel and production-performance invariance against the
|
||||
pre-campaign build `6c79d35c` was established later by Campaign VM slice VM0
|
||||
([report](../research/2026-08-22-vm0-default-path-invariance.md), corrected
|
||||
2026-08-22).
|
||||
|
||||
Measurement protocol:
|
||||
|
||||
|
|
|
|||
|
|
@ -80,12 +80,12 @@ single-pass path darkens by ~10 %. Neither explains a scene-wide level.
|
|||
| VM1 | F2/F3 — #226 single-pass re-port + fade removal | **CLOSED 2026-08-22** — `05970306`, `388457a7`, `ae651312`, closeout; Opus APPROVE |
|
||||
| VM2 | F3 — which retail detail path ran | **CLOSED 2026-08-22** — single-pass; see [cdb note](../research/2026-08-22-vm2-retail-detail-path-cdb.md) |
|
||||
| VM3 | F4 — linear-light post stack | automated + **owner visual** |
|
||||
| VM4 | F5 — overclaiming docs, incl. the reviewer's own | docs |
|
||||
| VM4 | F5 — overclaiming docs, incl. the reviewer's own | **CLOSED 2026-08-22** |
|
||||
| VM5 | F8 — volumetric banding; F7 filed | automated |
|
||||
| VM6 | Foliage wind | automated + **owner visual** |
|
||||
| VM7 | Closeout: full gates, register, roadmap, merge | **owner** |
|
||||
|
||||
Order is VM2 (done) → VM0 (done) → VM1 (done) → VM4 → VM5 → VM3 → VM6 → VM7. VM0 goes first because everything after it is measured
|
||||
Order is VM2 (done) → VM0 (done) → VM1 (done) → VM4 (done) → VM5 → VM3 → VM6 → VM7. VM0 goes first because everything after it is measured
|
||||
against the baseline it establishes.
|
||||
|
||||
---
|
||||
|
|
@ -220,6 +220,17 @@ clipping, highlights roll off". Budget unchanged (two `pow` per pixel).
|
|||
|
||||
## VM4 — Truthful documents (F5)
|
||||
|
||||
**OUTCOME (2026-08-22): CLOSED.** Corrected in place, each with a dated
|
||||
"VM4 correction" note: the AR plan's 2x2-oracle sentence and both
|
||||
"zero skips" totals (now "under the hermetic lane filter"); the Stage-2
|
||||
report's turning-hitch paragraph (observer tax, not product); the Track A
|
||||
report's and the findings doc's `TerrainUtils.GetNormal` premise; the findings
|
||||
doc's "retail brightens" section (fallback only; single-pass lerp is what runs),
|
||||
its landscape-detail open question (`LandscapeDetailTextures = 0`, answered by
|
||||
VM2), and its open question 5; the completion audit's retail-path row; and the
|
||||
review's own F1/F2/F3/F5 headers. The VM0 production table is now the baseline
|
||||
in the findings doc §5.
|
||||
|
||||
Correct, in the AR plan and its reports, the four sentences the review
|
||||
named: the 2×2 oracle described as a production pin; the turning-hitch
|
||||
conclusion drawn under the automation observer; the "zero skips" headline
|
||||
|
|
|
|||
|
|
@ -80,11 +80,14 @@ gated on the single `Render::m_RenderPrefs.EnvironmentDetailTextures`. **So
|
|||
retail's setting is a BUILDINGS-AND-INTERIORS setting, not a terrain
|
||||
setting** — which explains why its UI label is "Building Detail Textures".
|
||||
|
||||
`SmartBox::SetDetailTexturing` (0x00451df0) *can* pass landscape through — its
|
||||
callers are **untraced**; that is the open question for whether terrain detail
|
||||
is ever enabled in practice.
|
||||
`SmartBox::SetDetailTexturing` (0x00451df0) *can* pass landscape through.
|
||||
**ANSWERED 2026-08-22 (VM2 cdb read):** `Render::m_RenderPrefs.LandscapeDetailTextures`
|
||||
is a real, separate preference and reads **0** on the live client
|
||||
(`EnvironmentDetailTextures = 1`); `landscape_detail_surface` is null while
|
||||
`building_detail_surface`/`environment_detail_surface` are set. Terrain detail
|
||||
is off by preference, and there is no Options row for it.
|
||||
|
||||
### The blend — and retail's own bug
|
||||
### The blend — the FALLBACK path (see the correction below)
|
||||
|
||||
`ACRender::SetDetailSurfaceInternal` (0x006b6280):
|
||||
|
||||
|
|
@ -117,12 +120,18 @@ category:
|
|||
| `0x06006D57` | 0.414 | 0.210 | **1.204** | **+20% brighter** |
|
||||
| `0x06006D58` | 0.165 | 0.132 | **1.033** | **+3% brighter** |
|
||||
|
||||
**Retail's own detail pass BRIGHTENS rather than roughens.** A proper
|
||||
roughening modulate needs `dst = ZERO` so the result centres on 1.0; here the
|
||||
`dest x (1-alpha)` term adds most of the original back on top. This
|
||||
independently confirms the community observation that it looks like surfaces
|
||||
"reflect more instead of being rougher", and it raises a real design decision
|
||||
for #226 (see open questions).
|
||||
**The FALLBACK detail pass brightens rather than roughens** — and, **CORRECTED
|
||||
2026-08-22 (VM2/VM4)**, the fallback is not what real hardware runs. The
|
||||
framebuffer blend above is taken only when `stage == 0`, i.e. when the adapter
|
||||
cannot advertise `D3DTEXOPCAPS_PREMODULATE`. A live cdb read on the owner's AMD
|
||||
GPU gave `m_caps.bCanDoSinglePassDetailing = 1` and `trysinglepass = 1`, so
|
||||
retail uses the single-pass texture-stage path in `D3DPolyRender::SetSurface`
|
||||
(0x0059c4d0): `lerp(base * diffuse, detail.rgb, detail.a * diffuse.a)` — a mild
|
||||
blend toward the detail colour (about −10 % on mid-tones with the live category
|
||||
texture). The community's "reflect more instead of being rougher" describes
|
||||
the fallback only. Full evidence:
|
||||
[`2026-08-22-vm2-retail-detail-path-cdb.md`](2026-08-22-vm2-retail-detail-path-cdb.md).
|
||||
The #226 port was re-done to the single-pass math at Campaign VM VM1.
|
||||
|
||||
### Terrain draw path
|
||||
|
||||
|
|
@ -168,9 +177,14 @@ non-single-pass fallback that is **untraced**. Vertex lighting comes from
|
|||
- Diagonal split direction comes from the `FSplitNESW` hash of world cell
|
||||
coords (constants `0x0CCAC033`, `0x421BE3BD`, `0x6C1AC587`, `0x519B8F25`).
|
||||
- `src/AcDream.Core/Rendering/Wb/TerrainUtils.cs` `GetNormal` returns the
|
||||
**flat per-face normal** (cross product of whichever triangle the sample
|
||||
lands in). **No averaging anywhere in the tree.** That is what produces the
|
||||
faceted look.
|
||||
**flat per-face normal**. **CORRECTED 2026-08-22 (VM4):** that function only
|
||||
orients procedural scenery (`SceneryGenerator.cs:166`); it never fed the
|
||||
render normal, and the claim that it produced a faceted look was wrong. The
|
||||
rendered mesh already used smooth central-difference normals (Phase 3b,
|
||||
`LandblockMesh`). Retail (`CLandBlockStruct::calc_lighting` 0x00531700)
|
||||
averages the unit plane normals of each vertex's incident polygons; Campaign
|
||||
AR's A2 ported that, replacing central differences — a real parity port with
|
||||
a subtle visual delta (VM0: 11–14 % of pixels at mean |Δ| ≈ 1–1.5).
|
||||
|
||||
**Open question, must be answered from the decomp, no guessing:** does retail
|
||||
smooth terrain vertex normals? Entry points: `ACRender::landPolyDraw` (both
|
||||
|
|
@ -233,6 +247,19 @@ registered bounded divergence.
|
|||
profile is **CPU-SUBMISSION-BOUND** (memory:
|
||||
`feedback_render_perf_measurement`).
|
||||
|
||||
**VM0 baseline (2026-08-22, connected, uncapped Release, no automation
|
||||
observer, `ACDREAM_FRAME_PROF=1`; `2026-08-22-vm0-default-path-invariance.md`):**
|
||||
|
||||
| Spot | Binary | CPU p50 / p95 | GPU p50 | alloc KB/frame |
|
||||
|---|---|---|---|---|
|
||||
| Holtburg | `6c79d35c` | 4.7 / 5.1 ms | 0.4 | 574 |
|
||||
| Holtburg | Campaign AR, pack off | 4.1 / 4.4 ms | 0.4 | 21 |
|
||||
| Arwic (dense) | `6c79d35c` | 6.0 / 6.5 ms | 0.7 | 582 |
|
||||
| Arwic (dense) | Campaign AR, pack off | 5.2 / 5.6 ms | 0.7 | 29 |
|
||||
|
||||
Any figure captured under `ACDREAM_AUTOMATION_ARTIFACT_DIR` carries the
|
||||
render-scene observer's allocation and is NOT comparable with this table.
|
||||
|
||||
Consequences:
|
||||
|
||||
- GPU-side **fullscreen** work is nearly free in observed FPS — it fills GPU
|
||||
|
|
@ -308,9 +335,9 @@ Design points the user asked for:
|
|||
3. What is the non-single-pass detail fallback in `landPolyDraw`? (§2)
|
||||
4. What uses the `BumpMap` / `DotProduct3` path, if not the detail textures?
|
||||
(§3)
|
||||
5. For #226: port retail's brightening blend **verbatim**, fix it to `dst=ZERO`
|
||||
so it roughens as intended and register the deviation, or expose both behind
|
||||
the setting? (§2)
|
||||
5. ~~For #226: port retail's brightening blend verbatim, fix it, or expose
|
||||
both?~~ **ANSWERED 2026-08-22:** neither — the brightening blend was the
|
||||
fallback; VM1 ported the single-pass lerp that real hardware runs (§2).
|
||||
|
||||
## 8. Where this sits
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,15 @@ The decisive named-retail function is
|
|||
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, not flat per-face shading. The
|
||||
WorldBuilder-derived `TerrainUtils.GetNormal` identified in the findings §4
|
||||
is therefore a simplified tool path and not the retail oracle.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ been pushed.
|
|||
| Requirement | Verdict | Authoritative evidence |
|
||||
|---|---|---|
|
||||
| Stage 1 project-owner stop | Pass | The owner's 2026-08-22 “Looks good!” acceptance, after exposure 1.0 → 0.80, is recorded in the [live-gate report](2026-08-22-atmospheric-stage1-live-gate.md). |
|
||||
| Retail-faithful path stays default and authoritative | Pass | The checked-in production no-op oracle, six physical pack-off rows, connected disable/restore transitions, and package-failure rows all pass. A branch diff contains only newly named atmospheric/detail shader sources plus the generated shader manifest; no pre-campaign retail shader source is modified. |
|
||||
| Retail-faithful path stays default and authoritative | Pass (evidence strengthened by VM0, 2026-08-22: exact pack-off pixel identity vs `6c79d35c` on static content and a clean production perf A/B — see `2026-08-22-vm0-default-path-invariance.md`; the no-op oracle named here is a 2x2 recording-device fixture) | The checked-in production no-op oracle, six physical pack-off rows, connected disable/restore transitions, and package-failure rows all pass. A branch diff contains only newly named atmospheric/detail shader sources plus the generated shader manifest; no pre-campaign retail shader source is modified. |
|
||||
| Physics and collision unchanged | Pass | `git diff origin/main...HEAD -- src/AcDream.Runtime src/AcDream.App/Physics src/AcDream.Core/Physics` is empty. The connected routes use the existing gameplay simulation without changing it. |
|
||||
| Tier 1 bloom, filmic tone mapping, colour grade, vignette, neutral settings, resize, and retained-UI/private-view isolation | Pass for implementation and available automation/physical rows | Slice 1 tests and the RX 9070 XT 30-row matrix pass; final project-owner image judgment remains below. |
|
||||
| Tier 1 authored-sun rays | Pass for implementation and connected state transitions | Authored sun/day-group/weather, occlusion-mask, behind-camera/off gates, and pre-tonemap composition are automated; connected time/weather transitions pass. Final physical-display dawn/noon/dusk, occlusion, and edge-flicker judgment remains below. |
|
||||
|
|
|
|||
|
|
@ -72,8 +72,20 @@ camera turn, server, character, entity population (15,522), and warmed scene:
|
|||
| Six-second turn | 27.8 / 32.9 / 36.7 ms | 28.6 / 32.2 / 40.2 ms | 0.6 / 1.2 ms | 1.5 / 1.9 ms |
|
||||
| Stationary | 28.6 / 30.2 / 31.1 ms | 29.1 / 30.9 / 32.6 ms | 0.9 / 0.9 ms | 1.7 / 1.8 ms |
|
||||
|
||||
The user's turning hitch reproduces on the retail path: Medium did not worsen
|
||||
turn CPU p95 (32.2 versus 32.9 ms). It adds the expected GPU work, about
|
||||
**VM4 correction (2026-08-22):** both runs below executed under the connected
|
||||
automation observer (`ACDREAM_AUTOMATION_ARTIFACT_DIR` render-scene oracle),
|
||||
which the Slice H closeout documents as allocating 3.9–10.5 MiB/frame
|
||||
(`alloc_kb p50 = 9,830` here, 31 Gen0 collections in 216 frames). The absolute
|
||||
CPU figures are therefore observer cost, not product cost, and this A/B says
|
||||
nothing about the owner's turning hitch on the product. Clean production
|
||||
numbers (no observer, uncapped Release) are in the
|
||||
[VM0 report](2026-08-22-vm0-default-path-invariance.md): dense Arwic CPU p50
|
||||
6.0 ms pre-campaign vs 5.2 ms pack-off. The paragraph below is kept as the
|
||||
historical record of the Medium-minus-retail increment, which the observer does
|
||||
not distort.
|
||||
|
||||
With that caveat: Medium did not worsen turn CPU p95 under the observer (32.2
|
||||
versus 32.9 ms). It adds the expected GPU work, about
|
||||
0.7–0.9 ms at p95/p50 in this run. The Atmospheric screenshot's pack-owned
|
||||
window reports incremental CPU p50/p95/p99 of 0.209/0.248/0.302 ms, inclusive
|
||||
GPU p50/p95/p99 of 1.374/1.818/1.869 ms, 14,890 casters, three cascades,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ run; decide F2; schedule F3/F4 as follow-ups; then the owner visual gate.
|
|||
|
||||
### F1 — HIGH (evidence): default-path invariance is unproven
|
||||
|
||||
> **CLOSED (VM0, 2026-08-22): PASS.** Exact pixel identity on static content
|
||||
> vs `6c79d35c` (Holtburg + open field) and a clean production perf A/B with no
|
||||
> regression — `2026-08-22-vm0-default-path-invariance.md`.
|
||||
|
||||
The plan says `NoOpRenderPackProductionIntegrationTests` "pins the
|
||||
pre-campaign pass list, pipeline set, draw/dispatch tuple, framebuffer
|
||||
SHA-256". It does — for a **2×2 synthetic framebuffer, one draw call, one
|
||||
|
|
@ -86,6 +90,14 @@ record shows it was run against a `6c79d35c` capture. The six physical
|
|||
|
||||
### F2 — HIGH (process): the #226 fade constants are invented and unregistered
|
||||
|
||||
> **Post-review correction (VM1, 2026-08-22):** "invented" was too strong. The
|
||||
> 10 m → 50 m ramp is a real retail function, `ACRender::get_alpha_for_z`
|
||||
> (0x006b6230). It is, however, dead for the surfaces #226 targets: retail
|
||||
> evaluates it only in `D3DPolyRender::DrawPolyInternal` (immediate polygons)
|
||||
> and only when the static `noFadeDetail` (0x00820e38, initialised 1) is 0;
|
||||
> built meshes light with `Diffuse.a = 1`. The finding's conclusion (remove
|
||||
> it; no register row) stands; the provenance claim is corrected.
|
||||
|
||||
`RetailDetailTextureContract.FullDetailDistanceMetres = 10f` /
|
||||
`ZeroDetailDistanceMetres = 50f` drive `mesh_detail.vert:83`
|
||||
(`clamp((50 − z) / 40, 0, 1)`). The pseudocode note presents "full through
|
||||
|
|
@ -104,6 +116,11 @@ keep it and file the register row naming it an acdream adaptation.
|
|||
|
||||
### F3 — MEDIUM (premise): #226 ports retail's two-pass fallback; which path real hardware ran is undetermined
|
||||
|
||||
> **ANSWERED (VM2, 2026-08-22):** `m_caps.bCanDoSinglePassDetailing = 1`,
|
||||
> `trysinglepass = 1` on the owner's GPU — retail runs the single-pass path.
|
||||
> The reviewer's "probably the fallback" was wrong. See
|
||||
> `2026-08-22-vm2-retail-detail-path-cdb.md`; re-ported at VM1.
|
||||
|
||||
`SetDetailSurfaceInternal` sets the `DSTCOLOR + INVSRCALPHA` framebuffer blend
|
||||
**only when `stage == 0`** (the two-pass fallback). With
|
||||
`m_caps.bCanDoSinglePassDetailing`, `RenderMeshSubset` and `landPolyDraw`
|
||||
|
|
@ -138,6 +155,10 @@ every other tool's controls. Schedule as a slice.
|
|||
|
||||
### F5 — MEDIUM (docs): closeout claims exceed their evidence
|
||||
|
||||
> **CLOSED (VM4, 2026-08-22):** (a)–(d) corrected in place in the AR plan, the
|
||||
> Stage-2 connected report, the Track A report and the findings doc, each with a
|
||||
> dated "VM4 correction" note rather than a silent rewrite.
|
||||
|
||||
a. "Pins the pre-campaign … framebuffer SHA-256" — see F1.
|
||||
b. "The user's turning hitch reproduces on the retail path" is drawn from
|
||||
`connected-dense-town-20260822-133727` (retail/off: CPU p50 **27.8 ms**,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue