Move light strength calculation to Light class
This commit is contained in:
parent
025f4d0508
commit
94b8af0f7f
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue