From 664ca9cb163ce63e1edf4fc1c4c3cc7724ea9697 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 27 May 2026 10:07:15 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"fix(render):=20Phase=20A8=20R3.5=20v2?= =?UTF-8?q?=20=E2=80=94=20gate=20depth-clear=20on=20cameraReallyInside=20t?= =?UTF-8?q?oo"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2bfeafd3582e0fa90969dc732c6940a2dc2a3bc0. --- src/AcDream.App/Rendering/GameWindow.cs | 58 +++++++++++-------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 32540b4..1f0177b 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -7160,42 +7160,17 @@ public sealed class GameWindow : IDisposable _terrainCpuSampleCursor = (_terrainCpuSampleCursor + 1) % _terrainCpuSamples.Length; MaybeFlushTerrainDiag(); - // Phase A8 R3.5 — transition-flicker fix. `cameraInsideCell` - // stays true for ~3 grace frames after the camera physically - // exits a cell (see CellVisibility._cellSwitchGraceFrames). - // The grace mechanism prevents sky/lighting flicker at the - // doorway threshold, but the render-frame mechanisms that - // touch depth (depth-clear AND the stencil pipeline) MUST be - // gated on the stricter PointInCell containment so they don't - // fire during grace frames when the camera is actually outside. - // - // cameraInsideCell — lenient, grace-aware → sky, lighting - // cameraReallyInside — PointInCell, no grace → depth-clear, - // stencil pipeline branch - // - // R3.5 v1 only gated the stencil branch on `cameraReallyInside`; - // depth-clear stayed on `cameraInsideCell`. Result: during grace - // frames the depth-clear ran but the outdoor branch ran (because - // !cameraReallyInside), so terrain depth was destroyed AND - // everything below terrain (cellars, basement geometry) won the - // depth test in the outdoor pass → "objects visible through - // ground." R3.5 v2 unifies the depth-related gates on - // `cameraReallyInside` so terrain depth is preserved during - // grace, eliminating the through-ground artifact. - bool cameraReallyInside = visibility?.CameraCell is not null - && CellVisibility.PointInCell(camPos, visibility.CameraCell); - - // Conditional depth clear: when camera is ACTUALLY inside a cell - // volume (not just in the grace window), clear depth (not color) - // so interior geometry writes fresh Z values on top of the - // terrain color buffer. Matches ACME GameScene.cs pattern. - if (cameraReallyInside) + // Conditional depth clear: when camera is inside a building, clear + // depth (not color) so interior geometry writes fresh Z values on top + // of the terrain color buffer. Exit portals show outdoor terrain color + // because we kept the color buffer. Matching ACME GameScene.cs pattern. + if (cameraInsideCell) _gl!.Clear(ClearBufferMask.DepthBufferBit); // L-fix1 (2026-04-28): animated-entity id set. Required by both - // the cameraReallyInside branch (to route them to LiveDynamic - // pass) and the outdoor path (where it preserves visibility - // across landblock frustum culling). + // the cameraInsideCell branch (to route them to LiveDynamic pass) + // and the outdoor path (where it preserves visibility across + // landblock frustum culling). HashSet? animatedIds = null; if (_animatedEntities.Count > 0) { @@ -7204,6 +7179,23 @@ public sealed class GameWindow : IDisposable animatedIds.Add(k); } + // Phase A8 R3.5 — transition-flicker fix. `cameraInsideCell` + // stays true for ~3 grace frames after the camera physically + // exits a cell (see CellVisibility._cellSwitchGraceFrames). + // The grace mechanism prevents lighting/sky flicker at the + // doorway threshold, but if the stencil pipeline runs during + // grace frames it marks/punches at the OLD cell's portal + // silhouettes — which are now behind/beside the camera — and + // the subsequent IndoorPass + stencil-gated outdoor produce + // a brief frame of "walls disappear + buildings under ground" + // garbage. Gate the stencil branch on the stricter + // `PointInCell` containment check so the pipeline only runs + // when the camera is ACTUALLY inside its cell volume; sky / + // lighting / depth-clear continue to use `cameraInsideCell` + // for their smoother grace-aware behavior. + bool cameraReallyInside = visibility?.CameraCell is not null + && CellVisibility.PointInCell(camPos, visibility.CameraCell); + // The `visibility?.CameraCell is not null` repeat is for the // compiler's null-flow analysis: `cameraReallyInside` already // implies it, but flow doesn't propagate through a separate