From f143ece317d15c0f32e0bf37a6c0503e753eeaaf Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 27 May 2026 16:14:13 +0200 Subject: [PATCH] =?UTF-8?q?fix(render):=20Phase=20A8=20=E2=80=94=20skip=20?= =?UTF-8?q?line-7200=20terrain=20when=20cameraInsideBuilding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User report after Step 5 disable + cull-cache fix: "Cant see anything, flickering colors, sometimes textures sometimes inside, house missing lots of walls. 10 FPS. GPU 100%." Root cause: terrain was being drawn TWICE per indoor frame: 1. Line 7283 _terrain.Draw — UNCONDITIONAL pre-A8 pass; writes full- screen terrain color + depth at terrain Z. 2. Step 4 inside RenderInsideOutAcdream — stencil-gated terrain at portal silhouettes only (matching WB VisibilityManager:143). Pre-A8 papered over the Z conflict with a depth-clear-if-inside workaround (cleared depth between terrain and cottage) which we DELETED as part of Wave 4. Without it, when Step 3 writes the cell geometry with DepthFunc.Less, the cottage walls at Z=92-94 (where they meet the ground) Z-FIGHT against the terrain already in the depth buffer from pass 1. Symptom: flickering walls + missing sections + GPU saturated drawing terrain twice. Fix: gate the line-7200 terrain draw on `!cameraInsideBuilding`. When indoor, Step 4 is the SOLE terrain pass — stencil-gated to portal silhouettes only. No double-draw, no Z-fighting, no need for the deleted depth-clear workaround. Outdoor mode unchanged (pass 1 still fires, Step 4 isn't taken). Build green. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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