From fd721afdf966461b4f9983fd03f0fadf4a26db28 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 27 May 2026 10:08:10 +0200 Subject: [PATCH] =?UTF-8?q?Revert=20"feat(render):=20Phase=20A8=20R3=20?= =?UTF-8?q?=E2=80=94=20wire=20stencil=20pipeline=20into=20render=20frame?= =?UTF-8?q?=20(WB=20order)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 60f07bc21be92c48a8629688f1bbc04fcc12ec22. --- src/AcDream.App/Rendering/GameWindow.cs | 101 +++--------------------- 1 file changed, 13 insertions(+), 88 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index bd54b28..5869071 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -36,7 +36,6 @@ public sealed class GameWindow : IDisposable private AcDream.App.Rendering.Wb.EntitySpawnAdapter? _wbEntitySpawnAdapter; private AcDream.App.Rendering.Vfx.EntityScriptActivator? _entityScriptActivator; private AcDream.App.Rendering.Wb.WbDrawDispatcher? _wbDrawDispatcher; - private IndoorCellStencilPipeline? _indoorStencilPipeline; /// Phase N.5: ARB_bindless_texture + ARB_shader_draw_parameters /// support. Required at startup — missing bindless throws /// in OnLoad. @@ -1753,15 +1752,6 @@ public sealed class GameWindow : IDisposable _classificationCache); // A.5 T22.5: apply A2C gate from quality preset. _wbDrawDispatcher.AlphaToCoverage = _resolvedQuality.AlphaToCoverage; - - // Phase A8 R3 — indoor visibility culling pipeline. Owns the - // portal_stencil shader pair and a dynamic VBO for per-frame - // portal triangle uploads. Stencil work runs only when the - // camera is inside an EnvCell; outside, the object is dormant. - _indoorStencilPipeline = new IndoorCellStencilPipeline( - _gl, - Path.Combine(shadersDir, "portal_stencil.vert"), - Path.Combine(shadersDir, "portal_stencil.frag")); } // Phase G.1 sky renderer — its own shader (sky.vert / sky.frag) @@ -7167,10 +7157,14 @@ public sealed class GameWindow : IDisposable if (cameraInsideCell) _gl!.Clear(ClearBufferMask.DepthBufferBit); - // L-fix1 (2026-04-28): animated-entity id set. Required by both - // the cameraInsideCell branch (to route them to LiveDynamic pass) - // and the outdoor path (where it preserves visibility across - // landblock frustum culling). + // L-fix1 (2026-04-28): pass the set of animated-entity ids so + // the renderer keeps remote players / NPCs / monsters + // visible even when their landblock rotates out of the + // frustum. Without this, other characters wink in/out as + // the camera turns. The set is rebuilt per-frame from + // _animatedEntities — it's small (<100 entities typically) + // so HashSet allocation is cheap. Static scenery still + // respects landblock-level cull. HashSet? animatedIds = null; if (_animatedEntities.Count > 0) { @@ -7179,79 +7173,11 @@ public sealed class GameWindow : IDisposable animatedIds.Add(k); } - if (cameraInsideCell && _indoorStencilPipeline is not null - && visibility?.CameraCell is not null) - { - if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeVisibilityEnabled) - Console.WriteLine("[vis] branch=indoor"); - // Phase A8 R3 — WB RenderInsideOut order. - // - // 1. Terrain has already drawn (color + depth) at line ~7104. - // 2. depth-clear-if-inside has already cleared depth to 1.0 - // (above this branch at line ~7118). The MarkAndPunch - // below is a no-op against that baseline — left in for - // symmetry with WB's reference pipeline and to handle - // the unusual case where depth-clear is later dropped. - // 3. MarkAndPunch — stencil bit 1 at the camera's-own-cell - // exit portals. Step 5 (cross-cell-portal visibility via - // 3-stencil-bit pipeline) is DEFERRED — we mark ONLY the - // camera's own cell's portals, not the BFS-extended - // VisibleCellIds. Trade-off: cross-cell visibility loss - // (rare visually); correctness in the common case (no - // see-through-wall to far-side portal openings). - var cameraCells = new[] { visibility.CameraCell }; - _indoorStencilPipeline.UploadPortalMesh(cameraCells); - - var viewProjection = camera.View * camera.Projection; - _indoorStencilPipeline.MarkAndPunch(viewProjection); - - // 4. IndoorPass — cell mesh + cell statics + building shells - // (R1's IsBuildingShell flag drives the partition). - // Stencil OFF (MarkAndPunch's cleanup restored that). - // Depth test normal; building shells write the wall depth - // that protects the indoor from outdoor visibility. - _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, - neverCullLandblockId: playerLb, - visibleCellIds: visibility.VisibleCellIds, - animatedEntityIds: animatedIds, - set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.IndoorPass); - - // 5. Stencil-gated outdoor pass. - _indoorStencilPipeline.EnableOutdoorPass(); - - // 5a. Re-draw terrain — at portal-silhouette pixels only, - // terrain Z (with the f48c74a -0.01 nudge) wins over the - // punched 1.0 depth. Color writes through window. - _terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb); - - // 5b. Outdoor scenery — same stencil gating. - _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, - neverCullLandblockId: playerLb, - visibleCellIds: visibility.VisibleCellIds, - animatedEntityIds: animatedIds, - set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.OutdoorScenery); - - // 6. Stencil OFF — live dynamic entities draw freely with - // depth test only (no stencil clipping). - _indoorStencilPipeline.DisableStencil(); - - _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, - neverCullLandblockId: playerLb, - visibleCellIds: visibility.VisibleCellIds, - animatedEntityIds: animatedIds, - set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.LiveDynamic); - } - else - { - if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeVisibilityEnabled) - Console.WriteLine("[vis] branch=outdoor"); - // Outdoor path — unchanged from pre-A8: single dispatcher call - // walks every entity with default EntitySet.All partition. - _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, - neverCullLandblockId: playerLb, - visibleCellIds: visibility?.VisibleCellIds, - animatedEntityIds: animatedIds); - } + // N.5: WbDrawDispatcher is always non-null (modern path mandatory). + _wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum, + neverCullLandblockId: playerLb, + visibleCellIds: visibility?.VisibleCellIds, + animatedEntityIds: animatedIds); // Phase G.1 / E.3: draw all live particles after opaque // scene geometry so alpha blending composites correctly. @@ -10607,7 +10533,6 @@ public sealed class GameWindow : IDisposable _liveSession = null; _audioEngine?.Dispose(); // Phase E.2: stop all voices, close AL context _wbDrawDispatcher?.Dispose(); - _indoorStencilPipeline?.Dispose(); _skyRenderer?.Dispose(); // depends on sampler cache; dispose first _samplerCache?.Dispose(); _textureCache?.Dispose();