fix(render): A7 Fix B — per-OBJECT point-light selection (minimize_object_lighting)
Outdoor objects brightened as the camera approached: lighting selected the nearest 8 lights to the VIEWER and fed that one global set to everything (LightManager.Tick), so a building's wall torches only lit it once the camera got close enough for them to win the global top-8. Probe confirmed the scale of the problem: a single Holtburg view registers 129 point lights — the global cap of 8 was hopeless. Retail selects up to 8 lights PER OBJECT by the object's own position (minimize_object_lighting 0x0054d480), so a torch always lights the wall it sits on, camera-independent. Ported faithfully: - LightManager.SelectForObject (pure, TDD, 8 new tests): candidacy (light.pos − center)² < (Range + radius)², nearest-8 among those. Plus BuildPointLightSnapshot for the per-frame stable-indexed light list. - mesh_modern.vert: two SSBOs — binding=4 GLOBAL point-light array (the snapshot), binding=5 per-instance light SET (8 int indices into it, -1 = unused), parallel to the binding=0 instance buffer (mirrors the U.3 clip-slot mechanism). accumulateLights keeps ambient + sun from the SceneLighting UBO (cleared as faithful by the lighting audit) and loops THIS instance's point lights. pointContribution factored out (same calc_point_light wrap+norm shape). - WbDrawDispatcher: per-entity light set computed ONCE at the isNewEntity site (constant across the entity's parts), by the entity's AABB sphere; threaded into grp.LightSets parallel to grp.Matrices; global + per-instance buffers uploaded in Phase 5. Camera-independent ⇒ stable for static buildings. - GameWindow: BuildPointLightSnapshot + dispatcher.SetSceneLights each frame. Tests: 17/17 LightManager + 36/36 dispatcher clip-slot/clip-frame green (parallel-array lockstep preserved). Visually gated: the meeting hall now holds steady as the camera approaches (was the popping symptom). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aa94cedc38
commit
4345e77d62
5 changed files with 473 additions and 50 deletions
|
|
@ -7766,6 +7766,16 @@ public sealed class GameWindow : IDisposable
|
|||
// frame — terrain, static mesh, instanced mesh, sky.
|
||||
UpdateSunFromSky(kf, playerInsideCell);
|
||||
Lighting.Tick(camPos);
|
||||
|
||||
// Fix B (A7 #3): build this frame's point-light snapshot and hand it to
|
||||
// the entity dispatcher for per-OBJECT light selection
|
||||
// (minimize_object_lighting). Replaces the single global nearest-8-to-
|
||||
// camera UBO set for point/spot lights so a wall's torches stay tied to
|
||||
// the wall as the camera moves. The SUN + ambient still flow through the
|
||||
// SceneLighting UBO built below (binding=1) — terrain/sky read those.
|
||||
Lighting.BuildPointLightSnapshot(camPos);
|
||||
_wbDrawDispatcher?.SetSceneLights(Lighting.PointSnapshot);
|
||||
|
||||
var ubo = AcDream.Core.Lighting.SceneLightingUbo.Build(
|
||||
Lighting, in atmo, camPos, (float)WorldTime.DayFraction);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue