Apply LmParams attenuation

This commit is contained in:
Jarrod Doyle 2025-02-16 11:44:02 +00:00
parent 4827ffb76b
commit f4d5dcbd5a
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
2 changed files with 24 additions and 9 deletions

View File

@ -56,21 +56,24 @@ public class Light
SpotlightDir = Vector3.Normalize(Vector3.Transform(vhotLightDir, scale * rotate)); SpotlightDir = Vector3.Normalize(Vector3.Transform(vhotLightDir, scale * rotate));
} }
public float StrengthAtPoint(Vector3 point, Plane plane, uint lightCutoff) public float StrengthAtPoint(Vector3 point, Plane plane, uint lightCutoff, float attenuation)
{ {
// Calculate light strength at a given point. As far as I can tell // Calculate light strength at a given point. As far as I can tell
// this is exact to Dark (I'm a genius??). It's just an inverse distance // this is exact to Dark (I'm a genius??).
// falloff with diffuse angle, except we have to scale the length.
var dir = Position - point; var dir = Position - point;
var angle = Vector3.Dot(Vector3.Normalize(dir), plane.Normal);
var len = dir.Length(); var len = dir.Length();
var slen = len / 4.0f; dir = Vector3.Normalize(dir);
var strength = (angle + 1.0f) / slen;
// Base strength is a scaled inverse falloff
var strength = 4.0f / MathF.Pow(len, attenuation);
// Diffuse light angle
strength *= 1.0f + MathF.Pow(Vector3.Dot(dir, plane.Normal), attenuation);
// Inner radius starts a linear falloff to 0 at the radius // Inner radius starts a linear falloff to 0 at the radius
if (InnerRadius != 0 && len > InnerRadius) if (InnerRadius != 0 && len > InnerRadius)
{ {
strength *= (Radius - len) / (Radius - InnerRadius); strength *= MathF.Pow((Radius - len) / (Radius - InnerRadius), attenuation);
} }
// Anim lights have a (configurable) minimum light cutoff. This is checked before // Anim lights have a (configurable) minimum light cutoff. This is checked before
@ -102,6 +105,7 @@ public class Light
} }
else else
{ {
// Interestingly DromEd doesn't apply attenuation here
spotlightMultiplier = (spotAngle - outer) / (inner - outer); spotlightMultiplier = (spotAngle - outer) / (inner - outer);
} }

View File

@ -22,12 +22,19 @@ public class LightMapper
{ {
public Vector3[] AmbientLight; public Vector3[] AmbientLight;
public bool Hdr; public bool Hdr;
public float Attenuation;
public float Saturation;
public SoftnessMode MultiSampling; public SoftnessMode MultiSampling;
public float MultiSamplingCenterWeight; public float MultiSamplingCenterWeight;
public bool LightmappedWater; public bool LightmappedWater;
public SunSettings Sunlight; public SunSettings Sunlight;
public uint AnimLightCutoff; public uint AnimLightCutoff;
public bool UsePvs; public bool UsePvs;
public override string ToString()
{
return $"Ambient Levels: {AmbientLight}, Hdr: {Hdr}, Attenuation: {Attenuation}, Saturation: {Saturation}";
}
} }
private ResourcePathManager.CampaignResources _campaign; private ResourcePathManager.CampaignResources _campaign;
@ -106,6 +113,8 @@ public class LightMapper
{ {
Hdr = worldRep.DataHeader.LightmapFormat == 2, Hdr = worldRep.DataHeader.LightmapFormat == 2,
AmbientLight = [..ambientLight], AmbientLight = [..ambientLight],
Attenuation = lmParams.Attenuation,
Saturation = lmParams.Saturation,
MultiSampling = lmParams.ShadowSoftness, MultiSampling = lmParams.ShadowSoftness,
MultiSamplingCenterWeight = lmParams.CenterWeight, MultiSamplingCenterWeight = lmParams.CenterWeight,
LightmappedWater = lmParams.LightmappedWater, LightmappedWater = lmParams.LightmappedWater,
@ -114,6 +123,8 @@ public class LightMapper
UsePvs = pvs, UsePvs = pvs,
}; };
Log.Information("Lighting Settings: {Settings}", settings);
Timing.TimeStage("Gather Lights", BuildLightList); Timing.TimeStage("Gather Lights", BuildLightList);
Timing.TimeStage("Set Light Indices", () => SetCellLightIndices(settings)); Timing.TimeStage("Set Light Indices", () => SetCellLightIndices(settings));
Timing.TimeStage("Trace Scene", () => TraceScene(settings)); Timing.TimeStage("Trace Scene", () => TraceScene(settings));
@ -791,7 +802,7 @@ public class LightMapper
if (!TraceOcclusion(_scene, light.Position, point)) if (!TraceOcclusion(_scene, light.Position, point))
{ {
strength += targetWeights[idx] * light.StrengthAtPoint(point, plane, settings.AnimLightCutoff); strength += targetWeights[idx] * light.StrengthAtPoint(point, plane, settings.AnimLightCutoff, settings.Attenuation);
} }
} }