fix #129: cap the punch mark bias's eye-space reach (was unbounded at distance)

The user's "doors/doorways leak through terrain and houses over a
landblock" is the #117 mark-pass bias evaluated in the wrong space.

Mechanism (confirmed analytically, Issue129PunchBiasTests): the punch's
pass-A stencil mark biased the aperture fan toward the viewer by a
CONSTANT 0.0005 NDC. NDC depth is non-linear - a constant NDC bias b
spans ~= b*d^2*(f-n)/(f*n) meters of eye depth at eye distance d. With
retail's znear 0.1 (d4b5c71) that is 0.125 m at 5 m but ~190 m at one
landblock: every hill/house in front of a distant aperture passed the
LEQUAL mark and was far-Z punched -> door-shaped leak through the
occluder. This is exactly the risk AD-18's register row recorded
("an occluder within ~bias in front of a distant aperture gets punched
through") - the symptom-scan rule found it before instrumentation.

Fix: cap the bias's EYE-SPACE span at 0.5 m -
  biasNdc(d) = min(0.0005, capMeters * near / d^2)
in the mark-pass vertex shader (clipPos.w = eye depth), CPU-mirrored as
PortalDepthMaskRenderer.MarkBiasNdc for tests. Below the ~10 m
crossover the constant-NDC term is smaller and wins - bit-identical to
the T5-validated close-range behavior, so the #108 grass coverage that
justified the bias is untouched. Beyond it the punch can never reach an
occluder more than 0.5 m in front of the aperture plane.

Pins (Issue129PunchBiasTests): the old form spans >100 m of eye depth
at a landblock (the leak, kept as documentation of the refuted shape);
the capped form stays <= 0.5 m at every distance 1-400 m and matches
the validated constant bit-for-bit below 10 m.

AD-18 register row updated in the same commit (bias description + the
#129 closure + the residual risk note: door-hugging geometry beyond the
0.5 m cap at >10 m viewing range re-occludes - the cap constant is the
tuning knob if the gate shows residue).

Suites: App 256+1skip / Core 1439+2skip / UI 420 / Net 294 green.
Awaiting the user visual gate at the original spot (+ #108 cellar
re-check up close).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-12 13:38:59 +02:00
parent 6c4b6d64d9
commit 4ba714835d
4 changed files with 134 additions and 25 deletions

View file

@ -4477,36 +4477,38 @@ staircase entity's per-frame draw decision.
## #129 — Doors/doorways leak through terrain and houses from over a landblock away
**Status:** OPEN
**Status:** FIX SHIPPED — awaiting user visual gate
**Severity:** MEDIUM (visible at distance during normal outdoor play)
**Filed:** 2026-06-12 (user report, post-#119-close session)
**Component:** render — aperture depth punch at distance (#117 family)
**Component:** render — aperture depth punch at distance (#117 family, AD-18)
**Symptom (user):** "leakage of like doors and doorways through the
terrain and houses over a landblock" — door/doorway-shaped patches
visible THROUGH intervening terrain and nearer buildings when the
source building is roughly a landblock (~192 m) or more away.
**Leads:**
1. **The #117 stencil depth-gate bias at long range (top suspect).**
#117's fix (`478c549`) marks aperture pixels at biased true depth
(LEQUAL, bias 0.0005 NDC) then far-Z punches only marked pixels. With
a non-linear depth buffer, 0.0005 NDC at ~200 m spans many METERS of
view depth — the bias can exceed the separation between the aperture
and a hill/house in front of it, marking occluder pixels and punching
them → the occluder shows the interior/background behind. The #108
coverage constraint pulls the bias up; distance pulls it wrong —
re-derive the bias in eye-space (or scale by w) instead of constant
NDC.
2. Per-building look-in floods admitting distant buildings (the #127
churn family) — would gate WHICH buildings punch, not the
through-occluder leak itself.
**Root cause (lead 1 confirmed analytically, `Issue129PunchBiasTests`):**
the #117 mark-pass bias was a CONSTANT 0.0005 NDC. NDC depth is
non-linear — a constant NDC bias `b` spans ≈ `b·d²/near` meters of eye
depth at distance `d`. With retail's znear 0.1 that is 0.125 m at 5 m
but **~190 m at a landblock**: every hill/house in front of a distant
aperture passed the LEQUAL mark and was far-Z punched → the door-shaped
leak. Exactly AD-18's recorded "Risk if assumption breaks".
**Next:** capture at the spot (ACDREAM_PROBE_VIEWER=1 + a screenshot +
player/eye position from [snap]/[viewer]); confirm whether the leak
patch matches an aperture polygon of the distant building; then test
the eye-space-bias hypothesis headlessly (the #117 commit has the bias
math).
**Fix (2026-06-12):** cap the bias's EYE-SPACE span —
`biasNdc(d) = min(0.0005, 0.5 m × near / d²)`
(`PortalDepthMaskRenderer.MarkBiasNdc`, mirrored in the vertex shader).
Below the ~10 m crossover the constant term wins, bit-identical to the
T5-validated behavior (#108 grass coverage untouched); beyond it the
punch can never reach an occluder more than 0.5 m in front of the
aperture plane. Pins: `Issue129PunchBiasTests` (old form spans >100 m
at a landblock; capped form ≤0.5 m at all distances; close range
unchanged).
**Gate:** the original spot — distant building doors no longer show
through terrain/houses at ~a landblock; AND the #108 cellar grass-sweep
stays gone up close. If a >10 m-range #108-class residue appears, the
cap constant (0.5 m) is the tuning knob — see AD-18.
---