refactor(lighting): extract GlobalLightPacker (shared binding=4 layout) — A7 Fix D prep

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-18 17:19:27 +02:00
parent ad53180190
commit 180b4af2a9
3 changed files with 105 additions and 32 deletions

View file

@ -142,7 +142,7 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
private uint _globalLightsSsbo;
private uint _instLightSetSsbo;
private int[] _lightSetData = new int[256 * LightManager.MaxLightsPerObject];
private float[] _globalLightData = new float[16 * 16]; // 16 floats (4 vec4) per GlobalLight
private float[] _globalLightData = new float[GlobalLightPacker.FloatsPerLight * 16]; // 16 floats (4 vec4) per GlobalLight
// This frame's point-light snapshot, handed in by GameWindow before Draw via
// SetSceneLights. Null/empty ⇒ only ambient + sun render (all instance sets -1).
private IReadOnlyList<LightSource>? _pointSnapshot;
@ -1812,39 +1812,12 @@ public sealed unsafe class WbDrawDispatcher : IDisposable
/// </summary>
private unsafe void UploadGlobalLights()
{
var snap = _pointSnapshot;
int n = snap?.Count ?? 0;
int n = GlobalLightPacker.Pack(_pointSnapshot, ref _globalLightData);
int count = n > 0 ? n : 1; // never zero-size
int floatsNeeded = count * 16;
if (_globalLightData.Length < floatsNeeded)
_globalLightData = new float[floatsNeeded + 16 * 16];
Array.Clear(_globalLightData, 0, floatsNeeded);
for (int i = 0; i < n; i++)
{
var L = snap![i];
int o = i * 16;
// posAndKind (xyz world pos, w kind)
_globalLightData[o + 0] = L.WorldPosition.X;
_globalLightData[o + 1] = L.WorldPosition.Y;
_globalLightData[o + 2] = L.WorldPosition.Z;
_globalLightData[o + 3] = (int)L.Kind;
// dirAndRange (xyz forward, w range = Falloff×1.3)
_globalLightData[o + 4] = L.WorldForward.X;
_globalLightData[o + 5] = L.WorldForward.Y;
_globalLightData[o + 6] = L.WorldForward.Z;
_globalLightData[o + 7] = L.Range;
// colorAndIntensity (xyz linear colour, w intensity)
_globalLightData[o + 8] = L.ColorLinear.X;
_globalLightData[o + 9] = L.ColorLinear.Y;
_globalLightData[o + 10] = L.ColorLinear.Z;
_globalLightData[o + 11] = L.Intensity;
// coneAngleEtc (x cone radians; yzw reserved)
_globalLightData[o + 12] = L.ConeAngle;
}
// Pack guarantees _globalLightData holds at least max(n,1) * FloatsPerLight floats.
fixed (float* gp = _globalLightData)
UploadSsbo(_globalLightsSsbo, 4, gp, count * 16 * sizeof(float));
UploadSsbo(_globalLightsSsbo, 4, gp,
count * GlobalLightPacker.FloatsPerLight * sizeof(float));
}
/// <summary>