From 76a6850bb88546fc21f5f78a53fbda04e77c8b52 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 13:11:52 +0800 Subject: feat(desktop): 确定性昼夜光照过渡与夜灯暖光 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 lightingBlend 纯函数(黎明明 4:00-6:00、暮色 20:00-22:00 线性过渡,边界与 isNightTick 对齐),天空底色/世界 tint 按混合插值渲染,夜晚灯笼暖光晕强度=LanternGlow(纯叠加矩形、无每帧分配风险);回归测试含锚点/单调斜坡/确定性/光晕开关。 --- src/LivingVillage.Desktop.Tests/PrototypeTests.fs | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/LivingVillage.Desktop.Tests') diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs index 7e4ce5f..d77abd6 100644 --- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs +++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs @@ -669,6 +669,41 @@ type PrototypeTests () = let needsView = { M5Interaction.initial with Panel = NeedsPanel } Assert.AreEqual(None, M5Interaction.refreshPrompt world needsView |> fun value -> value.Prompt) + [] + member _.DayPhaseLightingIsPureDeterministicAndTransitionsSmoothly () = + let ticksPerHour = Sim.ticksPerDay / 24L + let atHour hour = M6Presentation.lightingAtTick (int64 hour * ticksPerHour) + + // Anchors: full day at noon, full night at midnight, no drift. + Assert.AreEqual(0.0f, (atHour 12).Blend) + Assert.AreEqual(1.0f, (atHour 0).Blend) + Assert.AreEqual(1.0f, (atHour 2).Blend) + + // Dawn ramp: 4:00 -> 6:00 goes night -> day, monotonic. + let dawnStart = (atHour 4).Blend + let dawnMid = (M6Presentation.lightingAtTick (int64 5 * ticksPerHour)).Blend + let dawnEnd = (atHour 6).Blend + Assert.AreEqual(1.0f, dawnStart) + Assert.AreEqual(0.5f, dawnMid) + Assert.AreEqual(0.0f, dawnEnd) + + // Dusk ramp 20:00 -> 22:00 goes day -> night monotonically. + let duskStart = (atHour 20).Blend + let duskMid = (M6Presentation.lightingAtTick (int64 21 * ticksPerHour)).Blend + let duskEnd = (atHour 22).Blend + Assert.AreEqual(0.0f, duskStart) + Assert.AreEqual(0.5f, duskMid) + Assert.AreEqual(1.0f, duskEnd) + + // Determinism without randomness. + let once = atHour 13 + let twice = atHour 13 + Assert.AreEqual(once, twice) + + // Lantern glow: warm halo only rises with night blend. + Assert.AreEqual(0.0f, (atHour 13).LanternGlow) + Assert.AreEqual(1.0f, (atHour 0).LanternGlow) + [] member _.WorldPanelDoesNotRenderA永久KeyList () = let world = Sim.initialWorldN 42UL 0 -- cgit v1.2.3