#117: depth-gate the aperture punch - stencil mark+punch (z-buffered equivalent of retail's painter's order)
T5 reported doors/interiors visible through terrain hills and through
nearer buildings, always in aperture-shaped regions. Root cause, decomp-
settled: retail's DrawPortalPolyInternal (Ghidra 0x0059bc90) draws the
punch with DEPTHTEST_ALWAYS + per-vertex far-Z (0.99999899, maxZ1 bit0)
- it UNCONDITIONALLY stomps any occluder depth at aperture pixels.
Retail is safe only because its outdoor pass is painter's-ordered
far->near: anything nearer (hills, closer houses) draws AFTER the punch
and re-covers it. Our z-buffered MDI frame has no such global order
(one terrain pass + one shells pass), so the faithful GL-state port of
the punch was unsafe by construction - the far house's aperture punch
erased the near house's wall depth / the hill's depth, and the interior
+ door entities (dynamics drawn last) painted through.
Fix - the z-buffer-correct equivalent of the painter's-order guarantee:
punch only where the aperture polygon itself is VISIBLE.
PortalDepthMaskRenderer's punch path is now two passes:
A) stencil-mark: aperture fan at its (slightly biased) true depth,
depth LEQUAL, no depth write -> stencil=1 where the aperture wins
against everything drawn so far (terrain + all shells precede
DrawExitPortalMasks in the frame, so the buffer holds the real
occluders);
B) far-Z punch with depth ALWAYS, stencil-gated EQUAL 1, zeroing the
stencil as it goes (self-cleaning; no frame-level stencil state).
The mark bias (0.0005 NDC ~ 6 cm at 5 m) keeps #108's case covered:
terrain hugging the door plane still punches; a hill or another house
meters nearer no longer does. The SEAL path (interior roots) stays
retail-verbatim single-pass - it runs right after the gated full depth
clear, so there is nothing nearer to stomp.
Also: WindowOptions now requests 8 stencil bits explicitly (was the
GLFW platform default), and PortalDepthMaskRenderer's stale "RESERVED -
not wired" banner is corrected (T1 wired it via
DrawRetailPViewPortalDepthWrite).
Acceptance rides the focused post-T5 re-gate (downhill door check +
behind-house openings check + #108 cellar stays clean).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
2d15084243
commit
478c549b9e
2 changed files with 87 additions and 19 deletions
|
|
@ -926,6 +926,11 @@ public sealed class GameWindow : IDisposable
|
|||
// Cannot be changed at runtime; Quality changes mid-session that would
|
||||
// alter MsaaSamples are logged as a restart-required warning.
|
||||
Samples = startupQuality.MsaaSamples,
|
||||
// #117 (2026-06-11): the aperture punch's depth gate needs a
|
||||
// stencil buffer (PortalDepthMaskRenderer two-pass mark+punch).
|
||||
// GLFW defaults to 8 stencil bits, but make the requirement
|
||||
// explicit rather than platform-implicit.
|
||||
PreferredStencilBufferBits = 8,
|
||||
};
|
||||
|
||||
_window = Window.Create(options);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue