diff options
Diffstat (limited to 'src/LivingVillage.Desktop/SceneDetailRender.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/SceneDetailRender.fs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/SceneDetailRender.fs b/src/LivingVillage.Desktop/SceneDetailRender.fs index df2fa10..8bda8a9 100644 --- a/src/LivingVillage.Desktop/SceneDetailRender.fs +++ b/src/LivingVillage.Desktop/SceneDetailRender.fs @@ -137,9 +137,71 @@ module SceneDetailRender = for (rect, color) in VillageArt.lanternGlowLayers cx cy radius 5 255 214 150 peak do spriteBatch.Draw(pixel, rect, color) + /// P79 夜帧炊烟增强:烟柱(3 段向上堆叠)+ 外发光。只在夜帧叠加绘制,白天帧不受影响。 + let private drawNightSmoke + (spriteBatch: SpriteBatch) + (textures: VillageArt.ArtTextures) + (pixel: Texture2D) + (camera: Vector2) + (map: MapGen.Result) + (tick: int64) + (nightStrength: float32) = + let alpha = SceneDetail.nightSmokeAlphaAt nightStrength + let glowPeak = SceneDetail.nightSmokeGlowPeakAt nightStrength + let source = VillageArt.atlasTileRectangle (22 + SceneDetail.smokeFrame tick) + let cell = SceneDetail.smokeCellSize nightStrength + for (x, y) in SceneDetail.smokeSourceTiles map do + let seed = x * 29 + y * 11 + let sway, rise = SceneDetail.smokeDrift tick seed + let baseX = tileX camera x + (Sim.tilePixels - cell) / 2 + let baseY = tileY camera y + (Sim.tilePixels - cell) / 2 + // 外发光:暖色径向柔光,让烟柱在夜色里浮起。 + for (rect, glowColor) in + VillageArt.lanternGlowLayers + (baseX + cell / 2) + (baseY + rise) + SceneDetail.nightSmokeGlowRadius + 4 + 255 + 236 + 200 + glowPeak do + spriteBatch.Draw(pixel, rect, glowColor) + // 烟柱:自屋顶向上堆叠,越上越淡,并在每段叠一枚中性柔光团(外发光), + // 弥补烟精灵本身 alpha 很低的问题,使夜色里每一缕烟柱都清晰可辨。 + for segment in 0 .. SceneDetail.nightSmokeSegments - 1 do + let segmentAlpha = max 1 (alpha * (SceneDetail.nightSmokeSegments - segment) / SceneDetail.nightSmokeSegments) + let segmentColor = VillageArt.premultiply 246 242 232 segmentAlpha + let sx = baseX + sway * (segment + 1) / 2 + let sy = baseY + rise - segment * SceneDetail.nightSmokeSegmentLift + spriteBatch.Draw(textures.TileAtlas, Rectangle(sx, sy, cell, cell), source, segmentColor) + let puffPeak = max 1 (glowPeak * (SceneDetail.nightSmokeSegments - segment) / (SceneDetail.nightSmokeSegments + 1)) + for (rect, puffColor) in + VillageArt.lanternGlowLayers (sx + cell / 2) (sy + cell / 2) 12 3 238 242 248 puffPeak do + spriteBatch.Draw(pixel, rect, puffColor) + + /// P79 夜景光晕去叠:每个光源最多 2 层(内芯 + 外环)、层间暗隙、半径收紧到 3 tile。 + let private drawNightHalos + (spriteBatch: SpriteBatch) + (pixel: Texture2D) + (camera: Vector2) + (map: MapGen.Result) + (includeRoadLanterns: bool) + (nightStrength: float32) = + let peak = SceneDetail.nightHaloPeakAlphaAt nightStrength + if peak > 0 then + let half = Sim.tilePixels / 2 + let radius = SceneDetail.nightHaloRadiusTiles * Sim.tilePixels + for (lx, ly) in VillageArt.nightLightTilesWith includeRoadLanterns map do + let cx = tileX camera lx + half + let cy = tileY camera ly + half + for (rect, color) in VillageArt.haloRingLayers cx cy radius peak do + spriteBatch.Draw(pixel, rect, color) + /// P78 夜帧加成层(水面光斑 + 桥头窄光晕):在 veil 之后调用,故不被夜色乘暗、仍醒目。 let drawNight (spriteBatch: SpriteBatch) + (textures: VillageArt.ArtTextures) (pixel: Texture2D) (camera: Vector2) (map: MapGen.Result) @@ -147,6 +209,8 @@ module SceneDetailRender = (nightStrength: float32) = drawNightWater spriteBatch pixel camera map tick nightStrength drawBridgeHalos spriteBatch pixel camera map nightStrength + drawNightHalos spriteBatch pixel camera map textures.Cc0TileAtlas.IsSome nightStrength + drawNightSmoke spriteBatch textures pixel camera map tick nightStrength /// 一次性绘制全部 P47 场景细节(倒影 → 岸边芦苇 → 漂浮元素 → 近景前景层 → P78 炊烟)。 let draw |
