fix(render): #226 detail overlay uses retail's single-pass combine; drop the dead distance fade (Campaign VM VM1)
VM2's live cdb read against the PDB-paired retail client (GUID 9e847e2f-777c-4bd9-886c-22256bb87f32) proved m_caps.bCanDoSinglePassDetailing = 1 and trysinglepass = 1 on real hardware, so D3DPolyRender::RenderMeshSubset (0x0059ca10) never falls back to the two-pass framebuffer blend the earlier #226 port reproduced. Every loaded CGfxObj sets use_built_mesh = 1 (CGfxObj::InitLoad 0x005346b0), so buildings and EnvCells always take the single-pass texture-stage combine set up in D3DPolyRender::SetSurface (0x0059c4d0): result = lerp(base * diffuse, detail.rgb, detail.a * diffuse.a) RenderMeshSubset lights opaque built-mesh subsets with tmpmaterial.Diffuse.a = 1, so on the live Dereth category texture 0x06006D58 (mean rgb 0.165, mean alpha 0.132) the combine works out to ~0.868 * base + 0.022 — a mild darkening, the opposite sign of the fallback DstColor blend's brightening. Also removes the invented 10 m / 50 m distance fade. Retail's ACRender::get_alpha_for_z (0x006b6230) is only evaluated in D3DPolyRender::DrawPolyInternal (0x0059d7c0, the immediate-polygon path) and only when the static noFadeDetail (0x00820e38, initialised to 1) is 0 — unreachable for built meshes. Attenuation is the sampler's linear mip chain converging to the texture mean, not a scripted ramp. Changes: - mesh_detail.vert/.frag: drop vDetailFade and its distance term; add vDetailOpacity mirroring mesh_modern.vert's InstanceAlphaBuf (binding 7) read, and output detail.rgb with alpha = detail.a * vDetailOpacity under the corrected pipeline blend. - VulkanViewportMapping.BlendFactorsOf / GpuEnums.GpuBlendMode.RetailDetail: SrcAlpha + OneMinusSrcAlpha instead of DstColor + OneMinusSrcAlpha. - RetailDetailTextureContract: replaced the distance-fade constants and FramebufferFactor with Expected(base, detail, opacity) and IsNeutral, matching the lerp; contract tests cover zero-alpha/zero-opacity no-ops, the measured darkening on the live category texture, and full-alpha replacement. - Regenerated mesh_detail's committed SPIR-V and the shader manifest (tools/compile-shaders.ps1); no other shader pair changed. - Docs: #226's pseudocode note, the docs/ISSUES.md #226 entry, and the retired TS-52 divergence-register row corrected from the two-pass DESTCOLOR description to the single-pass path and the darkening expectation, each citing the VM2 cdb note. Verified: dotnet build AcDream.slnx -c Release (0 warnings, 0 errors); dotnet test on AcDream.App.Tests and AcDream.Core.Tests (Release, hermetic lanes) both green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
30e72a2af8
commit
059703066f
13 changed files with 266 additions and 128 deletions
|
|
@ -9207,7 +9207,11 @@ the full 6,558-pass / 5-skip suite remains green.
|
|||
|
||||
## #226 — Retail building/EnvCell detail-texture overlay is not rendered
|
||||
|
||||
**Status:** IMPLEMENTED + CONNECTED-VISUAL-VERIFIED 2026-08-21
|
||||
**Status:** IMPLEMENTED + CONNECTED-VISUAL-VERIFIED 2026-08-21; re-ported to
|
||||
the single-pass path 2026-08-22 by Campaign VM VM1 after VM2's live cdb read
|
||||
found retail hardware never takes the two-pass fallback this issue originally
|
||||
ported (see
|
||||
[`docs/research/2026-08-22-vm2-retail-detail-path-cdb.md`](research/2026-08-22-vm2-retail-detail-path-cdb.md)).
|
||||
**Severity:** LOW
|
||||
**Filed:** 2026-07-20
|
||||
**Component:** rendering / building and environment materials
|
||||
|
|
@ -9224,8 +9228,12 @@ mechanisms. `bb5acab9` ported the behavior that produced the observed mismatch:
|
|||
`TexMerge::CopyAndTile`/`Merge` pass each source's authored base tiling into the
|
||||
terrain composition. #226 now resolves Dereth category 1/2 detail surfaces,
|
||||
uploads their authored texture/tiling with retail wrap/linear sampling, and
|
||||
replays building and EnvCell built-mesh subsets with the exact
|
||||
`DESTCOLOR + INVSRCALPHA` blend. This includes opaque, ClipMap, straight-alpha,
|
||||
replays building and EnvCell built-mesh subsets with retail's single-pass
|
||||
detail combine (VM1/VM2, 2026-08-22): `SRCALPHA + INVSRCALPHA` compositing
|
||||
`lerp(base * diffuse, detail.rgb, detail.a * diffuseAlpha)`, matching the
|
||||
`bCanDoSinglePassDetailing = 1` path real hardware runs — not the two-pass
|
||||
`DESTCOLOR + INVSRCALPHA` fallback the port originally reproduced. This
|
||||
includes opaque, ClipMap, straight-alpha,
|
||||
additive, and inverse-alpha material subsets; transparent base/detail commands
|
||||
remain adjacent in acdream's authoritative shared alpha order with depth writes
|
||||
disabled (retail bypasses delayed alpha while detail is installed; retaining
|
||||
|
|
@ -9253,10 +9261,12 @@ its evidence source is
|
|||
|
||||
**Acceptance:** Toggling the existing “Building Detail Textures” checkbox
|
||||
visibly changes nearby building and interior surfaces without a restart.
|
||||
Enabled detail is full through 10 m positive view depth, fades linearly to an
|
||||
exact no-op at 50 m, and preserves retail's measured slight brightening.
|
||||
Disabling it submits no detail replay and preserves the already-accepted base
|
||||
render. Landscape, ordinary objects, physics, and collision remain unchanged.
|
||||
There is no distance fade (VM1/VM2: retail's `get_alpha_for_z` is unreachable
|
||||
for built meshes; attenuation is the sampler's linear mip chain), and the
|
||||
single-pass combine darkens the live category texture by roughly 10% on
|
||||
mid-tones rather than brightening it. Disabling it submits no detail replay
|
||||
and preserves the already-accepted base render. Landscape, ordinary objects,
|
||||
physics, and collision remain unchanged.
|
||||
The automated gates cover the setting gate, data/blend/fade contract,
|
||||
built-mesh subset eligibility, opaque command filtering and A2C coverage,
|
||||
transparent depth/order seam, Vulkan descriptor
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue