feat(render): Phase U.4 — unified gated draw pass (indoor root)
Wire the portal-visibility result through the clip pipeline: build a per-frame ClipFrame (slot 0 no-clip, slot 1 OutsideView, slot 2..N per visible cell) + cellIdToSlot from PortalVisibilityBuilder; call the (previously dormant) EnvCellRenderer.Render for cell shells inside the clip bracket; assign per-instance clip slots in WbDrawDispatcher (live-dynamic unclipped per retail, cell statics to their cell slot, outdoor scenery to OutsideView, non-visible culled); gate/scissor/ skip terrain per OutsideView (empty ⇒ no terrain — the bleed fix). Emit ACDREAM_PROBE_VIS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
864fc5f94e
commit
7993e064a0
6 changed files with 748 additions and 67 deletions
|
|
@ -237,6 +237,24 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
|||
public void SetClipRegionSsbo(uint sharedClipRegionSsbo)
|
||||
=> _sharedClipRegionSsbo = sharedClipRegionSsbo;
|
||||
|
||||
// Phase U.4: per-frame cellId→CellClip-slot map for the cell shells. When
|
||||
// non-null, RenderModernMDIInternal writes instanceClipSlot[i] =
|
||||
// _cellIdToSlot[allInstances[i].CellId] so each cell's shell instances are
|
||||
// gated to that cell's portal-clip region. When null (U.3 path), every
|
||||
// instance maps to slot 0 (no-clip). A cell absent from the map writes slot 0
|
||||
// (no-clip) — but the caller's Render filter already restricts the draw to the
|
||||
// map's keys, so that fallback should not fire in practice.
|
||||
private IReadOnlyDictionary<uint, int>? _cellIdToSlot;
|
||||
|
||||
/// <summary>
|
||||
/// Phase U.4: install the per-frame cellId→slot map used to gate cell shells
|
||||
/// to their portal-clip regions. Call once per frame BEFORE
|
||||
/// <see cref="Render(WbRenderPass, HashSet{uint}?)"/>. Pass null to revert to
|
||||
/// the U.3 no-clip behavior (every shell instance → slot 0).
|
||||
/// </summary>
|
||||
public void SetClipRouting(IReadOnlyDictionary<uint, int>? cellIdToSlot)
|
||||
=> _cellIdToSlot = cellIdToSlot;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GetEnvCellGeomId
|
||||
// Verbatim copy of WB EnvCellRenderManager.cs:94-103.
|
||||
|
|
@ -1047,14 +1065,25 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
|||
(nuint)(totalDraws * sizeof(ModernBatchData)), ptr);
|
||||
}
|
||||
|
||||
// Phase U.3: upload the per-instance clip-slot buffer (binding=3), all
|
||||
// zeros ⇒ every instance maps to slot 0 ⇒ no-clip. Re-zero the reused head
|
||||
// each frame so stale U.4 slot indices can't leak. Sized to
|
||||
// uniqueInstanceCount; the buffer was already grown above with the
|
||||
// instance buffer when capacity increased.
|
||||
// Phase U.4: upload the per-instance clip-slot buffer (binding=3). When
|
||||
// _cellIdToSlot is set (indoor routing), each cell shell instance is gated
|
||||
// to its cell's CellClip slot via allInstances[i].CellId; cells absent from
|
||||
// the map (shouldn't happen — the Render filter is the map's keys) and the
|
||||
// U.3 path both map to slot 0 (no-clip). allInstances is laid out in the
|
||||
// SAME order as the binding=0 transforms (_gpuInstanceTransforms below), so
|
||||
// instanceClipSlot[i] tracks Instances[i] through the MDI BaseInstance.
|
||||
if (_clipSlotData.Length < uniqueInstanceCount)
|
||||
_clipSlotData = new uint[Math.Max(_clipSlotData.Length * 2, uniqueInstanceCount)];
|
||||
Array.Clear(_clipSlotData, 0, uniqueInstanceCount);
|
||||
if (_cellIdToSlot is null)
|
||||
{
|
||||
Array.Clear(_clipSlotData, 0, uniqueInstanceCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < uniqueInstanceCount; i++)
|
||||
_clipSlotData[i] = _cellIdToSlot.TryGetValue(allInstances[i].CellId, out int slot)
|
||||
? (uint)slot : 0u;
|
||||
}
|
||||
_gl.BindBuffer(GLEnum.ShaderStorageBuffer, _clipSlotBuffer);
|
||||
_gl.BufferData(GLEnum.ShaderStorageBuffer,
|
||||
(nuint)(uniqueInstanceCount * sizeof(uint)), null, GLEnum.DynamicDraw);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue