fix #176 #177: the camera-capped light snapshot evicted visible cells' torches — per-cell lighting popped at seams
The probe launch discriminated it: the user reproduced the purple floor flash while [light] (ambient branch) and [pv-input] (portal flood) read provably healthy — eliminating the last CPU-side theories and exposing the one channel the probes could not see: per-cell 8-light set composition. BuildPointLightSnapshot kept the MaxGlobalLights=128 point lights nearest THE CAMERA; the Facility Hub registers 366 fixtures, so 238 were evicted per frame by camera distance. SelectForObject (faithfully camera-independent, and unit-pinned as such) could only choose from the surviving 128 — an in-range torch of a visible cell that ranked past the cap dropped out of that cell's 8-set, so per-cell Gouraud lighting flipped as the chase boom swung the camera: - #176: the flipping unit is a CELL -> discontinuity lines at exactly cell-seam granularity; a torch-losing floor drops to dim blue-grey stone at 0.2 ambient (the perceived purple), camera-angle dependent. - #177: a stair room whose torches all ranked past the cap rendered at bare 0.2 ambient (near-black = 'not visible'); approach re-admitted them ('pops into existence'); the sweeping boundary dropped the ramp's lights mid-descent ('disappears on the last step'). The geometry never vanished - its lights did. Retail's minimize_object_lighting (0x0054d480) has NO global camera-nearest pool cap (lights register per cell, insert_light 0x0054d1b0). Fix: MaxGlobalLights 128 -> 1024, a non-biting safety valve (GlobalLightPacker grows to fit; 64 B/light). Register row AP-85. TDD pin: PointSnapshot_HubScaleLightCount_ObjectSelectionIsCameraInvariant (RED at 128 with a Hub-scale 401-light layout, GREEN at 1024). The pre-existing camera-independence pin covered the SELECTOR but not the SNAPSHOT it selects from - the pop re-entered one stage upstream. Suites: Core 2588 / App 719 / UI 425 / Net 385 green. Pending user gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b8e9e204ad
commit
4d25e04d83
5 changed files with 151 additions and 28 deletions
|
|
@ -176,9 +176,18 @@ public sealed class LightManager
|
|||
public const int MaxLightsPerObject = 8;
|
||||
|
||||
/// <summary>Hard cap on the per-frame global point-light snapshot the shader
|
||||
/// indexes. AC scenes rarely exceed a few dozen lit point lights in view; 128
|
||||
/// is generous. If exceeded, the nearest-to-camera are kept (cold path).</summary>
|
||||
public const int MaxGlobalLights = 128;
|
||||
/// indexes. #176/#177 (2026-07-06): the old value of 128 BIT in the Facility
|
||||
/// Hub — 366 registered fixtures, so 238 were evicted per frame by camera
|
||||
/// distance. An in-range torch of a VISIBLE cell that ranked past the cap
|
||||
/// dropped out of the cell's 8-light set, so per-cell Gouraud lighting popped
|
||||
/// as the camera moved (the purple seam flash / the stair-room pop-in).
|
||||
/// Retail's <c>minimize_object_lighting</c> (0x0054d480) has NO global
|
||||
/// camera-nearest cap — every registered light reaching an object is a
|
||||
/// candidate. 1024 is a pure safety valve (the whole Facility Hub registers
|
||||
/// 366; GlobalLightPacker grows to fit, 64 B/light on the GPU) and must never
|
||||
/// bite at real content scale — if it ever does, raise it, don't tune it.
|
||||
/// Pin: LightManagerTests.PointSnapshot_HubScaleLightCount_ObjectSelectionIsCameraInvariant.</summary>
|
||||
public const int MaxGlobalLights = 1024;
|
||||
|
||||
private readonly List<LightSource> _pointSnapshot = new();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue