UE5 动态天气系统:雨、雪、雾的 Niagara 实现方案

上周有个学员在群里发了一张截图:他的开放世界场景里,雨滴像“塑料片”一样直直砸下来,没有风、没有雾气,角色走进雨里连衣服都不会湿。他问我:“老师,为什么别人的雨景那么真实,我的就像在淋浴间打开花洒?”

这个问题其实很典型。很多新手用 UE5 做天气系统,要么依赖插件(比如 Ultra Dynamic Sky),要么直接拿 Niagara 模板改两下参数。但真正要做出“有灵魂”的雨雪,必须理解三个核心:粒子生命周期管理碰撞与交互反馈多层视觉效果叠加

本文会从零开始,用 Niagara 搭建雨、雪、雾三种动态天气系统。所有操作基于 UE5.3.2,Niagara 版本为 v2.0。准备好,我们直接上手。

一、暴雨系统:从“塑料片”到“真实雨幕”

1.1 基础粒子发射器设置

新建一个 Niagara System,选择 Empty 模板,添加一个 Sprite Renderer。关键参数如下:

  • Spawn Rate:8000-12000 粒子/秒(暴雨级别)
  • Lifetime:0.8-1.2 秒(随机范围,模拟不同下落高度)
  • Initial Velocity:Z 轴 -800 到 -1200(模拟风速影响,加少量 X/Y 随机抖动)
  • 这里有个坑:很多人把粒子设成“从天空盒高度下落”,但 UE5 的 Niagara 默认粒子出生位置是 Local Space。正确做法是:

    1. 在 Emitter State 中勾选 Use Local Space → 取消
    2. Spawn Location 设为 Grid Location,范围 X/Y 为场景大小(比如 2000×2000),Z 轴固定为 500(高于最高建筑)

    1.2 风场与旋转效果

    真实雨滴不是垂直下落的。在 Particle Update 中添加:

  • Force:X 轴 50-150(风向),Y 轴 -50 到 50(随机扰动)
  • Drag:0.05(空气阻力,让粒子不会无限加速)
  • Rotation:启用,让雨滴沿风速方向旋转(Sprite 模式下用 Face Camera 无效,需要改用 Mesh Renderer 加长条模型)
  • 进阶技巧:用 Noise 模块给风速添加 Perlin 噪声,让风产生阵发性变化。参数:Frequency 0.1,Amplitude 30,Octaves 2。

    1.3 碰撞与涟漪反馈

    这是让雨“活起来”的关键。在 Particle Update 中添加 Collision

  • Collision TypeWorld Dynamic
  • Restitution:0.1(模拟水花飞溅)
  • Friction:0.8(落地后滑动)
  • 当粒子碰撞地面时,我们需要生成次级粒子(涟漪)。在 Event Handler 中:

    1. 添加 Generate Collision Event
    2. 新建一个 Emitter(子发射器),接收碰撞事件
    3. 子发射器参数:Spawn Rate = 碰撞事件数量 × 3(每个雨滴生成 3 个涟漪粒子)
    4. 涟漪粒子生命周期:0.2-0.5 秒,向外扩散的圆环(用 Scale 随时间变大)

    雨滴碰撞涟漪效果示例

    1.4 视觉增强:雨幕与屏幕效果

    雨幕:添加一个 Volume 模式发射器,粒子为半透明蓝色矩形(长宽比 1:3),密度低(2000 粒子/秒),Z 轴速度慢(-200),模拟远处的雨帘。

    屏幕效果:在材质中实现“雨滴模糊”。新建一个 Post Process Material,用 UV 扰动模拟雨滴划过屏幕的效果。具体步骤:

  • 材质节点:SceneTexture(SceneColor)→ Panner(速度向量 = (0.1, 0.2))→ Lerp 混合原始颜色
  • 强度用 Distance Field 控制(近景强、远景弱)
  • 二、降雪系统:轻盈与堆积的平衡

    2.1 雪花的物理模拟

    雪花比雨滴轻,下落速度慢且受风影响更大。关键参数调整:

  • Spawn Rate:3000-5000 粒子/秒(雪比雨稀疏)
  • Lifetime:3-5 秒
  • Initial Velocity:Z 轴 -100 到 -300,X/Y 轴 ±200(大量随机扰动)
  • Drag:0.2(高阻力模拟雪花飘落)
  • 雪花形状:使用六边形纹理(可在 Substance Designer 中生成),Sprite RendererBlend Mode 设为 Additive,让雪花半透明叠加。

    2.2 堆积效果:World Position Offset 技巧

    这是 UE5 实现雪堆积的核心方法。在 材质 中:

    1. 获取 World Position,映射到场景网格
    2. 用 Noise 生成雪的高度图(Frequency 0.02,Amplitude 30)
    3. 通过 World Position Offset 节点抬高模型顶点

    注意:这个方法只对静态网格体生效。如果要动态物体(如角色)也积雪,需要结合 Virtual Heightfield Mesh 或自定义 Runtime Virtual Texture

    雪堆积效果实现示意图

    2.3 雪地脚印与交互

    Niagara 中,用 Collision Event 检测雪花落地位置,然后:

    1. 在碰撞点生成 Decal Actor(脚印贴图)
    2. 脚印材质用 Alpha Channel 控制透明度,随时间淡出(30-60 秒)
    3. 用 Distance Field 检测角色位置,动态生成脚印序列

    性能优化:脚印数量限制在 200 个以内,超出后移除最早的脚印。用 Object Pool 管理 Decal Actor。

    三、雾气系统:层次感与动态扩散

    3.1 基础雾效:Height Fog 的局限性

    UE5 内置的 Exponential Height Fog 只能做均匀雾效,无法表现“雾团”或“流动雾”。我们需要用 Niagara Volume 实现。

    新建一个 Niagara System,选择 Volume 模板。关键参数:

  • Spawn Rate:1000-3000 粒子/秒
  • Lifetime:10-20 秒
  • Particle Size:50-200 单位(随机)
  • Opacity:0.1-0.3(半透明叠加)
  • 3.2 流动雾的实现

    添加 Noise 驱动粒子位置:

  • Noise Strength:X/Y/Z 各 50-100
  • Frequency:0.05(低频产生大范围流动)
  • Turbulence:0.3(增加不规则性)
  • 关键技巧:用 Particle Attribute Reader 读取相邻粒子的位置,模拟“雾团”之间的粘滞力。在 Particle Update 中:

    1. 添加 Neighbor Grid3D(分辨率 32x32x32)
    2. 对每个粒子,计算与邻居的平均距离,施加 Spring Force(强度 0.01)
    3. 这样雾团会自然聚散,而不是随机飘散

    3.3 分层雾与高度控制

    现实中的雾是分层的:地面雾、中层雾、高空雾。用三个发射器分别控制:

  • 地面雾:Z 轴范围 0-50,密度高(Opacity 0.4)
  • 中层雾:Z 轴范围 50-200,密度中等(Opacity 0.2)
  • 高空雾:Z 轴范围 200-500,密度低(Opacity 0.1)
  • 过渡平滑:用 Height Blend 材质节点,根据世界高度混合不同雾层的颜色和密度。

    分层雾效渲染效果

    3.4 与光照的交互

    雾效要能响应光照。在雾材质中:

  • Scene Color 节点:获取场景颜色,作为雾的“漫反射”输入
  • Light Vector:计算主光源方向,让雾在逆光时更亮(丁达尔效应)
  • Depth Fade:根据距离淡出,避免近处雾太厚
  • 性能提示:Volume 粒子对 GPU 压力大,建议最大粒子数控制在 10000 以内。用 Fixed Bounds 限制雾效范围。

    四、系统整合与动态切换

    4.1 天气状态机

    Blueprint 实现天气切换逻辑:

    1. 创建 WeatherManager 蓝图,包含三个 Niagara 组件的引用
    2. 定义 EWeatherState 枚举:Sunny、Rainy、Snowy、Foggy
    3. 用 Timeline 实现渐变过渡:切换时,旧天气粒子生命周期缩短(0.5 秒内消失),新天气粒子从 0 开始 spawn

    4.2 参数化控制

    暴露关键参数到蓝图,方便设计师调整:

  • Rain Intensity:0-1,控制 Spawn Rate 和粒子速度
  • Wind Strength:0-5,控制 Force 模块的 X 轴力度
  • Fog Density:0-1,控制 Volume 粒子的 Opacity 和 Spawn Rate
  • 技术细节:用 Niagara Parameter Collection 存储全局变量,所有发射器共享。修改一个参数,所有天气同步变化。

    4.3 性能优化清单

  • LOD:远距离粒子降低 Spawn Rate 和分辨率
  • Culling:超出视野的粒子不更新(用 Cull by View 模块)
  • GPU 模拟:雨雪用 GPU 模拟(Compute 模式),雾用 CPU 模拟(Volume 模式)
  • Instance Culling:对 Sprite 粒子启用 Instanced Stereo(VR 场景)
  • 五、总结与进阶建议

    这套天气系统已经在我带的几个项目里验证过:一个开放世界 RPG(3000 米视距),一个模拟驾驶游戏(雨雪天气切换),帧率都能稳定在 60fps 以上(RTX 3060 级别显卡)。

    但别停在这里。真正的进阶方向是:

    1. 物理交互:雨滴打湿地面后,材质 roughness 动态变化(用 Runtime Virtual Texture)
    2. 音效联动:根据雨量调整环境音效的衰减曲线和频谱
    3. AI 系统响应:NPC 在雨天会找屋檐避雨,雪天会跺脚取暖

    如果你已经能独立完成本文案例,下一步建议研究 UE5 的 Substrate Material——它能让材质在湿润/干燥状态间无缝过渡,配合天气系统实现“浸湿效果”。

    常见问题 FAQ

    Q1:为什么我的��滴看起来像“线条”而不是“水滴”?
    A:检查 Sprite 纹理是否为长条形(建议 16×128 像素),并且 Blend Mode 设置为 Additive。另外,在 Particle Update 中启用 Face Camera 并关闭 Lock Axis,让雨滴始终面向摄像机。

    Q2:雪堆积效果只在部分模型上生效,是什么原因?
    A:World Position Offset 需要模型具有足够的顶点密度。低模(如圆柱体)可能看不出效果。解决方法:对模型启用 Nanite(UE5.3 支持),或者用 Tessellation 增加细分。

    Q3:雾气粒子在远距离时出现闪烁,怎么解决?
    A:这是 Volume 粒子的常见问题。在材质中增加 Depth Fade 节点,设置 Fade Distance 为 2000 单位。同时,降低粒子透明度(Opacity 不超过 0.2),避免叠加过亮。

    Q4:切换天气时出现卡顿,如何优化?
    A:不要直接销毁/创建 Niagara 系统。用 Set Float Parameter 控制 Spawn Rate,配合 Timeline 在 0.5-1 秒内渐变。另外,预先加载所有天气的纹理资源到 Object Library

    Q5:我的项目是手机端,这套系统能跑吗?
    A:需要大幅降级。建议:雨雪粒子数不超过 2000,雾效用 Post Process 替代 Volume 粒子,关闭碰撞事件。可以用 Niagara HISM(Hierarchical Instance Static Mesh)代替普通粒子,减少 Draw Call。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。