Move light strength calculation to Light class

This commit is contained in:
Jarrod Doyle 2024-10-27 15:15:59 +00:00
parent 025f4d0508
commit 94b8af0f7f
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
2 changed files with 49 additions and 49 deletions

View File

@ -32,4 +32,52 @@ public class Light
Radius = Radius == float.MaxValue ? 0 : Radius, Radius = Radius == float.MaxValue ? 0 : Radius,
}; };
} }
public float StrengthAtPoint(Vector3 point, Plane plane)
{
// 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.
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;
// Inner radius starts a linear falloff to 0 at the radius
if (InnerRadius != 0 && len > InnerRadius)
{
strength *= (Radius - len) / (Radius - InnerRadius);
}
// This is basically the same as how inner radius works. It just applies
// a linear falloff to 0 between the inner angle and outer angle.
if (Spotlight)
{
var spotAngle = Vector3.Dot(-Vector3.Normalize(dir), SpotlightDir);
var inner = SpotlightInnerAngle;
var outer = SpotlightOuterAngle;
// In an improperly configured spotlight inner and outer angles might be the
// same. So to avoid division by zero (and some clamping) we explicitly handle
// some cases
float spotlightMultiplier;
if (spotAngle >= inner)
{
spotlightMultiplier = 1.0f;
}
else if (spotAngle <= outer)
{
spotlightMultiplier = 0.0f;
}
else
{
spotlightMultiplier = (spotAngle - outer) / (inner - outer);
}
strength *= spotlightMultiplier;
}
return strength;
}
} }

View File

@ -508,7 +508,7 @@ class Program
info.AnimLightBitmask |= 1u << paletteIdx; info.AnimLightBitmask |= 1u << paletteIdx;
layer = paletteIdx + 1; layer = paletteIdx + 1;
} }
var strength = CalculateLightStrengthAtPoint(light, pos, plane); var strength = light.StrengthAtPoint(pos, plane);
lightmap.AddLight(layer, x, y, light.Color, strength, hdr); lightmap.AddLight(layer, x, y, light.Color, strength, hdr);
} }
} }
@ -553,52 +553,4 @@ class Program
} }
}); });
} }
private static float CalculateLightStrengthAtPoint(Light light, Vector3 point, Plane plane)
{
// 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.
var dir = light.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;
// Inner radius starts a linear falloff to 0 at the radius
if (light.InnerRadius != 0 && len > light.InnerRadius)
{
strength *= (light.Radius - len) / (light.Radius - light.InnerRadius);
}
// This is basically the same as how inner radius works. It just applies
// a linear falloff to 0 between the inner angle and outer angle.
if (light.Spotlight)
{
var spotAngle = Vector3.Dot(-Vector3.Normalize(dir), light.SpotlightDir);
var inner = light.SpotlightInnerAngle;
var outer = light.SpotlightOuterAngle;
// In an improperly configured spotlight inner and outer angles might be the
// same. So to avoid division by zero (and some clamping) we explicitly handle
// some cases
float spotlightMultiplier;
if (spotAngle >= inner)
{
spotlightMultiplier = 1.0f;
}
else if (spotAngle <= outer)
{
spotlightMultiplier = 0.0f;
}
else
{
spotlightMultiplier = (spotAngle - outer) / (inner - outer);
}
strength *= spotlightMultiplier;
}
return strength;
}
} }