summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/SceneDetail.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-29 16:02:35 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-29 16:02:35 +0800
commit975d6721973fa526014fb2401e97075ecbf51c2c (patch)
tree2099e87d01f742ce57868e20a20abb2ba2fa8e7c /src/LivingVillage.Desktop/SceneDetail.fs
parent3196b4914d037052db0cf191be0431dc4ac4d596 (diff)
downloadliving-village-975d6721973fa526014fb2401e97075ecbf51c2c.tar.gz
p78: 夜帧水面微光斑、生成器世界炊烟与桥头窄光晕
Diffstat (limited to 'src/LivingVillage.Desktop/SceneDetail.fs')
-rw-r--r--src/LivingVillage.Desktop/SceneDetail.fs70
1 files changed, 69 insertions, 1 deletions
diff --git a/src/LivingVillage.Desktop/SceneDetail.fs b/src/LivingVillage.Desktop/SceneDetail.fs
index 50313ac..54665ac 100644
--- a/src/LivingVillage.Desktop/SceneDetail.fs
+++ b/src/LivingVillage.Desktop/SceneDetail.fs
@@ -144,7 +144,75 @@ module SceneDetail =
let floatFrame (tick: int64) (seed: int) : int =
int (positiveModulo64 2L (tick / 32L + int64 seed))
- // ---------------- 近景楼层层错落(屏幕空间前景层) ----------------
+ // ---------------- P78 夜帧水面逐格微光斑 ----------------
+
+ /// 光斑候选水面格:水面/水田按位置 hash 稀疏取样(约 1/6 水面格),位置确定性。
+ /// 帧号只驱动相位/位移,同帧同 tick 逐字节可复现。
+ let waterGlintTiles (map: MapGen.Result) : (int * int) list =
+ if map.Width <= 0 then
+ []
+ else
+ [ for y in 1 .. map.Height - 2 do
+ for x in 0 .. map.Width - 1 do
+ if isWaterSurface map x y && (x * 5 + y * 3) % 6 = 0 then
+ yield (x, y) ]
+
+ let waterGlintPhaseCount = 4
+
+ /// 逐格相位(0..3),只随 tick 慢速切换,让相邻光斑不同步闪烁。
+ let waterGlintPhase (tick: int64) (x: int) (y: int) : int =
+ int (positiveModulo64 4L (tick / 8L + int64 (x * 3 + y * 5)))
+
+ /// 光斑 alpha:夜越深越亮;相位在满亮/六成亮间呼吸,保证暗部有两档以上层次。
+ let waterGlintAlpha (nightStrength: float32) (phase: int) : int =
+ if nightStrength <= 0.0f then
+ 0
+ else
+ let baseAlpha = 46.0f + 78.0f * max 0.0f (min 1.0f nightStrength)
+ int (baseAlpha * (if phase % 2 = 0 then 1.0f else 0.6f))
+
+ /// 帧号驱动的光斑水平位移(±1px),镜像水面波纹,同帧确定性。
+ let waterGlintOffset (tick: int64) (x: int) (y: int) : int =
+ int (positiveModulo64 3L (tick / 16L + int64 (x + y))) - 1
+
+ // ---------------- P78 炊烟(生成器世界) ----------------
+
+ /// 生成器世界的炊烟源:每户民居与散落农舍屋顶脊上一格(沿用样例世界 0,-3 偏移)。
+ let smokeSourceTiles (map: MapGen.Result) : (int * int) list =
+ (map.Buildings @ map.Farmhouses)
+ |> List.map (fun building -> building.DoorX, building.DoorY - 3)
+ |> List.distinct
+
+ /// 炊烟三相位(复用 VillageArt 的确定性帧),供绘制取精灵。
+ let smokeFrame (tick: int64) : int =
+ VillageArt.smokeFrameTick tick
+
+ /// 炊烟上升/摇曳位移:随 tick 缓慢升高并左右摆动,有界、逐帧连续。
+ let smokeDrift (tick: int64) (seed: int) : int * int =
+ let rise = int (positiveModulo64 5L (tick / 24L + int64 seed))
+ let sway = int (positiveModulo64 3L (tick / 32L + int64 (seed * 3 + 1))) - 1
+ (sway, -rise)
+
+ /// 炊烟 alpha:夜帧更醒目(用户要求夜间存在感更强),白天仍可辨。
+ let smokeAlphaAt (nightStrength: float32) : int =
+ let night = max 0.0f (min 1.0f nightStrength)
+ int (78.0f + 104.0f * night)
+
+ /// 炊烟绘制边长:夜帧略放大,增强存在感。
+ let smokeCellSize (nightStrength: float32) : int =
+ let night = max 0.0f (min 1.0f nightStrength)
+ int (20.0f + 8.0f * night)
+
+ // ---------------- P78 桥头灯柱近圈光晕 ----------------
+
+ /// 桥头灯柱瓦片(与 VillageArt.bridgeLanternTiles 同源,供窄光晕绘制与取证计数)。
+ let bridgeLanternTiles (map: MapGen.Result) : (int * int) list =
+ VillageArt.bridgeLanternTiles map
+
+ /// 窄光晕半径(tile):固定 1,只围灯柱一圈,不铺满整条河。
+ let bridgeHaloRadiusTiles = 1
+
+ /// ---------------- 近景楼层层错落(屏幕空间前景层) ----------------
/// 前景层屋顶分段:等宽 tile 分段、高度按确定性函数错落(0/8/16/24 px 四层),
/// 并随 tick 极慢移动(视差)。返回 (x, y, width)。