feat(render): Phase A8.F — wire-in #2 per-cell translucent clip on stencil bit 2

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-29 12:45:56 +02:00
parent d581f4c549
commit 1c02a01298
2 changed files with 97 additions and 2 deletions

View file

@ -11070,13 +11070,37 @@ public sealed class GameWindow : IDisposable
gl.Disable(EnableCap.Blend);
_envCellRenderer!.Render(AcDream.App.Rendering.Wb.WbRenderPass.Opaque, currentEnvCellIds);
// Transparency pass.
// Phase A8.F (#2): translucent cell geometry clipped to each cell's portal-chain
// region (stencil BIT 2). Opaque cells already clip correctly via depth (left
// untouched above — Q4 fidelity-vs-perf decision). Bit 1 (OutsideView mask) is
// preserved: every bit-2 op below uses StencilMask 0x02 and never clears the
// whole stencil. The camera cell's region is full-screen, so it (and any cell
// without a non-empty region) renders unclipped.
gl.Enable(EnableCap.Blend);
gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
gl.DepthMask(false);
_envCellRenderer!.Render(AcDream.App.Rendering.Wb.WbRenderPass.Transparent, currentEnvCellIds);
foreach (var cellId in currentEnvCellIds)
{
var oneCell = new System.Collections.Generic.HashSet<uint> { cellId };
if (cellId != cameraCell.CellId
&& portalFrame.CellViews.TryGetValue(cellId, out var cv) && !cv.IsEmpty)
{
_indoorStencilPipeline!.MarkRegionBit2(cv.Polygons);
_indoorStencilPipeline.EnableBit2CellPass();
_meshShader!.Use();
_envCellRenderer!.Render(AcDream.App.Rendering.Wb.WbRenderPass.Transparent, oneCell);
gl.Disable(EnableCap.StencilTest);
_indoorStencilPipeline.ResetRegionBit2(cv.Polygons); // clear bit 2 for next cell; bit 1 intact
}
else
{
_meshShader!.Use();
_envCellRenderer!.Render(AcDream.App.Rendering.Wb.WbRenderPass.Transparent, oneCell);
}
}
gl.DepthMask(true);
gl.Disable(EnableCap.Blend);
gl.Disable(EnableCap.StencilTest); // ensure clean for Step 4 (which re-enables for bit-1 terrain gate)
}
// FIX 2026-05-28 (post-third-visual-gate): render IndoorPass entities.