From 2bf5013c2fe869f6398a12b14b3f83667317aa38 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 27 May 2026 16:22:16 +0200 Subject: [PATCH] =?UTF-8?q?fix(render):=20Phase=20A8=20=E2=80=94=20render?= =?UTF-8?q?=20IndoorPass=20entities=20(cottage=20shell=20walls)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User report after Step 5 disable + ColorMask cleanup + cull-cache fix + terrain-skip fix: "Still chaos, GPU 100%. House missing lots of walls." Root cause finally found: Pre-A8 indoor walls came from IsBuildingShell entities (landblock-baked GfxObj slabs that represent cottage exterior walls — NOT part of any cell's CellStruct). They were drawn via Dispatcher.Draw(set: IndoorPass) in the pre-A8 outdoor path. WB's algorithm assumes its StaticObjectManager.Render in Step 4 handles these (its partition lumps shells with outdoor statics). Our EntitySet partition (RR2) puts IsBuildingShell into IndoorPass (alongside cell stabs), NOT OutdoorScenery — because logically shells ARE indoor walls. A8's RenderInsideOutAcdream Step 4 calls Draw(set: OutdoorScenery) which EXCLUDES IsBuildingShell. So cottage exterior wall slabs never render in A8. EnvCellRenderer provides the floor + interior CellStruct walls, but the shell slabs (exterior walls visible from inside) are gone. Symptom: "missing walls" because half the cottage walls are landblock-baked shells, not cell mesh. FIX: insert a Draw(set: IndoorPass) call between Step 3 (cells) and Step 4 (stencil-gated outdoor) when cameraInsideBuilding. Uses currentEnvCellIds as the cell filter — narrows cell stabs to camera- building cells; building shells (no ParentCellId) pass through and all render. Depth-tested (DepthFunc.Less) so cottage-A's near walls occlude cottage-B's far walls; no stencil so shells render unconditionally inside the camera building. Build green. This was the root cause behind the 4 days of RR7 failures. The handoff doc even noted "Building shells render (they ARE GfxObj entities with proper mesh refs after hydration)" — but the new RenderInsideOutAcdream code DIDN'T call IndoorPass, only OutdoorScenery. Hence shells never rendered. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index d75cd66..af984ae 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -10710,6 +10710,34 @@ public sealed class GameWindow : IDisposable gl.DepthMask(true); } + // FIX 2026-05-28 (post-third-visual-gate): render IndoorPass entities. + // EnvCellRenderer covers cell GEOMETRY (floor, walls baked into the + // cell's CellStruct). But cottages ALSO have IsBuildingShell entities + // — landblock-baked GfxObjs representing exterior wall slabs that + // aren't part of any cell's CellStruct. Pre-A8 rendered these via + // Dispatcher.Draw(set: IndoorPass); WB's algorithm assumes its + // StaticObjectManager.Render handles them in Step 4. Our EntitySet + // partition puts IsBuildingShell into IndoorPass (not OutdoorScenery), + // so Step 4's `Draw(set: OutdoorScenery)` misses them entirely. + // Result with the missing call: user reports "house missing lots of + // walls" — the cottage's exterior wall slabs aren't drawn. + // + // Render IndoorPass between Step 3 and Step 4, with the + // currentEnvCellIds filter narrowing cell stabs but NOT the building + // shells (they have no ParentCellId and pass through). Depth-test + // with DepthFunc.Less so cottage-A's near walls occlude cottage-B's + // far walls. NO stencil — we want them rendered unconditionally + // inside the camera-building. + if (camBuildings.Count > 0) + { + _meshShader!.Use(); + _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, + neverCullLandblockId: playerLb, + visibleCellIds: currentEnvCellIds, + animatedEntityIds: animatedIds, + set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.IndoorPass); + } + EmitEnvCellProbe(camBuildings.Count, otherBuildings.Count, currentEnvCellIds.Count); // Step 4: stencil-gated outdoor (terrain + scenery + static objects).