Niagara 流体模拟实战:水、火、烟的真实感制作技巧

上周有位学员在直播课上问我:“老师,我用 Niagara 做了个火焰,看起来像一堆飘着的橘子皮,完全没有火的炽热感和体积感。折腾了两天,参数调了几十遍,还是不行。” 这个问题非常典型——很多特效师在接触 Niagara 流体模拟时,容易陷入“参数迷宫”,却忽略了流体模拟的核心逻辑:行为模式 + 物理近似 + 视觉欺骗

今天这篇文章,我们直接聚焦三个最常见的流体类型——水、火、烟,用 UE5.3(实测版本)的 Niagara 系统,拆解它们的真实感制作技巧。每个案例都会给出具体的操作路径、关键参数和调试思路,让你从“调参侠”变成“逻辑控”。

一、水:用“粒子+网格”模拟流体表面张力

水的难点在于表面张力飞溅细节。纯粒子模拟的水会像爆米花一样松散,而纯网格模拟(如 FLIP)又太吃性能。Niagara 的 Fluid Surface 模块 提供了一种折中方案:用粒子承载物理,用网格生成表面。

步骤1:初始化粒子系统

1. 在 Content Browser 右键 → FXNiagara System,选择 Empty 模板。
2. 打开 Niagara 编辑器,在 Emitter Properties 中设置:
– `Simulation Target`:`GPU Compute Sim`(必须,否则无法启用 Fluid Surface)
– `Local Space`:`true`(方便调试位置)
3. 添加 Spawn Burst Instantaneous 模块,设置 `Spawn Count` 为 `5000`(后续可调)。
4. 在 Initialize Particle 模块中,设置初始位置为 `(0,0,0)` 周围半径 `30` 内的随机点,并赋予随机初速度 `(0, -50, 200)` 左右,让粒子下落并碰撞。

步骤2:启用流体表面渲染

这是水模拟的核心。在 Renderer 选项卡中:
1. 删除默认的 Sprite Renderer,添加 Fluid Surface Renderer(UE5.3 内置)。
2. 关键参数:
– `Grid Size`:`64`(粒子数少于 3000 时用 32,否则用 64,平衡性能与细节)
– `Smoothing Radius`:`2.0`(控制表面光滑度,数值越大越像果冻,越小越像水滴)
– `Surface Tension`:`0.8`(核心参数!0.0-1.0,模拟水的张力,建议从 0.6 开始微调)
– `Viscosity`:`0.3`(水的粘度较低,油类可调至 0.8 以上)

步骤3:添加碰撞与重力

Particle Update 组中:
1. 添加 Gravity Force:`(0, 0, -980)`(UE 单位,厘米/秒²)。
2. 添加 Collision 模块,选�� World Collision,设置 `Collision Radius` 为 `1.0`。
3. 为了模拟水花飞溅,在 Emitter Update 中添加 Spawn Per Frame,设置 `Spawn Rate` 为 `100`,并让新粒子的初速度随机偏移 `(±30, ±30, 50)`。

技巧:调试表面张力

  • 如果水看起来像油:降低 Surface Tension 到 0.3,并提高 Viscosity 到 0.5。
  • 如果水像果冻:提高 Surface Tension 到 0.9,并降低 Smoothing Radius 到 1.2。
  • 如果粒子穿透地面:检查 Collision 中的 Collision Channel 是否设为 `WorldStatic`,并在场景中放置一个 Box 并启用 Simulate Physics 作为碰撞体。
  • 水模拟表面张力效果

    二、火:用“粒子层级”构建火焰体积

    火的真实感来自内焰、外焰、烟尘三个层次的叠加。很多新手只用一个 Sprite 粒子,结果就是“橘子皮”。正确的做法是:用三个 Emitter 分层模拟

    步骤1:内焰(高温核心)

    新建一个 Emitter,命名为 `Core`:
    1. Spawn Burst Instantaneous:`Spawn Count = 200`,初始位置在 `(0,0,0)` 向上偏移 `(0,0,5)`。
    2. Initialize Particle:设置 `Lifetime` 为 `0.5-1.0`(随机),`Size` �� `5-10`。
    3. 在 Particle Update 中:
    Scale Size by Curve:曲线设为“先升后降”,峰值在 0.3 秒处。
    Add Velocity:`(0, 0, 50 + Random(-20, 20))`。
    4. Renderer:使用 Sprite Renderer,材质选择 `M_FireCore`(引擎自带内容,路径 `/Engine/FX/Materials/Fire/M_FireCore`)。
    5. 材质参数:将 `Emissive Color` 设为 `(10, 3, 0)` 橙色,`Opacity` 曲线设为“快速上升,缓慢下降”。

    步骤2:外焰(燃烧层)

    新建 Emitter `OuterFlame`:
    1. Spawn Per Frame:`Rate = 50`,初始位置在 Core 粒子位置周围 `3` 单位内。
    2. Initialize Particle:`Lifetime = 0.8-1.5`,`Size = 15-25`。
    3. 物理更新:
    Drag:`0.2`(让火焰飘散更自然)。
    Vortex Force:强度 `5`,范围 `10`(制造火焰旋转感)。
    4. Renderer:使用 Ribbon Renderer,材质 `M_FireRibbon`(路径同上)。关键设置:
    – `Ribbon Width`:`10-20`(随生命期变化)。
    – `Sort Mode`:`Sort by Age`(避免闪烁)。

    步骤3:烟尘(背景层)

    新建 Emitter `Smoke`:
    1. Spawn Per Frame:`Rate = 20`,粒子延迟 0.5 秒生成(在 Initialize Particle 中设置 `Spawn Time` 偏移)。
    2. Size:`30-60`,Lifetime:`2-4`。
    3. 物理:Gravity 设为 `(0,0,30)`(向上飘),Noise 扰动强度 `10`。
    4. Renderer:Sprite Renderer,材质 `M_Smoke`(使用引擎自带或自己制作的半透明烟雾贴图)。将 `Opacity` 曲线设为“从 0 到 0.3 再到 0”。

    技巧:调试火焰颜色

  • 在材质中,用 Particle Color 节点控制颜色随生命期变化:内焰从 `(10,5,0)` 过渡到 `(5,1,0)`,外焰从 `(5,2,0)` 到 `(1,0,0)`。
  • 如果火焰偏紫:降低蓝通道值,火焰主要是红橙黄。
  • 火焰分层效果

    三、烟:用“噪声+扭曲”模拟流体扩散

    烟和水的区别在于:烟没有表面张力,但有强烈的扩散和扭曲。Niagara 的 Noise FieldVector Field 是制造烟雾体积感的关键。

    步骤1:基础粒子系统

    1. 新建 Niagara 系统,Emitter 类型选 GPU
    2. Spawn Burst Instantaneous:`Spawn Count = 1000`,初始位置在 `(0,0,0)` 球体内。
    3. Initialize Particle:`Lifetime = 3-6`,`Size = 10-20`,初速度 `(0,0,50)`。

    步骤2:添加噪声场

    Particle Update 中添加 Noise Force 模块:

  • `Noise Strength`:`(20, 20, 10)`(水平扩散强,垂直弱)。
  • `Noise Frequency`:`0.5`(低频产生大块烟雾,高频产生细节)。
  • `Noise Offset`:绑定 `Engine.Owner.Time`,让噪声随时间变化。
  • `Noise Type`:`Perlin`(最自然)。
  • 步骤3:使用向量场扭曲

    1. 在 Content Browser 中导入一个 .vfield 文件(或使用引擎自带的 `VFTurbulence`)。
    2. 在 Niagara 中添加 Vector Field Force 模块:
    – `Vector Field Asset`:选择导入的向量场。
    – `Field Intensity`:`0.3`(不要太大,否则烟雾会撕裂)。
    – `Field Scale`:`(1,1,1)`。
    3. 为了增加细节,再添加一个 Curl Noise Force 模块,强度 `0.1`,让烟雾边缘产生卷曲。

    步骤4:渲染优化

    Renderer 使用 Sprite Renderer,材质要点:

  • 贴图:使用 PerlinNoise 纹理或真实烟雾照片(黑白)。
  • 材质混合模式:`Translucent`。
  • Opacity 曲线:粒子生命期前 10% 快速升到 0.5,后 20% 缓慢降到 0(模拟消散)。
  • Scale Size:粒子生命期线性增长 3 倍。
  • 技巧:调试烟雾扩散

  • 如果烟雾聚成一团:提高 Noise Frequency 到 1.0,并增加 Spawn Count 到 3000。
  • 如果烟雾消失太快:延长 Lifetime 到 8-10,并将 Opacity 曲线的下降段改为更缓的曲线。
  • 如果想模拟爆炸烟:初始速度设为放射状,并在 0.5 秒后添加 Drag 快速减速。
  • 烟雾扩散与扭曲

    四、总结与进阶建议

    三个案例的核心逻辑:

  • :依赖 Fluid Surface 模块,重点调 Surface Tension 和 Smoothing Radius。
  • :分层 Emitter,内焰用 Sprite,外焰用 Ribbon,烟尘用半透明。
  • :Noise Force + Vector Field + Curl Noise 三重扰动。
  • 进阶建议:
    1. 学习 Houdini 的向量场生成:Niagara 的向量场文件(.vfield)可以用 Houdini 导出,制作自定义的旋风、爆炸等复杂流场。
    2. 掌握 GPU 调试技巧:在 Niagara 的 Debug 模式下,开启 Particle CountSimulation Time 监控,避免性能瓶颈。
    3. 参考真实物理参数:比如水的粘度 0.001 Pa·s(对应 Niagara 的 Viscosity 0.1-0.3),火的上升速度约 2-5 m/s(对应 UE 单位 200-500 cm/s)。
    4. 使用材质函数:将火焰颜色、烟雾透明度等逻辑封装成材质函数,方便复用。

    常见问题 FAQ

    Q1:我的 Fluid Surface 渲染器是灰色不可选状态,怎么办?
    A:检查 Emitter Properties 中的 `Simulation Target` 是否设为 `GPU Compute Sim`。Fluid Surface 只支持 GPU 模拟。另外,UE 版本需 5.3 及以上,早期版本需要启用插件 `NiagaraFluidSurface`。

    Q2:火焰的 Ribbon Renderer 出现断裂或闪烁,怎么解决?
    A:在 Ribbon Renderer 中,将 `Ribbon Width` 的 `U0` 和 `U1` 曲线设为线性,并确保粒子的 `Lifetime` 足够长(>0.5秒)。如果闪烁,检查材质中是否使用了 `SceneColor` 节点(可能导致半透明排序问题),改用 `CustomDepth` 或调整 `Sort Priority`。

    Q3:烟雾粒子在场景中穿模,看起来像���物体内部?
    A:Niagara 的碰撞检测默认只对 WorldStatic 有效。如果需要与动态物体碰撞,在 Collision 模块中选择 Object Types 为 `WorldDynamic`,并在场景中为物体启用 Simulate PhysicsCollision Enabled。注意,GPU 模拟的碰撞精度有限,建议用简单碰撞体(Box/Sphere)替代复杂网格。

    Q4:我的水粒子看起来像塑料球,没有液体感?
    A:三个关键点:① 检查 Fluid Surface Renderer 的 `Smoothing Radius` 是否过低(建议 1.5-2.5);② 粒子数量不够(至少 3000 个);③ 材质中需要添加 Fresnel 效果(使用 `PixelNormalWS` 与 `CameraVector` 点积)和 Refraction(使用 `SceneColor` 偏移)。引擎自带的 `M_Water` 材质可以作为起点。

    Q5:Niagara 流体模拟很卡,如何优化?
    A:① 减少粒子数量,水用 3000-5000,火用 500-1000(三层总计),烟用 2000-3000;② 降低 Fluid Surface 的 `Grid Size` 到 32;③ 关闭不必要的模块(如 Vortex Force 在粒子数少时效果不明显);④ 使用 LOD:在 Emitter Properties 中设置 `LOD Distance`,远距离时降低 Spawn Rate 或切换到低精度材质。

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