用途
blender-weather-fx 是一套用于 Blender 5.2 的天气效果工具集,通过几何节点(Geometry Nodes)生成可无缝循环的雨、雪、灰尘、灰烬和余烬等降水效果,并配套表面湿润、水坑、涟漪、水痕、积雪以及闪电。执行模型位于 blender-core,天空、太阳/月亮、雾与氛围来自 blender-time-of-day,因此应先运行 scene_mood.py,再添加天气;渲染设置位于 blender-rendering。
主要能力
降水 precipitation.py(雨、雪、灰尘、灰烬、余烬)
- 在 ENV_Weather_<Type> 上构建几何节点修改器,其方盒覆盖相机在帧范围内的可见范围;盒体固定于世界,因此相机移动不会拖拽雨滴。无相机时覆盖 18 米方盒。地面为 --ground 物体最高的顶面。
- 无缝循环且无需模拟:每个粒子在每次循环中存活 N 个整周期(Lives),因此最后一帧 + 1 恰好等于第一帧。任何帧都可单独渲染,支持无头运行。
- 真实速度:雨 7 m/s(heavy/storm 为 9),雪 1,灰烬 0.6,灰尘 0.15,余烬以 1.5 上升,并与 --wind X Y(m/s)叠加。
- 地面:对 --ground 物体做射线检测,粒子在首次命中处停止(屋顶、雨棚、街道)。雨在每个命中点生成持续 80 ms 的溅射冠,对齐表面法线。
- 雨使用三面长条而非运动模糊:长度 = 速度 × 半帧(180° 快门),对齐运动方向。关闭运动模糊更省且效果相同。
- 距相机 1.5 m 内的粒子会隐藏(Near Clear)。视口显示 10%(Viewport Fraction),渲染显示 100%。
- 各强度密度(粒子/m³):雨 5/15/40/80,雪 10/30/80/160。可用 --density 覆盖。数量受 --max-count(400k)上限约束,达到上限时会警告。
- 所有数值均保留为修改器输入(Count、Speed、Wind、Lives、Particle Size、Streak Length、Sway、Ground、Splash 等),可在修改器中直接微调而不必重跑脚本。
表面天气 surface_weather.py(湿润、水坑、涟漪、水痕、积雪)
- 在每个 Principled BSDF 前放置一个 ENV_Weather 着色器组,并将原始连接记录在材质上;--remove 可精确恢复链接与数值。
- Wet(Lagarde 模型):多孔反照率变暗(最多 55% × --porosity),粗糙度下降,并作为 Coat 添加水膜。沥青、混凝土、木材和织物建议 porosity 0.6–0.9,金属、玻璃和塑料建议 0.1–0.2。
- 水坑:朝上面使用域扭曲的世界空间噪声。覆盖率约等于 --puddles,特征尺寸为 --scale(米,默认 3)。水坑内部为全 Coat、镜面 Coat 粗糙度 0.02,并压平基础法线,因为水填满了裂缝。
- 涟漪:扩张的圆环,每个约 17 cm 单元一个,由帧驱动器驱动(简单表达式,无需自动运行脚本即可工作),仅在水坑内显示。
- 水痕:墙面上的垂直噪声添加 Coat 流痕。
- 积雪:朝上覆盖并带噪声边缘,反照率 0.9、粗糙度 0.6 和细致凹凸。--snow-depth 通过 ENV_SnowCover 几何节点修改器添加真实厚度:朝上面被细分并沿向上方向按永不为零的噪声高度挤出,因此不会出现 z-fighting。使用带次表面散射的 ENV_M_Snow 材质。
- --vertex-mask 写入 ENV_Weather 颜色属性(R 水坑、G 雪、B 墙面),供引擎着色器使用。
闪电 lightning.py
- 一次打击包含 3 次回击,间隔约 50 ms(至少相隔 2 帧,以便在 24 fps 下读出闪烁感),每次为先峰值后 2 帧衰减。可用 --strokes、--flashes 或 --frames 设置时序。闪光为偏冷的 ENV_Storm_Flash 太阳(12° 柔和),相对场景主光键控(×2.5)。
- ENV_Storm_Bolt 是一条带分支的自发光曲线(中点位移加 4 条分支),与闪光一起键控。默认距 300 米、位于画面内且偏离中心。世界背景强度也会闪烁(--no-sky 可跳过)。
- 关键帧使用 LINEAR 插值(闪光必须突变而非缓动)。
使用方式
一次调用一个脚本的示例命令:
scripts/precipitation.py -- --type rain --intensity heavy --ground Street Roofs --wind 2 0
scripts/surface_weather.py -- --objects Street Car Walls --wetness 0.7 --puddles 0.4 --ripples 1 --streaks 0.5
scripts/lightning.py -- --flashes 2 --strokes 3
scripts/precipitation.py -- --type snow --intensity moderate --ground Terrain
scripts/surface_weather.py -- --objects Terrain Roofs --snow 0.8 --snow-depth 0.06
scripts/surface_weather.py -- --objects Street Car Walls --remove # 精确恢复
一个雨夜示例流程:scene_mood.py --time night --fog-visibility 250 → 雨 → 湿润 + 水坑 → 闪电。雨和水坑在夜晚最能烘托湿润场景:湿表面会反射每一处实际灯光。
适用场景与规则
- 雨只有在逆光或侧光、背景较暗时才可见:在其后方放置实际灯光或明亮天空。正面打光的雨会消失。
- 组合图层:雾(大气)+ 雨条(中景)+ 溅射/涟漪(地面)+ 湿反射。任何单独一层看起来都假。
- 真实尺度是强制要求:速度、密度和水坑尺寸均以米为单位(blender-scene-setup)。
- 以最终分辨率渲染检查。雨密度和雨条可见性不会在视口中显示(10% 数量、无雾)。
- 若资产将导出,对雪的几何体运行 blender-asset-qa。
游戏与实时
天气是引擎系统(Unreal Niagara、Unity VFX Graph、Roblox ParticleEmitter)。从 Blender 可导出掩码:顶点颜色属性(--vertex-mask)或烘焙贴图(blender-texture-baking 对湿材质自烘焙),以及积雪网格。细节见 references/realtime-engines.md。物理数值与外观库见 references/weather-values.md。
限制与注意事项
- 几何节点粒子为实例,因此 object.data 保持为空。需通过求值后的 depsgraph(depsgraph.object_instances)读取结果。
- 后台(-b)求值对 Is Viewport 节点而言算作视口,因此无头测试只看到 10% 的数量。渲染为 100%。
- 地面对象被链接(而非移动)到 ENV_Weather_<Type>_Ground 集合。
- surface_weather 会修改共享材质:使用该材质的每个对象都会变湿。应先复制材质以限制影响。
- Coat 在两个引擎中都出现。EEVEE 需要开启光线追踪(eevee.use_raytracing)才能获得良好的水坑反射。