fix(render): Phase A8 — remove cull-restore at EnvCell exit (lets IndoorPass inherit cull-off)
Visual-gate-#4 evidence revealed the prior commit's cull-restore-at-exit addition was wrong. The Landblock→None CullMode override worked correctly for cell-mesh polys, but the cull-back state I restored at Render exit propagated to the subsequent `dispatcher.Draw(IndoorPass)` call. The dispatcher's IndoorPass renders AC's cottage shell — landblock-baked GfxObj parts (wooden floor planks, wall slabs) whose pos-side winding + our FrontFace=CCW + cull-back = floor poly is back-facing and culled. User saw light blue sky through the floor in gate-#4. Reverting the cull-restore lets cull-disabled propagate from EnvCellRenderer.Render through IndoorPass. Cottage shell renders double-sided so the floor + wall slabs are visible from any angle. Step 4's gl.Enable(EnableCap.CullFace) at the terrain pass (line ~10768) + the cleanup block's enable (line ~10870) re-establish cull-back BEFORE the LiveDynamic dispatcher.Draw fires — so chars, NPCs, doors still render solid (no see-through-head regression from gate-#3's ACDREAM_A8_DISABLE_CULL=1 diagnostic). The retail-faithful long-term fix is matching WB's `glFrontFace(GLEnum.CW)` globally (per GameScene.cs:843) so cull-back selects the correct side for AC's natural polygon winding without needing double-sided rendering. That requires a wider audit of every consumer's FrontFace assumption (translucent crystal renderer + others) and is deferred. 14/14 EnvCellRenderer tests pass. Build green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0940d7961a
commit
d5deeb3314
1 changed files with 26 additions and 15 deletions
|
|
@ -815,21 +815,32 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
||||||
_gl.BindVertexArray(0);
|
_gl.BindVertexArray(0);
|
||||||
_currentVao = 0;
|
_currentVao = 0;
|
||||||
|
|
||||||
// Phase A8 fix (2026-05-28 visual-gate-#3 follow-up): explicitly
|
// Phase A8 (2026-05-28 visual-gate-#4 follow-up): NO cull-restore
|
||||||
// restore cull-back at exit. The Landblock→None override above
|
// at exit. The Landblock→None override can leave cull DISABLED
|
||||||
// can leave cull DISABLED if the last batch's CullMode was
|
// if the last batch was Landblock — and that's intentional: the
|
||||||
// Landblock — which would leak into the subsequent dispatcher
|
// subsequent `dispatcher.Draw(IndoorPass)` call in
|
||||||
// draws (IndoorPass building shells, then LiveDynamic chars +
|
// RenderInsideOutAcdream's Step 3 wants cull-off too, because
|
||||||
// NPCs + doors), making them all render see-through (no
|
// AC's cottage-shell GfxObj parts (the wooden floor planks +
|
||||||
// back-face cull). The see-through-head symptom in the
|
// wall slabs that the player walks on / through) have winding
|
||||||
// ACDREAM_A8_DISABLE_CULL=1 A/B test was caused exactly by
|
// that gets back-face-culled by the dispatcher's default
|
||||||
// this state leak. Re-enabling cull here restores the
|
// FrontFace=CCW. Letting cull stay off through IndoorPass
|
||||||
// dispatcher's expected default and updates our static cache
|
// renders both shell and cell mesh double-sided, so floors are
|
||||||
// so the next Render call's first SetCullMode comparison is
|
// visible from above (and inverted-front-facing wall slabs are
|
||||||
// correct.
|
// visible from inside the room). Step 4's
|
||||||
_gl.Enable(EnableCap.CullFace);
|
// `gl.Enable(EnableCap.CullFace)` (line ~10768) + the cleanup
|
||||||
_gl.CullFace(TriangleFace.Back);
|
// block's enable (line ~10870) re-establish cull-back before
|
||||||
_currentCullMode = CullMode.CounterClockwise;
|
// LiveDynamic chars / NPCs / doors render — so those still
|
||||||
|
// look solid (no see-through head). The static `_currentVao`
|
||||||
|
// is reset because the next Render call's batch loop needs to
|
||||||
|
// re-issue BindVertexArray regardless; `_currentCullMode` is
|
||||||
|
// intentionally left at None so the cache matches actual GL
|
||||||
|
// state until the next Render call's per-batch SetCullMode
|
||||||
|
// either confirms or re-sets it.
|
||||||
|
//
|
||||||
|
// The retail-faithful long-term move is matching WB's
|
||||||
|
// glFrontFace(CW) globally (GameScene.cs:843) so cull-back
|
||||||
|
// selects the correct side for AC's polygon winding without
|
||||||
|
// double-sided rendering — deferred until a wider audit.
|
||||||
|
|
||||||
// Update frame stats for probe emission at the call site.
|
// Update frame stats for probe emission at the call site.
|
||||||
_lastFrameStats.CellsRendered = filter?.Count ?? snapshot.BatchedByCell.Count;
|
_lastFrameStats.CellsRendered = filter?.Count ?? snapshot.BatchedByCell.Count;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue