fix(render): feed look-in cells to particle and light visibility
Look-in rooms (cells reached through building portals) drew their geometry but never entered the visible-cell set consumed by the particle gate and the point-light candidacy scope, so their emitters stayed frozen and their lanterns dark until the player entered or the camera left the building. Retail has no look-in split: ShouldDrawParticles @0x0050FE60 gates on cell->IsInView(), and a cell installed by DrawBuilding @0x0059F2A0 -> PView::ConstructView @0x005A57B0 is drawn by the same DrawCells traversal as any flooded cell, so it is in view identically (per-cell in_view stamped by PView::InitCell @0x005A4B70). RetailPViewFrameResult now carries InViewCells (main flood + look-in cells, the existing prepareCells union; the borrowed-scratch contract is unchanged because RecycleLookInFrames runs at the start of the next DrawInside). WorldSceneRenderer feeds InViewCells to ParticleVisibilityController and the point-light scope. DrawableCells is untouched for seals, the outside-stage predicate, diagnostics, and the packed-product referee. The legacy 4-arg Reset defaults InViewCells = DrawableCells for standalone callers. User-gated 2026-08-29 at the Sanctuary Cathedral: adjacent look-in rooms show particles and lantern lights from the root cell without entry or an outside camera; recall/waterfall/Holtburg/paperdoll unregressed. The pre-existing #132-family candle-behind-opening report remains open and is unchanged by this fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f7aa8e0eb7
commit
85530c0b7e
4 changed files with 82 additions and 9 deletions
|
|
@ -251,10 +251,13 @@ public sealed class RetailPViewRenderer
|
|||
RenderProjectionCounts sourceCounts = frameViewBorrowed
|
||||
? frameView.SourceDigest.Counts
|
||||
: LegacySourceCounts(partition!);
|
||||
// prepareCells is exactly "main flood ∪ look-in cells" — the cells
|
||||
// this traversal actually reached, i.e. retail's in-view set.
|
||||
RetailPViewFrameResult result = _frameResultScratch.Reset(
|
||||
pvFrame,
|
||||
clipAssembly,
|
||||
drawableCells,
|
||||
prepareCells,
|
||||
counts,
|
||||
sourceCounts,
|
||||
partition);
|
||||
|
|
@ -1910,6 +1913,23 @@ public sealed class RetailPViewFrameResult
|
|||
public PortalVisibilityFrame PortalFrame { get; private set; } = null!;
|
||||
public ClipFrameAssembly ClipAssembly { get; private set; } = null!;
|
||||
public HashSet<uint> DrawableCells { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Every cell this completed view actually reached: the main flood
|
||||
/// (<see cref="DrawableCells"/>) plus the building look-in cells. This is
|
||||
/// retail's per-cell <c>in_view</c> answer for effect consumers —
|
||||
/// <c>CPhysicsObj::ShouldDrawParticles</c> @0x0050FE60 gates on
|
||||
/// <c>cell->IsInView()</c>, and a cell entered through a building portal
|
||||
/// (<c>PView::ConstructView</c> @0x005A57B0, installed by
|
||||
/// <c>RenderDeviceD3D::DrawBuilding</c> @0x0059F2A0) is drawn by the same
|
||||
/// <c>PView::DrawCells</c> traversal as a flooded cell, so retail marks it
|
||||
/// in view identically. acdream's look-in adaptation keeps those cells out
|
||||
/// of <see cref="DrawableCells"/> (seals / outside-stage predicate stay
|
||||
/// main-flood scoped, #124); particle and light visibility must consume
|
||||
/// THIS set or look-in rooms render with frozen emitters and dark lights.
|
||||
/// </summary>
|
||||
public HashSet<uint> InViewCells { get; private set; } = null!;
|
||||
|
||||
internal RenderFrameDiagnosticCounts DiagnosticCounts { get; private set; }
|
||||
internal RenderProjectionCounts SourceCounts { get; private set; }
|
||||
internal InteriorEntityPartition.Result? DiagnosticPartition
|
||||
|
|
@ -1919,6 +1939,7 @@ public sealed class RetailPViewFrameResult
|
|||
PortalVisibilityFrame portalFrame,
|
||||
ClipFrameAssembly clipAssembly,
|
||||
HashSet<uint> drawableCells,
|
||||
HashSet<uint> inViewCells,
|
||||
RenderFrameDiagnosticCounts diagnosticCounts,
|
||||
RenderProjectionCounts sourceCounts,
|
||||
InteriorEntityPartition.Result? diagnosticPartition)
|
||||
|
|
@ -1926,6 +1947,7 @@ public sealed class RetailPViewFrameResult
|
|||
PortalFrame = portalFrame;
|
||||
ClipAssembly = clipAssembly;
|
||||
DrawableCells = drawableCells;
|
||||
InViewCells = inViewCells;
|
||||
DiagnosticCounts = diagnosticCounts;
|
||||
SourceCounts = sourceCounts;
|
||||
DiagnosticPartition = diagnosticPartition;
|
||||
|
|
@ -1941,6 +1963,7 @@ public sealed class RetailPViewFrameResult
|
|||
portalFrame,
|
||||
clipAssembly,
|
||||
drawableCells,
|
||||
drawableCells,
|
||||
RetailPViewRenderer.LegacyDiagnosticCounts(
|
||||
diagnosticPartition),
|
||||
RetailPViewRenderer.LegacySourceCounts(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue