From 94b8af0f7f936b9199f9c4a7d13f1d4baf7c1b03 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Sun, 27 Oct 2024 15:15:59 +0000 Subject: [PATCH] Move light strength calculation to Light class --- KeepersCompound.Lightmapper/Light.cs | 48 +++++++++++++++++++++++++ KeepersCompound.Lightmapper/Program.cs | 50 +------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/KeepersCompound.Lightmapper/Light.cs b/KeepersCompound.Lightmapper/Light.cs index 5eff220..931b02d 100644 --- a/KeepersCompound.Lightmapper/Light.cs +++ b/KeepersCompound.Lightmapper/Light.cs @@ -32,4 +32,52 @@ public class Light 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; + } } \ No newline at end of file diff --git a/KeepersCompound.Lightmapper/Program.cs b/KeepersCompound.Lightmapper/Program.cs index c452047..5662af1 100644 --- a/KeepersCompound.Lightmapper/Program.cs +++ b/KeepersCompound.Lightmapper/Program.cs @@ -508,7 +508,7 @@ class Program info.AnimLightBitmask |= 1u << paletteIdx; layer = paletteIdx + 1; } - var strength = CalculateLightStrengthAtPoint(light, pos, plane); + var strength = light.StrengthAtPoint(pos, plane); 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; - } } \ No newline at end of file