perf(pview): batch EnvCell look-in shell opaque pass (interior-root parity)

DrawBuildingLookIns had the same per-cell heavy Render pattern. Lift the opaque
shell Render out into one per-building batch (after that building's aperture
punches); keep the per-cell loop for transparent (skip-empty) + per-cell statics
/dynamics/particles. User-verified: no missing walls, look-in interiors correct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-23 18:10:28 +02:00
parent 3af7d0048d
commit 8067d3b04a

View file

@ -350,13 +350,26 @@ public sealed class RetailPViewRenderer
// Pass 2: shells + statics, far→near. // Pass 2: shells + statics, far→near.
UseIndoorMembershipOnlyRouting(); UseIndoorMembershipOnlyRouting();
// Opaque shells batched per building into ONE Render (this building's
// aperture punches above already ran; z-buffer handles order and
// lighting is per-instance CellId-keyed) — was one heavy per-frame
// Render per cell. Per-cell entity/particle work stays in the loop.
_shellBatch.Clear();
foreach (uint cid in frame.OrderedVisibleCells)
_shellBatch.Add(cid);
if (_shellBatch.Count > 0)
_envCells.Render(WbRenderPass.Opaque, _shellBatch);
for (int i = frame.OrderedVisibleCells.Count - 1; i >= 0; i--) for (int i = frame.OrderedVisibleCells.Count - 1; i >= 0; i--)
{ {
uint cellId = frame.OrderedVisibleCells[i]; uint cellId = frame.OrderedVisibleCells[i];
_oneCell.Clear(); _oneCell.Clear();
_oneCell.Add(cellId); _oneCell.Add(cellId);
_envCells.Render(WbRenderPass.Opaque, _oneCell); // Opaque shell batched above. Transparent stays per-cell (far→near)
_envCells.Render(WbRenderPass.Transparent, _oneCell); // for correct compositing; skipped for opaque-only cells.
if (_envCells.CellHasTransparent(cellId))
_envCells.Render(WbRenderPass.Transparent, _oneCell);
_cellStaticScratch.Clear(); _cellStaticScratch.Clear();
if (partition.ByCell.TryGetValue(cellId, out var bucket)) if (partition.ByCell.TryGetValue(cellId, out var bucket))