#118: outdoor dynamics draw in the outside stage under interior roots - the house-exit clip+vanish was the SEAL z-killing the player
Root cause (pinned by the new deterministic exit-walk harness, NOT guessed):
under an interior render root, the exit-portal SEAL stamps the door fan at
TRUE depth after the gated full depth clear, and T1's "ALL dynamics last"
pass then drew the outdoor-classified player depth-tested - every fragment
beyond the door plane z-failed against the seal across the whole aperture.
Harness measured the full window: from the moment the sphere center crosses
the plane until the eye follows (~2.6 m of camera lag, ~2.2 s at walk speed)
the player is invisible; while straddling, the beyond-plane body half clips
at the plane. The handoff's three cone-level candidates are all EXONERATED:
the cone walk passes every step; (eye, ViewerCellId) come from the same
SweepEye call with camera-update-before-visibility-read in the same frame;
the side-test window is sub-epsilon under healthy resolution.
Retail oracle (grep-named-first): PView::DrawCells 0x005a4840 runs
LScape::draw FIRST (pc:432719), then the gated depth clear (pc:432731-32)
and the exit-portal seals (pc:432785-86); outdoor cell objects draw inside
the landscape stage (DrawBlock 0x005a17c0 -> DrawSortCell pc:430124), and
an object draws once per overlapped shadow cell (pc:430056-64) - the
straddling body composes from both stages, neither half clips.
Fix: RetailPViewRenderer assigns dynamics to the OUTSIDE stage under an
interior root when outdoor-classified OR sphere-straddling an exit-portal
plane of their flood-visible cell (DynamicDrawsInOutsideStage - pure, the
harness drives it as the ordering contract); they ride the landscape slice
draw (pre-clear, seal-protected) with the same per-slice cone test as
outdoor statics. Indoor dynamics keep the last pass (retail loop C);
straddlers draw in both (retail shadow dual-draw). Outdoor roots keep
all-dynamics-last - the BR-2 punch-after-dynamics lesson (88be519) stands.
Apparatus: HouseExitWalkReplayTests - dat-backed corner-building exit walk
driving the production stack headlessly (RetailChaseCamera damping ->
healthy-sweep viewer resolution -> PortalVisibilityBuilder.Build ->
ClipFrameAssembler -> ViewconeCuller -> the DrawDynamicsLast predicate +
a CPU seal-depth model). 5 tests: cone pin, seal-depth pin, straddle
dual-draw pin, per-step table, stale-root window quantifier (#118 cand 2).
Suites: App 232 (227+5), Core 1416+2skip, UI 420, Net 294.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
acaaeae434
commit
5a80a2ee24
5 changed files with 628 additions and 10 deletions
|
|
@ -3937,7 +3937,36 @@ AFTER the punch. Compare against the T1 (`579c8b0`) punch pass wiring.
|
|||
|
||||
## #118 — Character clipped + disappears for a moment when exiting houses
|
||||
|
||||
**Status:** OPEN
|
||||
**Status:** FIXED 2026-06-11 — pending visual re-gate
|
||||
|
||||
**Root cause (pinned by the exit-walk harness, `HouseExitWalkReplayTests`):**
|
||||
NOT the cone stack — candidates 1–3 all exonerated (cone-level walk passes
|
||||
every step; the camera publishes (eye, ViewerCellId) from the SAME SweepEye
|
||||
call and updates before the visibility read, so the pair is coherent; the
|
||||
side-test window is ≤ PortalSideEpsilon and never occurs under healthy
|
||||
resolution). The mechanism is DEPTH ORDERING: under an interior root, the
|
||||
exit-portal SEAL stamps the door fan at TRUE depth after the full depth
|
||||
clear, and T1's "ALL dynamics last" then draws the outdoor-classified player
|
||||
depth-tested — every fragment beyond the door plane z-fails against the seal
|
||||
across the whole aperture. Full vanish once the center exits (harness: the
|
||||
entire s=0.04→2.64 m window until the eye crosses, ~2.2 s at walk speed);
|
||||
the body's beyond-plane half clips at the plane while straddling.
|
||||
|
||||
**Retail oracle:** PView::DrawCells (0x005a4840) runs LScape::draw FIRST
|
||||
(pc:432719), THEN the gated depth clear (pc:432731) + seals (pc:432786);
|
||||
outdoor cell objects draw inside the landscape stage via DrawBlock →
|
||||
DrawSortCell (0x005a17c0, pc:430124), and an object draws once per
|
||||
overlapped shadow cell (pc:430056-430064) — so a threshold-straddling body
|
||||
draws in both stages and neither half clips.
|
||||
|
||||
**Fix (`RetailPViewRenderer`):** under an interior root, outdoor-classified
|
||||
dynamics draw in the OUTSIDE (landscape) stage — before the clear+seal, so
|
||||
the seal protects their pixels — and indoor dynamics whose sphere straddles
|
||||
an exit-portal plane draw in BOTH stages (`DynamicDrawsInOutsideStage`).
|
||||
Outdoor roots keep all-dynamics-last (the BR-2 punch lesson). Pins:
|
||||
`ExitWalk_PlayerStaysConeVisible_EveryStep`,
|
||||
`ExitWalk_PlayerSurvivesSealDepth_WhenConeVisible`,
|
||||
`ExitWalk_StraddlingPlayerDrawsInOutsideStage`.
|
||||
**Severity:** MEDIUM-HIGH (every house exit, brief)
|
||||
**Filed:** 2026-06-11 (T5 comprehensive gate, user item 10)
|
||||
**Component:** render — dynamics handling at the indoor→outdoor transition
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue