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

上周在火星人教育的 UE5 特效进阶班上,一位学员小李拿着他刚做好的开放世界场景问我:“老师,为什么我用默认粒子系统做的雨,一下雨帧率就掉到 20 帧?而且雨丝看着像塑料条,完全没有真实感。”这个问题其实非常典型——很多开发者用传统 Cascade 做天气特效时,要么性能崩盘,要么视觉效果假到离谱。今天我们就用 UE5 的 Niagara 系统,从底层逻辑出发,手把手构建一套可商用的动态天气系统,涵盖雨、雪、雾三种核心天气。

一、为什么选择 Niagara 做天气系统?

在 UE5.3 及以上版本(本文基于 UE5.4.2 测试),Niagara 已经彻底取代了 Cascade。但很多人只是把 Niagara 当“更强的粒子系统”用,忽略了它的数据驱动架构GPU 计算优势

传统 Cascade 做雨:每个粒子独立模拟位置,CPU 计算碰撞,10000 个粒子就能让低端显卡喘气。而 Niagara 的 GPU 模拟模式(`GPUComputeSim`)允许我们同时处理 50 万+粒子,且通过 Emitter State 模块控制生命周期,配合 Spawn Rate 动态调整,性能开销反而更低。

核心工具准备:

  • UE5.4.2(建议 5.3+,因为 Niagara Fluids 功能更稳定)
  • Niagara 系统:`Content/Weather/NS_RainSystem`
  • 材质函数库:`Content/Weather/MF_WeatherHelpers`
  • 二、实操案例一:高性能真实雨滴系统

    2.1 基础粒子设置

    打开 Niagara 编辑器,创建 `NS_RainSystem`,选择 GPU Compute Sim 模板。关键参数如下:

    Emitter 属性:

  • `SpawnRate`:80000(80K 雨滴,可在蓝图动态调整)
  • `LifeTime`:2.5 秒(让雨滴有足够下落距离)
  • `Initial Velocity`:Z 轴 -800 cm/s(模拟重力加速)
  • `Particle Size`:X=0.3cm,Y=0.3cm,Z=1.5cm(细长雨丝形态)
  • 关键模块配置:
    1. 在 `Particle Spawn` 阶段添加 `Set Random Seed`(避免重复模式)
    2. 使用 `Add Velocity` 模块,给 X/Y 轴添加 0~50 cm/s 的随机偏移(模拟风力扰动)
    3. 在 `Particle Update` 阶段,用 `Scale Color` 模块让雨滴透明度随生命值衰减(从 0.8 降到 0.2)

    2.2 碰撞与地面效果

    雨滴必须与场景碰撞才能真实。但 80K 粒子全部做碰撞检测会炸性能。这里用 Distance Culling 策略:

    在 `Particle Update` 中添加 `Collision` 模块:

  • `Collision Mode`:`Surface Only`
  • `Friction`:0.1
  • `Restitution`:0.05(几乎无弹跳)
  • 然后添加 `Spawn Burst Instantaneous` 模块,在碰撞位置生成��级粒子:

  • 次级粒子数量:1(每个碰撞点生成一个水花粒子)
  • 生命周期:0.3 秒
  • 大小:0.5~1.2cm 随机
  • 性能优化技巧: 在 `Emitter State` 中开启 `Use Max Particles` 设为 100000,并勾选 `Cull When Not Visible`。这样当雨滴离开相机视野时,Niagara 会自动暂停计算,节省 40% 以上性能。

    2.3 材质与视觉增强

    雨滴材质 `M_RainDrop` 需要半透明和折射效果:

    // 自定义节点实现雨滴变形
    float2 UV = GetDefaultTextureCoordinates();
    float Distortion = sin(UV.x  50 + Time  10) * 0.02;
    UV += Distortion;
    return Texture2DSample(Tex, TexSampler, UV);
    

    雨滴材质节点图

    在材质中开启 `Translucent` 混合模式,`Lighting Mode` 选择 `Surface Translucency Volume`,配合 `Subsurface Color` 让雨滴有半透明感。

    三、实操案例二:动态雪系统与雾效融合

    3.1 雪花粒子的物理模拟

    雪和雨的核心区别在于:雪有飘落轨迹、旋转和堆积效果。创建 `NS_SnowSystem`,使用 CPU Sim(因为需要每帧计算旋转和风力影响)。

    粒子属性:

  • `SpawnRate`:15000(雪量较少,但每个粒子更大)
  • `LifeTime`:8~12 秒(随机范围,让雪花散布更自然)
  • `Initial Size`:0.5~2.0cm(雪花大小随机)
  • `Initial Rotation`:0~360° 随机
  • 风力系统集成:
    在场景中放置 `BP_WeatherManager`,暴露一个 `WindStrength` 变量(0~100)。在 Niagara 的 `Particle Update` 中,通过 `User Exposed` 参数绑定该变量:

    // 风力影响公式
    Velocity.X += WindStrength  0.5  sin(Time * 0.3);
    Velocity.Y += WindStrength  0.3  cos(Time * 0.5);
    Velocity.Z = -50 - WindStrength * 0.2; // 下落速度受风力影响
    

    3.2 地面积雪的实时生成

    用 Niagara 模拟雪堆积不现实(粒子数量爆炸)。这里用 Runtime Virtual Texture(RVT) 方案:

    1. 在场景中放置 `RuntimeVirtualTextureVolume`,设置分辨率 2048×2048
    2. 在雪材质 `M_SnowGround` 中,采样 RVT 的 Alpha 通道
    3. 当雪花粒子碰撞地面时,通过 `Spawn Burst` 生成一个 `Decal` 组件,将雪纹理写入 RVT

    蓝图控制逻辑:

    // 在 BP_WeatherManager 的 Tick 中
    if (SnowIntensity > 0.5f)
    {
        // 每帧更新 RVT 的雪覆盖范围
        RVTVolume->SetWorldLocation(PlayerCamera->GetComponentLocation());
        // 动态调整积雪厚度
        SnowMaterial->SetScalarParameterValue("SnowDepth", SnowIntensity * 5.0f);
    }
    

    积雪 RVT 效果

    3.3 雾效的 Niagara 实现

    传统雾效用 `ExponentialHeightFog` 即可,但动态雾(比如雾随海拔变化)需要 Niagara。创建 `NS_FogSystem`,使用 `Sprite Renderer` 模式。

    关键技巧:

  • 粒子类型:`Ribbon`(带状粒子,模拟雾的流动感)
  • 透明度:0.05~0.15(极低透明度,叠加 500+ 粒子形成体积感)
  • 大小:500~2000cm(大尺度粒子覆盖场景)
  • 使用 `Noise` 模块让粒子位置随时间噪波偏移
  • 性能注意: 雾粒子不要超过 2000 个,否则 GPU 带宽会饱和。配合 `Cull Proxy Volume` 只在玩家周围 50 米内生成。

    四、蓝图集成与动态天气切换

    4.1 天气管理器蓝图

    创建 `BP_WeatherManager`,包含三个 Niagara 系统引用:

    UPROPERTY(EditAnywhere)
    UNiagaraComponent* RainSystem;

    UPROPERTY(EditAnywhere) UNiagaraComponent* SnowSystem;

    UPROPERTY(EditAnywhere) UNiagaraComponent* FogSystem;

    在蓝图事件图表中,暴露 `SetWeatherType(WeatherType NewWeather)` 函数:

    Switch on NewWeather:
      - Rain: 激活 RainSystem,停用 SnowSystem,FogSystem 透明度设为 0.3
      - Snow: 激活 SnowSystem,停用 RainSystem,FogSystem 透明度设为 0.6
      - Fog: 停用 Rain 和 Snow,FogSystem 透明度设为 0.9
      - Clear: 全部停用,透明度过渡 2 秒
    

    4.2 过渡动画实现

    直接��� Niagara 的 `SetFloatParameter` 做淡入淡出太生硬。建议用 `Timeline` 节点:

    // 在蓝图 Tick 中
    float TargetAlpha = (CurrentWeather == Rain) ? 1.0f : 0.0f;
    float CurrentAlpha = FMath::FInterpTo(CurrentAlpha, TargetAlpha, DeltaTime, 3.0f);
    RainSystem->SetFloatParameter("Opacity", CurrentAlpha);
    

    这样切换天气时有 3 秒的平滑过渡,视觉上非常自然。

    天气切换效果对比

    五、性能调优与常见坑

    5.1 粒子数量与 LOD

    不同平台需要不同粒子密度:

  • PC 高画质:雨 80K,雪 20K,雾 1500
  • 主机/中画质:雨 40K,雪 10K,雾 800
  • 手机/低画质:雨 15K,雪 4K,雾 300
  • 在 Niagara 的 `Emitter State` 中,通过 `LOD` 设置不同级别:

    LOD 0: SpawnRate 80000
    LOD 1: SpawnRate 40000
    LOD 2: SpawnRate 15000
    

    然后在项目设置中绑定 `Scalability` 的粒子 LOD 等级。

    5.2 常见问题排查

    问题1:雨滴闪烁
    原因:粒子大小与屏幕分辨率不匹配。解决方案:将 `Particle Size` 的 Z 轴改为 `ScreenSize` 模式,让雨滴在屏幕上保持固定像素宽度。

    问题2:雪粒子穿透地形
    原因:碰撞检测精度不够。在 `Collision` 模块中,将 `Collision Trace Channel` 改为 `Visibility`,并勾选 `Complex Collision`。

    问题3:雾效导致帧率骤降
    原因:雾粒子渲染开销大。改用 `Mesh Renderer` 模式,用低多边形球体代替 Sprite,配合 `Instanced Static Mesh` 减少 Draw Call。

    常见问题 FAQ

    Q1:Niagara 系统在运行时动态调整粒子数量,会不会导致卡顿?
    A:不会。Niagara 的 `SpawnRate` 参数支持运行时修改,引擎会自动调整粒子池大小。但注意不要频繁在每帧修改,建议用 Timeline 做渐变。

    Q2:雨滴碰撞生成的水花效果,如何避免粒子重叠?
    A:在次级粒子的 `Spawn Burst` 中,添加 `Random Position Offset` 模块,偏移范围设为 5~15cm。同时限制每个主粒子最多生成 1 个次级粒子。

    Q3:雪景中如何让角色脚印显示在积雪上?
    A:使用 `Decal Actor` 配合 `Material Parameter Collection`。当角色移动时,在脚底位置生成 Decal,材质中采样 `SnowDepth` 参数,脚印区域将雪纹理替换为泥土纹理。

    Q4:动态天气系统支持多人联机吗?
    A:支持。将 `BP_WeatherManager` 设为 `Replicated`,在 `Multicast` 事件中同步天气类型和强度参数。Niagara 组件本身不复制,但参数变化会通过 RPC 同步。

    Q5:为什么我的雾效在室内场景显得很假?
    A:因为雾粒子没有考虑遮挡。在 Niagara 中开启 `Use Depth Buffer`,让雾粒子的透明度根据与场景物体的距离衰减。或者使用 `Volumetric Fog` 配合 Lightmass 烘焙。

    学习进阶建议

    1. 掌握 Niagara 的三种模拟模式:GPU 用于大批量粒子(雨),CPU 用于复杂逻辑(雪),Fluid 用于体积效果(雾)。不要混用模式,否则性能会打折扣。

    2. 深入理解材质中的 World Position Offset:天气特效的视觉质感 70% 靠材质。建议在材质中多用 `Sine` 和 `Noise` 节点做动态变形,避免粒子看起来像平面贴图。

    3. 结合 AIGC 生成天气纹理:尝试用 Stable Diffusion 生成雨滴法线贴图、雪花噪声图,再导入 UE5 作为 Niagara 的 `Texture` 输入。能大幅提升视觉独特性。

    4. 关注 UE5.5 的 Niagara Fluids 更新:新版本将支持 GPU 流体模拟,可以直接生成动态水雾和雪花飘落轨迹,省去手动调噪波的痛苦。

    最后,天气系统的核心不是“看起来很炫”,而是“让玩家感觉真实”。多观察现实中的雨雪形态——雨丝是倾斜的、雪花是旋转的、雾是流动的。把这些物理细节量化成参数,你的天气系统就成功了一半。

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