fix(render): A7 Fix D D-1 — clamp the point-light sum on its own (#140)
accumulateLights folded ambient+sun+torches into one accumulator clamped only in the frag, so a few warm intensity-100 torches blew walls/objects to white. Mirror retail SetStaticLightingVertexColors: sum point/spot into pointAcc, clamp to [0,1] (the baked emissive), THEN add ambient+sun, frag final-clamps. Matches LightBake.ComputeVertexColor (LightBakeConformanceTests). Per-light cap unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
39c70f00aa
commit
cf62793304
1 changed files with 14 additions and 10 deletions
|
|
@ -183,29 +183,33 @@ vec3 pointContribution(vec3 N, vec3 worldPos, GlobalLight L) {
|
|||
vec3 accumulateLights(vec3 N, vec3 worldPos, int instanceIndex) {
|
||||
vec3 lit = uCellAmbient.xyz;
|
||||
|
||||
// SUN / directional — from the SceneLighting UBO (global; the audit cleared
|
||||
// the ambient + sun chain as already faithful). Any point/spot entries still
|
||||
// present in the UBO from LightManager.Tick are IGNORED here — point lights
|
||||
// now come per-object from the SSBO below, so there's no double-count.
|
||||
// SUN / directional — material-lit term (added with ambient, NOT into the
|
||||
// torch sum), unchanged.
|
||||
int activeLights = int(uCellAmbient.w);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (i >= activeLights) break;
|
||||
if (int(uLights[i].posAndKind.w) != 0) continue; // directional only
|
||||
vec3 Ldir = -uLights[i].dirAndRange.xyz; // forward points INTO the scene
|
||||
vec3 Ldir = -uLights[i].dirAndRange.xyz;
|
||||
float ndl = max(0.0, dot(N, Ldir));
|
||||
lit += uLights[i].colorAndIntensity.xyz * uLights[i].colorAndIntensity.w * ndl;
|
||||
}
|
||||
|
||||
// POINT / SPOT — THIS object's selected set (minimize_object_lighting): 8 int
|
||||
// slots per instance into the global light buffer, -1 = unused. Camera-
|
||||
// independent, so a wall's torches light it the same regardless of viewer pos.
|
||||
// POINT / SPOT torches: their OWN accumulator (A7 Fix D, D-1). Retail's
|
||||
// SetStaticLightingVertexColors sums the static point lights from BLACK and
|
||||
// clamps the SUM to [0,1] before anything else (a baked emissive term), so a
|
||||
// few warm intensity-100 torches can't push the whole pixel to white the way
|
||||
// folding them into ambient+sun did. Mirrors LightBake.ComputeVertexColor
|
||||
// (LightBakeConformanceTests). Per-light cap inside pointContribution is unchanged.
|
||||
vec3 pointAcc = vec3(0.0);
|
||||
int base = instanceIndex * 8;
|
||||
for (int k = 0; k < 8; ++k) {
|
||||
int gi = instanceLightIdx[base + k];
|
||||
if (gi < 0) continue;
|
||||
lit += pointContribution(N, worldPos, gLights[gi]);
|
||||
pointAcc += pointContribution(N, worldPos, gLights[gi]);
|
||||
}
|
||||
return lit;
|
||||
lit += min(pointAcc, vec3(1.0)); // clamp the torch sum on its own (retail baked emissive)
|
||||
|
||||
return lit; // frag still does the final min(lit, 1.0)
|
||||
}
|
||||
|
||||
out vec3 vNormal;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue