fix(render): Phase U.4 — EnvCellRenderer.Render uploads its own uViewProjection
Root cause of the indoor cell-shell SEAM flicker ("transparent walls, oscillating
when moving"): EnvCellRenderer.Render never set uViewProjection — it inherited
WbDrawDispatcher's. But the opaque shell pass draws BEFORE the dispatcher's Draw
(GameWindow ~7411 vs ~7418, the only other setter), so opaque shells rendered with
the PREVIOUS frame's matrix — a stale gl_Position against this frame's clip planes,
yielding pose-dependent clipping that's worst while moving. Make Render self-contained:
stash the view-projection in PrepareRenderBatches and upload it in Render (same matrix
the portal clip planes use). Same self-contained-GL-state precedent as the 2026-05-28
cull-state fix in this file.
Visual re-test confirms this removes the wall-seam flicker. A separate residual
("some houses show only background on interior walls; some flicker remains") is a
distinct root cause, under investigation — NOT this matrix bug.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
354ca746ad
commit
d6d4671989
1 changed files with 20 additions and 0 deletions
|
|
@ -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<InstanceData>();
|
||||
var drawCalls = new List<(ObjectRenderData renderData, int count, int offset)>();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue