UE5 动态天气系统:雨、雪、雾的 Niagara 实现方案
从学员的困惑说起
上周有位正在做开放世界项目的学员找到我,他遇到了一个典型问题:用传统粒子系统实现雨天效果时,性能消耗巨大,而且雨滴的形态和运动轨迹生硬得像“像素块掉下来”。他尝试调整粒子数量到 5000 个,帧率直接掉到 30 以下,更别提同时叠加雪和雾的效果了。这其实是很多刚接触 UE5 特效的同学都会踩的坑——把 Niagara 当成旧版 Cascade 来用,忽略了它核心的“数据驱动”和“GPU 模拟”优势。
今天,我就带你一步步拆解 UE5 动态天气系统的实现方案。我们会重点使用 Niagara 5.0(UE5.3+ 版本内置)中的 GPU 模拟、距离场碰撞 和 动态材质参数 三大核心功能,构建一个可实时切换的雨、雪、雾系统。全程零废话,直接上操作。
—
一、核心基础:用 Niagara 构建“雨”系统
1.1 创建基础粒子发射器
打开 Content Browser,右键选择 FX → Niagara Emitter,命名为 `Rain_Emitter`。双击打开,在 Emitter Properties 面板中:
- Simulation Target:选择 GPU Compute Sim(这是性能关键,CPU 模拟 10000 粒子就会卡,GPU 可以轻松跑到 50000+)
1.2 粒子生成与运动逻辑
在 Emitter Update 模块中添加 Spawn Rate,设置 `Spawn Rate = 2000`(每秒 2000 个粒子)。然后在 Particle Spawn 模块中写入:
// 初始化生命周期
Particles.Lifetime = 2.0 (随机范围 1.5~2.5)
// 初始位置:在摄像机上方随机分布
Particles.Position = (CameraLocation.X + RandomRange(-2000,2000), CameraLocation.Y + RandomRange(-2000,2000), CameraLocation.Z + 1000)
// 初始速度:垂直下落,带轻微随机
Particles.Velocity = (0, 0, -800 + RandomRange(-100,100))
关键点:这里使用 CameraLocation 作为参考点,让粒子始终跟随玩家,而不是固定在场景中。实现方法是在 User Exposed 中添加 `CameraLocation` 向量参数,然后在关卡蓝图中每帧更新。
1.3 添加“雨丝”效果
默认粒子是点状,我们需要让它变成细长的雨丝。在 Particle Render 模块中:
进阶技巧:在 Niagara 的 Particle Update 中添加 Scale Color 模块,根据粒子生命周期让雨丝末尾逐渐消失,形成自然拖尾。
1.4 落地溅射与碰撞
这是实现“真实感”的关键。在 Particle Update 中添加 Collision 模块:
当粒子碰撞到地面时,我们需要触发一个子发射器生成水花。在 Event 模块中:
—
二、雪与雾:差异化实现策略
2.1 雪系统:飘落与堆积
新建 `Snow_Emitter`,核心参数调整:
关键差异点:雪需要“飘动”效果。在 Particle Update 中添加 Noise 模块:
材质方面,雪粒子使用 Subsurface 材质(半透明散射),配合一个 Noise 纹理让表面有凹凸感。同时,在 Renderer 中开启 Sort Mode 为 Sort by Distance,避免多层雪粒子出现穿插闪烁。
堆积效果:利用 Niagara 的 Data Interface 中的 Grid2D,将落地的雪粒子位置写入一张 2D 纹理,然后在场景材质中采样这张纹理,动态改变地表颜色(变白)。具体步骤:
1. 在 Snow_Emitter 的 Emitter Update 中添加 Grid2D Write,分辨率 `512×512`
2. 在场景地面的材质中,添加 Grid2D Sample 节点,将采样值混合到 Base Color
2.2 雾系统:体积雾与粒子雾结合
雾的实现有两种主流方式:指数高度雾(Exponential Height Fog,性能好但静态)和 Niagara 粒子雾(动态可交互)。这里推荐混合使用:
步骤 1:场景基础雾
在 World Settings 中添加 Exponential Height Fog 组件,设置:
步骤 2:动态粒子雾
新建 `Fog_Emitter`,粒子使用 Sphere 渲染器(3D 球体),参数:
材质使用 Translucent Lit 模式,Opacity 通过 Particle Alpha 控制,并加入 Panner 节点让雾团内部纹理缓慢流动。
性能优化:粒子雾只保留 50 个左右,因为体积雾已经提供了基础密度,粒子雾只用来增加局部动态感。
—
三、动态切换与天气管理
3.1 创建天气管理器蓝图
新建 Blueprint Class,父类为 Actor,命名为 `BP_WeatherManager`。添加一个 Timeline 组件,用于平滑切换天气。
核心逻辑:在蓝图中暴露三个 Niagara System 引用(Rain、Snow、Fog),通过 Set Variable 节点动态控制每个系统的 Spawn Rate 参数。
// 切换为雨天
Timeline → 0~3秒内:Rain_SpawnRate 从0→2000��Snow_SpawnRate 从500→0
// 切换为雪天
Timeline → 0~5秒内:Snow_SpawnRate 从0→500,Fog_Density 从0.02→0.05
3.2 使用 Audio Mixer 添加环境音
天气系统不仅要视觉,还要听觉。在蓝图中添加 Audio Component,播放预设的雨声、雪风声 WAV 文件。利用 Audio Modulation 功能,根据天气切换实时调整音量和混响。
关键参数:
3.3 性能监控与自适应
在 BP_WeatherManager 的 Tick 事件中,获取当前帧率(`Get World Delta Seconds`),如果低于 30 FPS,自动降低粒子数量:
If FPS < 30:
Rain_SpawnRate *= 0.8
Snow_SpawnRate *= 0.7
Fog_SpawnRate *= 0.9
这样能保证在不同配置的机器上都能流畅运行。
---
总结与进阶建议
通过以上三个步骤,你已经掌握了用 Niagara 构建动态天气系统的核心方法。总结关键点:
1. GPU 模拟:所有天气粒子使用 GPU Compute Sim,这是性能基础
2. 数据驱动:通过 User Exposed 参数控制粒子数量、速度、颜色,实现动态切换
3. 混合渲染:雨用 Sprite、雪用 Sprite+Noise、雾用 Sphere+体积雾,各取所长
进阶建议:
---
常见问题 FAQ
Q1:为什么我的雨滴看起来像“面条”而不是细丝?
A:检查 Sprite 的 Alignment 设置,确保为 Velocity-Aligned(粒子方向跟随速度)。同时材质中的纹理需要是细长渐变图,而不是正方形。
Q2:粒子碰撞到地面后不生成水花怎么办?
A:确认子发射器 Splash_Emitter 的 Spawn Group 设置为 Collision,并且在父发射器的 Event Handler 中正确绑定了子发射器。另外,子发射器的粒子生命周期要足够短(0.2-0.5秒)。
Q3:雪粒子在远处闪烁严重,怎么解决?
A:在 Renderer 中开启 Sort Mode 为 Sort by Distance,并降低粒子透明度(Alpha 0.3-0.5)。如果还是闪烁,尝试减少粒子数量并增大粒子尺寸。
Q4:雾系统的性能开销很大,如何优化?
A:基础雾用 Exponential Height Fog(几乎零开销),粒子雾控制在 30-50 个以内。粒子雾的材质避免使用��杂光照,改用 Unlit 模式。
Q5:我想实现“雨转雪”的渐变过渡,该怎么做?
A:在 BP_WeatherManager 中使用 Timeline 插值两个 Niagara 系统的 Spawn Rate 参数,同时用 Set Material Scalar Parameter 改变材质颜色(从偏蓝到偏白)。过渡时间建议 3-5 秒,太短会显得突兀。

评论(0)