diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 4df8455..d75cd66 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -7279,8 +7279,21 @@ public sealed class GameWindow : IDisposable // Phase N.5b: wrap Draw in CPU stopwatch for [TERRAIN-DIAG] rollup // (gated on ACDREAM_WB_DIAG=1, same env var as [WB-DIAG]). Stopwatch // is cheap; only the periodic Console.WriteLine is gated. + // + // FIX 2026-05-28: skip this terrain pass when cameraInsideBuilding. + // RenderInsideOutAcdream's Step 4 draws terrain stencil-gated to + // portal silhouettes (matching WB VisibilityManager:143). Drawing + // terrain BOTH here (full-screen) AND in Step 4 (stencil-gated) + // doubles GPU work AND causes Z-fighting at cottage walls — the + // lower wall portion (Z=92-94) overlaps terrain Z=92, terrain's + // depth from this pass is already in the depth buffer when Step + // 3 writes the cell mesh. The pre-A8 code papered over this with + // a depth-clear-if-inside workaround which we deleted in Wave 4. + // The proper fix is to NOT draw terrain here when indoor; Step 4 + // is the single, stencil-gated terrain pass. _terrainCpuStopwatch.Restart(); - _terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb); + if (!cameraInsideBuilding) + _terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb); _terrainCpuStopwatch.Stop(); // Multiply by 100 then divide by 100 in the diag print to keep // 0.01 µs precision in the long-typed sample buffer. Terrain Draw