fix(rendering): preserve opaque building coverage under detail MSAA (#473)
This commit is contained in:
parent
d35ed1aece
commit
bf23673f3d
7 changed files with 387 additions and 46 deletions
|
|
@ -41,7 +41,8 @@ remain closed. See
|
|||
|
||||
## #473 — Owner gate: exterior buildings have missing roof/wall sections
|
||||
|
||||
**Status:** IN-PROGRESS — owner visual gate FAIL, 2026-09-05.
|
||||
**Status:** IN-PROGRESS — bounded code repair complete; owner visual re-gate
|
||||
pending, 2026-09-05.
|
||||
|
||||
At clean campaign `02219318a`, Release 0 warnings / 0 errors, the owner
|
||||
reports broken exterior buildings in Holtburg and the cathedral, while
|
||||
|
|
@ -52,7 +53,12 @@ A reachable draw-state defect is now identified (packet section42): detail
|
|||
final alpha is wrongly converted into MSAA sample coverage on opaque Wb
|
||||
exteriors. The owner's 4x/A2C=true log and installed detail alpha24..46/255
|
||||
exercise that path. Interior EnvCell disables A2C. A bounded pipeline repair
|
||||
and actual exterior re-gate remain; no claim that all symptoms are fixed yet.
|
||||
now forces the shared detail-active opaque Wb command onto the non-A2C opaque
|
||||
pipeline while retaining pure Clip's AP-240 quality-selected arm. Actual
|
||||
ordered and classic grouped recording tests cover ordinary/atmospheric 1x/4x,
|
||||
including a mixed ordinary/building instance command, and the old-arm mutation
|
||||
fails 12/12 discriminators. The actual exterior re-gate remains; no claim that
|
||||
all symptoms are fixed yet.
|
||||
|
||||
Evidence: `research/2026-09-01-overhaul/owner-gate-20260905-holtburg-fail.png`;
|
||||
manual session `logs/owner-gate-20260905-02219318a/`, PID18836, verified
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ builder, reducing the current active total to **160**.
|
|||
|
||||
| # | Divergence | Where (file:line) | Why it is safe / justified | Risk if assumption breaks | Retail oracle |
|
||||
|---|---|---|---|---|---|
|
||||
| ~~AP-245~~ | **FILED AND CODE-RETIRED 2026-09-05 by #473 / Campaign OVERHAUL §42.** S5-c4's shared detail-active Wb selector reused the quality-selected opaque pipeline for `RetailSetSurfaceBlend.Opaque`. With 4x MSAA and A2C enabled, the shader's retail final detail alpha `X = a*qA*qA` therefore became sample coverage even though retail's ordinary opaque SetSurface state is ONE/ZERO without alpha test. The selector now uses the non-A2C `pipelines.Opaque` for every detail-bearing opaque command; pure Clip retains AP-240's `opaquePipeline`. A classic command may contain both ordinary and building-detail instances because detail category is per instance rather than part of `GroupKey`; such a command is correctly non-A2C as a whole while its shader still filters detail per instance. | `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.Rhi.cs` (`PipelineForMaterial`); `tests/AcDream.App.Tests/Rendering/Walk/OrderPreservingSubmitterTests.cs` | The correction is one shared material-selection arm reached by the actual ordered and classic grouped submitters. Recording tests cover ordinary/atmospheric 1x/4x descriptors, draw order/count, depth and detail pushes; detail unavailable/disabled and quality A2C=false stay unchanged. | None for the retired code divergence. The owner exterior gate remains FAIL until the repaired exact binary passes the required real re-gate; this row does not claim GPU or owner acceptance. | `D3DPolyRender::SetSurface @0x0059C4D0` opaque ONE/ZERO arm; Campaign OVERHAUL §42 |
|
||||
| AP-244 | **Filed 2026-09-05 at Campaign OVERHAUL S5-c4 fix round 1.** The new exact resolved SetSurface state is deliberately selected only when a Wb/EnvCell command has active building detail, preserving §23's bounded detail-off behavior. With detail off, Wb still collapses raw Additive and InvAlpha+Additive through `TranslucencyKind.Additive` to `SRCALPHA,ONE`; EnvCell additionally selects raw `IsAdditive` before the late `Translucent\|ClipMap` override and has no detail-off inverse pipeline. Both shader families retain the existing non-detail 0.05 discard rather than every combined ClipMap's palette/DDS reference, and fixed-function fog remains enabled for raw-Additive detail-off rows. AP-240 separately covers Wb pure-Clip placement/A2C. | `src/AcDream.App/Rendering/Wb/WbDrawDispatcher.Rhi.cs` (`PipelineForBlend`, detail gates); `src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs` (`ResolveBatchGroupIndex`); `src/AcDream.App/Rendering/Wb/EnvCellRenderer.Rhi.cs` (detail-active exact selection versus retained range buckets); `src/AcDream.App/Rendering/Shaders/mesh_modern.frag`; `src/AcDream.App/Rendering/Shaders/mesh_atmospheric.frag` | Fix round 1 was expressly bounded to detail-active one-pass material truth. The immutable state is already present end-to-end, so a later dedicated detail-off correction can select it without DAT lookup or new ownership, but must re-gate FIFO/routing/order and visual behavior together. | Detail-off raw Additive/inverse-additive brightness, inverse EnvCell compositing, combined ClipMap cutout threshold, late Translucent override, and raw-Additive fog can differ from retail. | `D3DPolyRender::SetSurface @0x0059C4D0` lines 425083–425303; Campaign OVERHAUL S5-c4 §23.2 |
|
||||
| AP-235 | **Filed 2026-08-25 at the Campaign CT4 fix round.** Retail resolves gender display text via `AppraisalSystem::InqGenderDisplayName @0x005b47c0` and heritage via `InqHeritageGroupDisplayName @0x005b4710`, both through the static `EnumMapper::GetString(uint32_t enumValue, uint32_t queryId, PStringBase<char>*) @0x0041ac40` overload — `DBObj::GetDIDByEnum(&did, enumValue, 1)` (master map `0x25000000` → category-1 sub-map `0x25000001` → `ClientEnumToID[0x10000001]`/`[0x10000002]` → EnumMapper DIDs `0x2200000A`/`0x2200000B`) — reading each id's `IdToStringMap` entry live, with heritage ids 2/5/0xd hardcoded to `"Gharu'ndim"`/`"Umbraen"`/`"Olthoi"` in place of the raw internal names `"Gharundim"`/`"Shadowbound"`/`"OlthoiAcid"`. `CharacterIdentityText.GenderDisplayName`/`HeritageGroupDisplayName` are hardcoded C# `switch` tables instead — a mechanism divergence (compile-time constant vs. live DAT read), not a content one: `CharacterPanelLiveDatTests.GenderHeritageDisplayNameTables_MatchTheRetailEnumMapperChain` (filed the same round) walks the live EnumMapper chain and asserts every table entry byte-exact, including the two entries (10 "Penumbraen", 12 "Olthoi") the CT4 review had flagged as unverified guesses — both are correct. | `src/AcDream.App/UI/Layout/CharacterIdentityText.cs` (`GenderDisplayName`, `HeritageGroupDisplayName`); `src/AcDream.App/UI/Layout/RetailAppraisalNameResolver.cs` (`ResolveHeritage` — CT5 fix round 2026-08-25 deleted its independent re-implementation of the same 2/5/13 overrides; it now delegates straight to `CharacterIdentityText.HeritageGroupDisplayName`, so this row's divergence has exactly ONE owner, not two) | `RetailDataIdResolver.Resolve` (`src/AcDream.Content/RetailDataIdResolver.cs`) already ports the generic two-level `GetDIDByEnum` chain (used today for layout/material DIDs); unifying gender/heritage onto it needs only `Resolve(dats, enumValue: 0x10000001u/0x10000002u, enumCategory: 1u)` plus an `EnumMapper.IdToStringMap` read — a live-DAT-only path with no bespoke traversal code to write, which is why the tables stayed hardcoded this round rather than porting live-read on the spot; CT5 is the natural landing slot since it already owns this same DAT-lookup family for the Titles page | A future DAT/game update that renames or reorders a heritage/gender enum entry would silently desync acdream's hardcoded tables from retail's live text with no build-time or runtime signal — the CT5 fix round retired the second-copy drift risk (`ResolveHeritage` now reads the same single table), but the core hardcoded-vs-live-DAT divergence itself remains open | `AppraisalSystem::InqGenderDisplayName @ 0x005B47C0`; `InqHeritageGroupDisplayName @ 0x005B4710`; `EnumMapper::GetString @ 0x0041AC40`; `DBObj::GetDIDByEnum @ 0x004153A0` |
|
||||
| AP-233 | **Filed 2026-08-23 at the Holtburg windmill fix (row owed since the R1-P5 sequencer cutover).** `AnimationSequencer.BuildBlendedFrame` blends each part between `floor(FrameNumber)` and the next frame in the playback direction using the retail slerp (`SlerpRetailClient`). Retail never blends animation frames: `CPartArray::UpdateParts` applies `CSequence::get_curr_animframe` = `get_part_frame(floor(frame_number))`, holding every authored 30 fps frame for its whole interval. Since 2026-08-23 the blend holds the boundary frame at BOTH ends of a node's window — including the cyclic seam — so a cycle's last→first transition is retail's hard cut, not a blend. | `src/AcDream.Core/Physics/AnimationSequencer.cs` (`BuildBlendedFrame`); tests `AnimationSequencerTests.Advance_LinkTailDoesNotBlendIntoLinkFrame0` (#61), `Advance_CyclicSeamHoldsLastFrameInsteadOfBlendingIntoFrame0` (windmill) | The blend only smooths between authored interior frames of one node; at every seam the pose is exactly retail's held frame. Authored cycles that loop by symmetry (the Holtburg windmill's 60-frame quarter turn, `0x0300061B`) or by design read identically at the seam; link tails hold their end pose (#61). The owner chose this over dropping the blend (retail's 30 fps stepping) on 2026-08-23. | Any two adjacent authored frames that are NOT meant to be traversed smoothly (a deliberate authored pop inside a node) would be smoothed where retail pops; none known. A per-frame hitch of one held 33 ms interval at each cycle seam is the price of the cut (1.5° on the windmill). | `CPartArray::UpdateParts @0x005190F0`; `CSequence::get_curr_animframe @0x00524970`; `CSequence::get_curr_frame_number @0x005249D0` |
|
||||
|
|
|
|||
|
|
@ -696,7 +696,7 @@ Update immediately when a slice changes state. Chat is not the ledger.
|
|||
| S5-#470 | **LANDED + REVIEW-CLOSED 2026-09-05; LEAD GRAPHICAL A/B PROVISIONAL PASS.** Campaign implementation stack `15a796c3a` -> `7506e5f14` -> `b333edb4f`; route `19b44e5e3`; reviewed scratch `51f974da4` -> `2cad9c84` -> `98c004aa7`; packet §§27–30. | G4 UNPASSED | Retail/behavior pass 2/10 and production pass 4/10 closed the two evidence-only findings. Fresh campaign Release 0W/0E and focused 48/48; exact scratch hermetic 16,976/16,976 and canonical InstalledDat 386/10/1, manifests 30/30. Pinned gate `logs/selfgate-20260905-032132-s5-470-pinned-shadow-ab-r1`: retail/off -> High -> retail/off, 3/3 PNGs, exit 0, graceful, no client; visual PASS provisional. The stale recipe-8 pre-route launch is excluded and recorded in §30. |
|
||||
| S5-#469 | **LANDED + REVIEW-CLOSED 2026-09-05; LEAD GRAPHICAL TRANSITION PROVISIONAL PASS.** Contract `809887524`; reviewed scratch `c09b6cf0f`; campaign implementation `94ddde69a`; route `62efc72cb`; packet §§31–32. | G4 UNPASSED | Retail/deviation pass 1/10 and production pass 2/10 both PASS with no finding. The two atmospheric vertex receivers keep retail's authored unnormalized `uLights` direction across every shadow gate; celestial direction remains for opt-in shadow/volumetric projection; IA-24 corrected in the same commit. Exact scratch: Release 0W/0E, focused 126/126, Vulkan 2/2, hermetic 16,983/16,983, InstalledDat 386/10/1. Fresh campaign Release 0W/0E, focused 82/82, Vulkan 2/2. Gate `logs/selfgate-20260905-040449-s5-469-lighting-transition-r1`: five PNGs, active 2,500-caster/four-cascade High rows, no near-black relight, exit 0/graceful, no client; visual PASS provisional. |
|
||||
| S5-c5 | **CLOSED + LANDED 2026-09-05; LEAD GRAPHICAL SMOKE PROVISIONAL PASS.** Contract `b77989c32`; campaign `bf53e2ad6` -> `e625dc4e6` -> `1b7ee4e58`; reviewed scratch tip `158656f0d`; packet §§33–35. | G4 UNPASSED | Retail/deletion pass 1/10 PASS. Production pass 2/10 found one static-field hole in the owner guard; fix round 1 reproduced both static-owner mutations, and production pass 3/10 PASS. Exact scratch hermetic 16,921/16,921, canonical InstalledDat 368/9/1, manifests 30/30. Fresh campaign Release 0W/0E, App 146/146, Core 8/8. A stale recipe-8 preflight is excluded; a non-destructive recipe-10 bake produced 2,237,865 keys with zero failures. Corrected gate `logs/selfgate-20260905-052130-s5-c5-landed-v10`: five PNGs, exit 0/graceful, no fatal/deleted-prefix match, no client left; geometry matches S5-c4, visual PASS provisional. |
|
||||
| S5 | **OWNER VISUAL GATE FAIL — #473 exterior roof/wall sections missing (2026-09-05).** c1–c5 plus #470/#469 landed; prior self-PASS is not owner acceptance. C1 offline evidence complete; C1c test correction frozen pending review. | G4 | Packet §§7 and 12–42 bind. Owner's clean02219318a Release/recipe10 gate failed Holtburg/cathedral exteriors; Facility interiors appear correct. §42 contracts the identified detail-active opaque A2C pipeline repair. The 4x/A2C=true owner path converts low detail alpha into lost coverage; a tested repair and correctly framed exterior re-gate remain. Prior screenshots did not cover complete exteriors. After repair/reviews/re-gate: C1c review/landing, real geometry/membership hash, full-lane closure, C2 and full owner G4 remain. Never merge main before G4. |
|
||||
| S5 | **OWNER VISUAL GATE FAIL — #473 code-repaired and review-closed; exterior re-gate pending (2026-09-05).** c1–c5 plus #470/#469 landed; prior self-PASS is not owner acceptance. C1 offline evidence complete; C1c test correction frozen pending review. | G4 | Packet §§7 and 12–42 bind. §42 repairs detail-active opaque A2C coverage loss at the owner's 4x/A2C=true settings. Both independent review lenses PASS; 45 focused/46 register-inclusive/158 adjacent tests pass; restored old-arm mutation fails12/12. All52 affected base/LOD prepared payloads match fresh extraction. Correctly framed full Holtburg/cathedral exterior PNG re-gate remains; prior images were inadequate. Then C1c review/landing, real geometry/membership hash, full-lane closure, C2 and full owner G4 remain. Never merge main before G4. |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -4010,3 +4010,66 @@ PASS/FAIL; close only the lead's own session gracefully. Lead PASS remains
|
|||
provisional until the owner re-gates. Keep #473 open if rendered sections
|
||||
remain missing, even if the narrow tests pass. No merge main; C1c and all
|
||||
remaining closeout/G4 obligations resume only after this failure is handled.
|
||||
|
||||
### 42.4 Implementation return — uncommitted, pending review and real re-gate
|
||||
|
||||
At base `d35ed1aec`, the bounded production repair changes only
|
||||
`PipelineForMaterial`'s detail-active Opaque arm from `opaquePipeline` to
|
||||
`pipelines.Opaque`; the pure Clip arm and every shader, prepared-data,
|
||||
geometry, LOD, queue and recipe path are unchanged. The actual ordered and
|
||||
classic grouped recording paths now cover ordinary and atmospheric pipeline
|
||||
sets at 1x and 4x. They pin exact non-A2C/A2C descriptors, opaque depth state,
|
||||
draw order/count and detail push fields. The classic proof also includes one
|
||||
real mixed command with detail categories `[0,1]`: because category is not in
|
||||
`GroupKey`, the whole detail-bearing command uses non-A2C while the shader's
|
||||
per-instance category still controls detail sampling. Detail unavailable,
|
||||
detail disabled and quality A2C=false remain on their pre-repair selections.
|
||||
|
||||
The old-arm mutation (`Opaque => opaquePipeline`) failed all 12 selected
|
||||
ordered/classic cases. The first ordered failure expected
|
||||
`wb-mesh-opaque` at pipeline transcript position 2 but received
|
||||
`wb-mesh-opaque-a2c`; the first classic failure expected
|
||||
`wb-mesh-atmospheric-opaque-1x` at position 1 but received
|
||||
`wb-mesh-atmospheric-opaque-a2c-1x`. The mixed-command discriminator likewise
|
||||
expected non-A2C and received A2C. The one-line repair was restored and the
|
||||
complete `OrderPreservingSubmitterTests` class passed 45/45 in Release.
|
||||
`dotnet build AcDream.slnx -c Release --no-restore` then completed with zero
|
||||
warnings and zero errors. A final no-build run of that class plus the existing
|
||||
register/count guard passed 46/46. `git diff --check` is clean. No client was
|
||||
launched; JSON preflights before each build/test found no AcDream, retail or
|
||||
debugger process and ACE UDP9000 PID13340. The owner gate remains FAIL and the
|
||||
required exact-binary exterior re-gate is pending sequential review and lead
|
||||
execution.
|
||||
|
||||
### 42.5 Lead review closure — graphical acceptance still pending
|
||||
|
||||
Sequential independent OpenAI review round1 passed both lenses without
|
||||
findings: Rawls checked named SetSurface, paired PE bytes, installed detail
|
||||
alpha, callers and retained material behavior; Wegener checked production
|
||||
reachability, state/order/ownership, actual dispatcher tests and gate honesty.
|
||||
The lead independently read the complete six-file diff, verified the same
|
||||
retail byte ranges and TRX mutation failures, and ran the adjacent existing
|
||||
material suite: 158/158 passed, zero skipped. Exact result files are under
|
||||
`tests/AcDream.App.Tests/TestResults/`: `s5-473-old-arm-mutation.trx` (0/12),
|
||||
`s5-473-focused-restored-final.trx` (45/45),
|
||||
`s5-473-focused-and-register-final.trx` (46/46), and
|
||||
`s5-473-lead-adjacent-material.trx` (158/158).
|
||||
|
||||
The tested candidate App.dll and the test directory's App.dll were identical:
|
||||
6F8890AA5E7FA16641EB5E9AB8CEDAC748E9CD5084853964EDCB5512EBE48E71.
|
||||
This is pre-commit candidate identity, not the subsequent graphical binary.
|
||||
Lead independently expanded the installed A9B4/F418 base/nonzero-LOD union
|
||||
and compared fresh canonical extraction against the actual recipe10 package:
|
||||
all52 complete ObjectMeshDataSerializer payloads match, no missing or corrupt
|
||||
read and no differing payload. This rules out that package/extractor mismatch
|
||||
for these meshes, not GPU upload or final coverage. It is not a replacement
|
||||
for C1's real placed geometry/membership witness.
|
||||
|
||||
No review finding or implementation fix round was needed. Mixed classic
|
||||
commands use one non-A2C opaque pipeline for all instances if any has detail;
|
||||
only wholly unarmed commands/global detail-off preserve quality-selected A2C.
|
||||
The owner expressly authorized closing/testing. Their original process had
|
||||
already exited gracefully without lead input. Lead may now commit, rebuild
|
||||
Release with no client present and execute the correctly framed exterior gate.
|
||||
Owner FAIL remains authoritative until that rendered result is inspected;
|
||||
there is no G4 or physical-GPU PASS in this review closure.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue