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,23 +56,26 @@ public class Light
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
// this is exact to Dark (I'm a genius??). It's just an inverse distance
// falloff with diffuse angle, except we have to scale the length.
// this is exact to Dark (I'm a genius??).
var dir = Position - point;
var angle = Vector3.Dot(Vector3.Normalize(dir), plane.Normal);
var len = dir.Length();
var slen = len / 4.0f;
var strength = (angle + 1.0f) / slen;
dir = Vector3.Normalize(dir);
// 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
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
// spotlight multipliers are applied so we don't cutoff the spot radius falloff.
if (Anim && strength * Brightness < lightCutoff)
@ -102,6 +105,7 @@ public class Light
}
else
{
// Interestingly DromEd doesn't apply attenuation here
spotlightMultiplier = (spotAngle - outer) / (inner - outer);
}

View File

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