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+)
  • Fixed Bounding Box:勾选并设置范围,比如 `X:5000 Y:5000 Z:3000`,让粒子只在摄像机周围活动,避免渲染远处无用粒子。
  • 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 模块中:

  • Renderer Type:选择 Sprite Renderer
  • Material:新建一个材质 `M_RainDrop`,使用 Unlit 模式,Blend Mode 设为 Translucent
  • 材质核心节点:`TextureCoordinate` → `Particle Color` → `Opacity Mask`,配合一个 Slope 纹理(黑白渐变图)让雨丝上端透明、下端实心
  • 进阶技巧:在 Niagara 的 Particle Update 中添加 Scale Color 模块,根据粒子生命周期让雨丝末尾逐渐消失,形成自然拖尾。

    1.4 落地溅射与碰撞

    这是实现“真实感”的关键。在 Particle Update 中添加 Collision 模块:

  • Collision ModeDistance Field(利用场景的距离场信息,比传统射线碰撞更高效)
  • Restitution:0.0(完全非弹性碰撞,雨滴不反弹)
  • Friction:0.8
  • 当粒子碰撞到地面时,我们需要触发一个子发射器生成水花。在 Event 模块中:

  • Event TypeCollision
  • Spawn Sub Emitter:选择已创建的 `Splash_Emitter`(另一个 Niagara 发射器,生成 5-10 个小球体粒子,生命周期 0.3 秒,向上弹跳)
  • Niagara雨滴碰撞设置

    二、雪与雾:差异化实现策略

    2.1 雪系统:飘落与堆积

    新建 `Snow_Emitter`,核心参数调整:

  • Spawn Rate:500(雪粒子比雨少,因为体积大)
  • Particles.Velocity:`(0, 0, -100 + RandomRange(-50,50))`,下落速度慢很多
  • Particles.Lifetime:5.0~8.0,让雪在空中停留更久
  • 关键差异点:雪需要“飘动”效果。在 Particle Update 中添加 Noise 模块:

  • Noise ModeVector 3D
  • Frequency:0.1(低频,让飘动轨迹平滑)
  • Amplitude:`(200, 200, 50)`(水平方向大,垂直方向小)
  • 材质方面,雪粒子使用 Subsurface 材质(半透明散射),配合一个 Noise 纹理让表面有凹凸感。同时,在 Renderer 中开启 Sort ModeSort by Distance,避免多层雪粒子出现穿插闪烁。

    堆积效果:利用 Niagara 的 Data Interface 中的 Grid2D,将落地的雪粒子位置写入一张 2D 纹理,然后在场景材质中采样这张纹理,动态改变地表颜色(变白)。具体步骤:
    1. 在 Snow_Emitter 的 Emitter Update 中添加 Grid2D Write,分辨率 `512×512`
    2. 在场景地面的材质中,添加 Grid2D Sample 节点,将采样值混合到 Base Color

    雪粒子Noise飘动参数

    2.2 雾系统:体积雾与粒子雾结合

    雾的实现有两种主流方式:指数高度雾(Exponential Height Fog,性能好但静态)和 Niagara 粒子雾(动态可交互)。这里推荐混合使用:

    步骤 1:场景基础雾
    World Settings 中添加 Exponential Height Fog 组件,设置:

  • Fog Density:0.02
  • Fog Height Falloff:0.5
  • Start Distance:100(从 100 厘米外开始有雾)
  • 步骤 2:动态粒子雾
    新建 `Fog_Emitter`,粒子使用 Sphere 渲染器(3D 球体),参数:

  • Spawn Rate:200
  • Particles.Lifetime:10.0~15.0
  • Particles.Velocity:`(RandomRange(-10,10), RandomRange(-10,10), RandomRange(-5,5))`,缓慢漂移
  • Particles.Scale:`(200, 200, 50)`,压扁成雾团形状
  • 材质使用 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 功能,根据天气切换实时调整音量和混响。

    关键参数

  • Rain Sound:音量 1.0,低通滤波 200Hz(模拟雨声的闷感)
  • Snow Sound:音量 0.5,加入 Reverb 效果(空旷感)
  • 3.3 性能监控与自适应

    BP_WeatherManagerTick 事件中,获取当前帧率(`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+体积雾,各取所长

    进阶建议

  • 学习 Niagara Data Interfaces 中的 Render Target 2D,可以实现雨滴在窗户上的流淌效果
  • 研究 Chaos Physics 与天气系统的联动,比如雨水影响地面摩擦力、雪堆积影响角色移动速度
  • 关注 Epic Games 的 Lyra 示例项目,里面有现成的天气系统框架可以学习
  • ---

    常见问题 FAQ

    Q1:为什么我的雨滴看起来像“面条”而不是细丝?
    A:检查 Sprite 的 Alignment 设置,确保为 Velocity-Aligned(粒子方向跟随速度)。同时材质中的纹理需要是细长渐变图,而不是正方形。

    Q2:粒子碰撞到地面后不生成水花怎么办?
    A:确认子发射器 Splash_EmitterSpawn Group 设置为 Collision,并且在父发射器的 Event Handler 中正确绑定了子发射器。另外,子发射器的粒子生命周期要足够短(0.2-0.5秒)。

    Q3:雪粒子在远处闪烁严重,怎么解决?
    A:在 Renderer 中开启 Sort ModeSort 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 秒,太短会显得突兀。

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