using MrGameEng.Lighting; using Xunit; namespace MrGameEng.Lighting.Tests; public class LightmapBuilderTests { private static float[] Build( int width, int height, float ambient, bool[] occluders, params LightSample[] lights ) { var light = new float[width * height]; LightmapBuilder.Build(light, width, height, ambient, occluders, lights); return light; } [Fact] public void Ambient_WithoutOccluders_IsUniform() { var light = Build(4, 4, 0.6f, new bool[16]); Assert.All(light, v => Assert.Equal(0.6f, v, 5)); } [Fact] public void OccluderCell_IsDarkerThanOpenCell() { var occ = new bool[9]; occ[4] = true; // centre cell shaded var light = Build(3, 3, 0.8f, occ); Assert.True(light[4] < light[0]); Assert.Equal(0.8f * LightmapBuilder.OccluderShade, light[4], 5); } [Fact] public void PointLight_IsBrighterNearSourceAndFadesToRadius() { var light = Build(7, 1, 0f, new bool[7], new LightSample(0, 0, 6f, 1f)); Assert.True(light[0] > light[2] && light[2] > light[5]); Assert.InRange(light[6], 0f, 0.01f); // на радиусе свет угасает } [Fact] public void Occluder_CastsShadowBehindIt() { var occ = new bool[7]; occ[3] = true; // препятствие между источником (0) и дальними клетками var light = Build(7, 1, 0f, occ, new LightSample(0, 0, 10f, 1f)); Assert.True(light[1] > 0f); // перед препятствием — освещено Assert.Equal(0f, light[5], 5); // за препятствием — тень } [Fact] public void Values_StayWithinUnitRange() { var light = Build( 5, 5, 0.5f, new bool[25], new LightSample(2, 2, 4f, 2f) // яркий свет — проверяем клампинг ); Assert.All(light, v => Assert.InRange(v, 0f, 1f)); } }