diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index b323bed..4df8455 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -10727,7 +10727,16 @@ public sealed class GameWindow : IDisposable // Step 5: per-other-building 3-bit stencil pipeline. // WB VisibilityManager.cs:157-232 - if (didInsideStencil && otherBuildings.Count > 0) + // + // FIX 2026-05-28 (post-first-visual-gate): Step 5 is GATED OFF BY DEFAULT. + // First visual gate showed perf collapse + texture flicker indoors because + // Step 5 iterates EVERY loaded other-building per frame (109 at Holtburg), + // each doing 5 GL draws (mark/end-query/punch/render-opaque/render-trans/reset) + // = ~545 extra draws/frame with no frustum culling. The driver hit TDR + // limits. Set ACDREAM_A8_STEP5=1 to re-enable for cross-building visibility + // testing once we add per-building frustum culling. + bool step5Enabled = string.Equals(Environment.GetEnvironmentVariable("ACDREAM_A8_STEP5"), "1", StringComparison.Ordinal); + if (step5Enabled && didInsideStencil && otherBuildings.Count > 0) { gl.Enable(EnableCap.StencilTest); gl.ColorMask(false, false, false, false); @@ -10791,7 +10800,18 @@ public sealed class GameWindow : IDisposable { gl.Disable(EnableCap.StencilTest); gl.StencilMask(0xFFu); - gl.ColorMask(true, true, true, false); + // FIX 2026-05-28: WB exits with ColorMask(t,t,t,FALSE) — alpha-bit + // off. That breaks subsequent acdream rendering (particles + + // anything that relies on alpha-to-coverage writing alpha). Restore + // full ColorMask before returning to the outer render frame. + // + // Step 5's iteration loop (when ACDREAM_A8_STEP5=1) leaves + // DepthMask=false / CullFace=disabled / ColorMask=(f,f,f,f) on + // its last iteration. Restore to acdream-default before returning. + gl.ColorMask(true, true, true, true); + gl.DepthMask(true); + gl.DepthFunc(DepthFunction.Less); + gl.Enable(EnableCap.CullFace); } }