fix(render): Phase A8.F — restore DepthFunc.Less in bit-2 clip helpers (Opus review C1/C2)

DrawRegionBit2 set DepthFunc.Always and never restored it; EnvCellRenderer
and WbDrawDispatcher rely on ambient DepthFunc, so the leak made clipped
translucent cells, the camera cell + cells iterated after a clipped one, and
the IndoorPass building shells all render with Always instead of Less (walls
drawing through each other). DrawRegionBit2 now restores DepthFunc.Less on
exit; EnableBit2CellPass sets the per-cell render state (Less + depth-write
off) explicitly so the bug class can't silently recur. ColorMask matched to
the indoor pass (alpha-write off).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-29 12:55:35 +02:00
parent 1c02a01298
commit 5a012c05f0

View file

@ -369,6 +369,11 @@ public sealed unsafe class IndoorCellStencilPipeline : IDisposable
_gl.StencilFunc(StencilFunction.Equal, 0x02, 0x02u); // bit 2 set
_gl.StencilMask(0x00u); // read-only — do not touch bit 1 or bit 2
_gl.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
// Make the per-cell transparent render state explicit (don't inherit DrawRegionBit2's
// DepthFunc.Always): depth-test Less, depth-write off (translucent). Self-describing so
// the clip pass can't silently regress if a sibling helper's exit state changes.
_gl.DepthFunc(DepthFunction.Less);
_gl.DepthMask(false);
}
// Triangulate the NDC region (fan, z=0) and draw it writing only bit 2 (set or clear).
@ -415,7 +420,10 @@ public sealed unsafe class IndoorCellStencilPipeline : IDisposable
_gl.DrawArrays(PrimitiveType.Triangles, 0, (uint)triVerts);
_gl.BindVertexArray(0);
_gl.Enable(EnableCap.CullFace);
_gl.ColorMask(true, true, true, true);
_gl.ColorMask(true, true, true, false); // match the indoor pass convention (alpha-write off)
// Restore the loop's depth-test: do NOT leak DepthFunc.Always into the cell render, the
// unclipped else-branch, the IndoorPass shells, or Step 4. (Opus review C1/C2.)
_gl.DepthFunc(DepthFunction.Less);
}
/// <summary>