summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/SceneDetailRender.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-28 20:58:24 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-28 20:58:24 +0800
commite46f1ddda07fc9c3d2617663ed28a3d1391c198b (patch)
tree01c5b074622a8d5ea58f6b11308165145c71b8d8 /src/LivingVillage.Desktop/SceneDetailRender.fs
parentf571b56359e4bb152b414a61527c4e9c6ef4cd53 (diff)
downloadliving-village-e46f1ddda07fc9c3d2617663ed28a3d1391c198b.tar.gz
p47: 整改 — 倒影改暖色垂直光柱(gap-skip穿桥面落水面,最长≥3格)+近景接入倒影+近景屋顶受光/背光双档luma
Diffstat (limited to 'src/LivingVillage.Desktop/SceneDetailRender.fs')
-rw-r--r--src/LivingVillage.Desktop/SceneDetailRender.fs62
1 files changed, 30 insertions, 32 deletions
diff --git a/src/LivingVillage.Desktop/SceneDetailRender.fs b/src/LivingVillage.Desktop/SceneDetailRender.fs
index 2136d25..abe0b89 100644
--- a/src/LivingVillage.Desktop/SceneDetailRender.fs
+++ b/src/LivingVillage.Desktop/SceneDetailRender.fs
@@ -6,40 +6,31 @@ open Microsoft.Xna.Framework.Graphics
open LivingVillage.Kernel
/// P47 场景细节渲染层:把 `SceneDetail` 的纯函数结果落成画面。
-/// 反射用「光源精灵垂直镜像 + 相位微抖」,岸边芦苇/漂浮元素用既有瓦片精灵与原创点阵图集,
-/// 近景屋顶用既有屋瓦精灵 + 统一方向阴影。全部只读,不改瓦片/可达性。
+/// 倒影为每个光源正下方一条暖色垂直光柱(核心 + 外晕,离光源越远越淡),
+/// 岸芦苇/漂浮元素用既有瓦片精灵与原创点阵图集,近景屋顶按统一光源分受光面/背光面。
+/// 全部只读,不改瓦片/可达性。
module SceneDetailRender =
let private tileX (camera: Vector2) (x: int) = x * Sim.tilePixels - int camera.X
let private tileY (camera: Vector2) (y: int) = y * Sim.tilePixels - int camera.Y
- let private drawFlipVertical
+ /// 河道倒影:每个光源在正下方水面格画一段暖色垂直光柱(外晕 20px + 核心 10px),
+ /// alpha 随离光源距离递减、逐格 ±1px 微抖,连成一条可辨认的暖色垂直条纹
+ /// (明显区别于蓝灰横向波纹)。
+ let private drawReflections
(spriteBatch: SpriteBatch)
- (atlas: Texture2D)
- (source: Rectangle)
- (x: int)
- (y: int)
- (color: Color) =
- spriteBatch.Draw(
- atlas,
- Rectangle(x, y, Sim.tilePixels, Sim.tilePixels),
- Nullable(source),
- color,
- 0.0f,
- Vector2.Zero,
- SpriteEffects.FlipVertically,
- 0.0f)
-
- /// 河道倒影:岸上每个光源在其正下方水面格画一份垂直镜像,随 waterFrameTickAt 相位水平微抖。
- let private drawReflections (spriteBatch: SpriteBatch) (textures: VillageArt.ArtTextures) (camera: Vector2) (map: MapGen.Result) (tick: int64) =
- let source, atlas =
- match textures.Cc0TileAtlas with
- | Some cc0 -> VillageArt.cc0TileRect VillageArt.cc0TileIndexStoneLantern, cc0
- | None -> VillageArt.atlasTileRectangle 20, textures.TileAtlas
- for (x, y, alpha) in SceneDetail.reflectionStreaks map do
+ (pixel: Texture2D)
+ (camera: Vector2)
+ (map: MapGen.Result)
+ (tick: int64) =
+ for (x, y, alpha, _) in SceneDetail.reflectionStreaks map do
let wobble = SceneDetail.reflectionWobbleAt tick x y
- let color = VillageArt.premultiply 255 214 168 alpha
- drawFlipVertical spriteBatch atlas source (tileX camera x + wobble) (tileY camera y) color
+ let cx = tileX camera x
+ let cy = tileY camera y
+ let halo = VillageArt.premultiply 255 150 70 (alpha * 3 / 5)
+ let core = VillageArt.premultiply 255 208 120 alpha
+ spriteBatch.Draw(pixel, Rectangle(cx + 4 + wobble, cy, 24, Sim.tilePixels), halo)
+ spriteBatch.Draw(pixel, Rectangle(cx + 10 + wobble, cy, 12, Sim.tilePixels), core)
/// 岸边芦苇加密度:用既有芦苇精灵补绘一层贴水芦苇。
let private drawBankReeds (spriteBatch: SpriteBatch) (textures: VillageArt.ArtTextures) (camera: Vector2) (map: MapGen.Result) =
@@ -69,17 +60,24 @@ module SceneDetailRender =
Nullable(source),
Color.White)
- /// 近景楼层层错落:屏幕空间前景屋顶带,所有阴影统一投向右下(SceneDetail.shadowOffsetPx)。
- let private drawForeground (spriteBatch: SpriteBatch) (textures: VillageArt.ArtTextures) (viewportWidth: int) (viewportHeight: int) (tick: int64) =
+ /// 近景楼层层错落:屏幕空间前景屋顶带。统一光源来自左上,故每段屋顶
+ /// 左半受光(暖亮)、右半背光(压暗),并整体投影到右下(shadowOffsetPx)。
+ let private drawForeground (spriteBatch: SpriteBatch) (textures: VillageArt.ArtTextures) (pixel: Texture2D) (viewportWidth: int) (viewportHeight: int) (tick: int64) =
let ridgeSource = VillageArt.atlasTileRectangle 8
let eaveSource = VillageArt.atlasTileRectangle 9
let shadowColor = VillageArt.premultiply 8 12 18 120
+ let litColor = VillageArt.premultiply 255 236 196 46
+ let darkColor = VillageArt.premultiply 6 10 18 110
let dx, dy = SceneDetail.shadowOffsetPx
for (x, y, w) in SceneDetail.foregroundRooftops viewportWidth viewportHeight tick do
- // 统一方向阴影:先把 eave 的暗色镜像平移一份到右下,再画本体。
+ // 统一方向的投影:先把 eave 的暗色镜像平移一份到右下,再画本体。
spriteBatch.Draw(textures.TileAtlas, Rectangle(x + dx, y + dy, w, Sim.tilePixels), Nullable(eaveSource), shadowColor)
spriteBatch.Draw(textures.TileAtlas, Rectangle(x, y - Sim.tilePixels, w, Sim.tilePixels), Nullable(ridgeSource), Color.White)
spriteBatch.Draw(textures.TileAtlas, Rectangle(x, y, w, Sim.tilePixels), Nullable(eaveSource), Color.White)
+ // 受光面 / 背光面:左半加暖亮、右半压暗,形成两档以上 luma 差。
+ let half = max 1 (w / 2)
+ spriteBatch.Draw(pixel, Rectangle(x, y - Sim.tilePixels, half, 2 * Sim.tilePixels), litColor)
+ spriteBatch.Draw(pixel, Rectangle(x + half, y - Sim.tilePixels, w - half, 2 * Sim.tilePixels), darkColor)
/// 一次性绘制全部 P47 场景细节(倒影 → 岸边芦苇 → 漂浮元素 → 近景前景层)。
let draw
@@ -91,7 +89,7 @@ module SceneDetailRender =
(viewportHeight: int)
(map: MapGen.Result)
(tick: int64) =
- drawReflections spriteBatch textures camera map tick
+ drawReflections spriteBatch pixel camera map tick
drawBankReeds spriteBatch textures camera map
drawFloaters spriteBatch textures camera map tick
- drawForeground spriteBatch textures viewportWidth viewportHeight tick
+ drawForeground spriteBatch textures pixel viewportWidth viewportHeight tick