diff --git a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs index 68ba289..0307c13 100644 --- a/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs +++ b/src/AcDream.App/Rendering/Wb/EnvCellRenderer.cs @@ -53,6 +53,13 @@ public sealed unsafe class EnvCellRenderer : IDisposable // API mapping: Bind() -> Use(), SetUniform(s, int) -> SetInt(s, int), // SetUniform(s, Vector4) -> SetVec4(s, Vector4). private AcDream.App.Rendering.Shader? _shader; + + // Phase U.4 root-cause fix: the view-projection captured in PrepareRenderBatches, + // re-uploaded by Render() so the cell-shell pass is self-contained and does NOT + // inherit WbDrawDispatcher's uViewProjection (which the opaque pass would read one + // frame stale, since it draws BEFORE the dispatcher's upload). Same matrix the + // portal clip planes are computed with (envCellViewProj). + private Matrix4x4 _lastViewProjection = Matrix4x4.Identity; private bool _initialized; // List pool — copied from WB ObjectRenderManagerBase. @@ -522,6 +529,9 @@ public sealed unsafe class EnvCellRenderer : IDisposable int? centerLbY = null, int? renderRadius = null) { + // Phase U.4 fix: stash the view-projection so Render() can upload it itself. + _lastViewProjection = viewProjection; + // WB EnvCellRenderManager.cs:249-250: if (!_initialized || cameraPosition.Z > 4000) return; @@ -815,6 +825,16 @@ public sealed unsafe class EnvCellRenderer : IDisposable _shader.SetInt("uRenderPass", (int)renderPass); _shader.SetInt("uFilterByCell", 0); + // Phase U.4 ROOT-CAUSE FIX (cell-shell flicker / "transparent walls when + // moving"): upload uViewProjection HERE rather than inheriting it from + // WbDrawDispatcher. The opaque shell pass runs BEFORE the dispatcher's + // Draw (GameWindow ~7411 vs ~7418, the only other setter), so without + // this the opaque shells used the PREVIOUS frame's matrix — a stale + // gl_Position against this frame's clip planes → pose-dependent clipping, + // worst while moving. Same self-contained-GL-state precedent as the + // 2026-05-28 cull-state cache fix above. + _shader.SetMatrix4("uViewProjection", _lastViewProjection); + var allInstances = new List(); var drawCalls = new List<(ObjectRenderData renderData, int count, int offset)>();