# 水下气泡与焦散光效:UE5 环境特效的高级技巧

上周,一个学员给我发来他做的水下场景截图——气泡像塑料珠子一样僵硬地漂浮,焦散光效则完全是一团模糊的白色光斑。“老师,我用了Niagara的默认发射器,也调了光照参数,但就是没有那种‘水感’。”他沮丧地说。这个问题其实很典型:很多人在UE5里做水下环境,要么只盯着粒子发射器,要么只顾着调后处理,却忽略了气泡的物理行为焦散光效的数学逻辑才是灵魂所在。

今天,我们就用UE5.3(部分功能在5.4中也有更新)来拆解这两个核心技巧。你不需要复杂的蓝图,甚至不需要外部贴图——纯Niagara和材质编辑器就能搞定。

一、气泡:从“漂浮”到“真实涌动”

1.1 基础发射器设置(别再用默认参数了)

打开Niagara系统,新建一个发射器(Emitter)。关键点:不要用“Simple Sprite Burst”模板,而是用“Empty”从头构建。因为默认模板会给你太多冗余参数,反而干扰你对核心逻辑的理解。

操作路径:
Content Browser → 右键 → Niagara System → New Niagara System → Empty

在Emitter Properties中,关键参数如下(UE5.3版本):

  • Spawn Rate:50-80(太多会遮挡视线,太少显得空旷)
  • Lifetime Mode:Random Range(Min 2.0, Max 4.5)
  • Initial Size:Uniform Random(Min 1.5, Max 4.0)
  • Material:新建一个Translucent材质,使用`Simple Translucent`模板(别用PBR,气泡不需要粗糙度)
  • 核心逻辑在Particle Update阶段:
    添加`Add Velocity`模块,但不要直接给固定值。水下气泡的上升速度不是线性的——它会在上升过程中因水压减小而加速。

    实操小练习:
    1. 在Particle Update中添加`Add Velocity`模块
    2. 在`Velocity`输入框里,点击右侧箭头 → `Random Range` → 设置X/Y为0,Z为`50-120`(随机范围)
    3. 添加`Scale Velocity by Curve`模块 → 创建一个Float Curve,让速度在粒子生命周期的前20%缓慢,后80%逐渐加速(曲线形状类似J型)
    4. 播放预览,你会发现气泡不再匀速上升,而是像真实水中那样“挣扎”着上浮

    1.2 气泡的“呼吸感”:使用Noise驱动位置偏移

    这是最容易被忽略的点。真实气泡不是直线上升的,它们会受水流影响产生微小的螺旋或摆动。在Niagara中,我们可以用Noise来模拟这种扰动。

    操作路���:
    Particle Update → 添加`Add Velocity`(这次用Noise驱动)

    具体参数设置:

  • Noise Mode:`Perlin`(Perlin噪声比Simplex更柔和,适合气泡)
  • Frequency:`0.3-0.5`(太低气泡会剧烈抖动,太高则像高频振动)
  • Amplitude:`10-20`(单位是厘米,别太大)
  • Turbulence:`1.0`(开启后噪声会随时间变化,产生流动感)
  • 注意: 这个Noise要加到`Velocity`的X和Y轴上,Z轴保持原有的上升速度。否则气泡会像喝醉了一样乱飘。

    实操小练习:
    1. 在Particle Update中再添加一个`Add Velocity`模块
    2. 将其拖到原有`Add Velocity`模块下方(顺序决定优先级)
    3. 在第二个模块的Velocity输入框中,点击右键 → `Make Float from Float` → 分别将X和Y连接到`Make Noise`节点
    4. 在`Make Noise`节点中,将`Position`连接到`Particles.Position`(让噪声基于粒子位置变化)
    5. 调整Frequency到0.4,Amplitude到15,观察气泡的螺旋上升轨迹

    气泡噪声扰动效果

    1.3 气泡大小随深度变化(高级技巧)

    真实水中,气泡越靠近水面越大(因为水压减小)。在Niagara中,我们可以��`Particles.Position.Z`来驱动Size的变化。

    操作路径:
    Particle Spawn → 添加`Set Size`(这里设初始大小)
    Particle Update → 添加`Scale Size by Curve`(这里做动态缩放)

    关键:创建一个Curve Atlas(曲线图集),让Size随Z轴高度线性增加。
    具体操作:
    1. 在Content Browser中右键 → Curve Atlas → 创建Float Curve
    2. 曲线横轴设为Z轴高度(0-500单位),纵轴设为Size倍数(1.0-2.5)
    3. 在`Scale Size by Curve`模块中,将`Curve`参数指向这个Curve Atlas,`Input`连接到`Particles.Position.Z`

    这样,浅水区的气泡会比深水区大1.5-2倍,真实感瞬间提升。

    气泡大小随深度变化曲线

    二、焦散光效:从“光斑”到“水纹舞动”

    2.1 材质核心:用数学函数生成焦散纹理

    很多教程教你要用外部贴图,但UE5.3的材质编辑器已经强大到可以纯数学生成。核心思路是多层正弦波叠加

    操作路径:
    Content Browser → 右键 → Material → 命名为`M_CausticPattern`
    材质属性:`Surface`为`Translucent`,`Blend Mode`为`Additive`(焦散是光,用叠加模式)

    节点网络:
    1. 创建两个`Sine`节点(搜索`Sine`)
    2. 第一个Sine:`Period`= 500(单位是厘米),`Phase`= `Time * 0.3`(让波纹移动)
    3. 第二个Sine:`Period`= 300,`Phase`= `Time * 0.5`(不同频率产生干涉)
    4. 将两个Sine相乘(用`Multiply`节点),得到基础纹路
    5. 再乘以`Absolute World Position`的X和Y分量(让纹路跟随场景位置变化)
    6. 最后连到`Opacity Mask`(如果是Masked模式)或`Emissive Color`(如果是Additive模式)

    关键参数:

  • `Time`节点要乘以一个系数(0.2-0.5),太快的移动像闪光灯,太慢像死水
  • 在`Multiply`后加一个`Power`节点(指数2-3),可以增强对比度,让光斑更锐利
  • 实操小练习:
    1. 创建一个新的Translucent材质
    2. 添加`Sine`节点,Period=400,Phase=`Time * 0.2`
    3. 添加第二个`Sine`节点,Period=250,Phase=`Time * 0.4`
    4. 用`Multiply`连接两个Sine,再连到`Emissive Color`
    5. 在材质实例中,将`Emissive Color`强度调至3-5,观察效果
    6. 尝试添加第三个Sine(Period=600,Phase=`Time * 0.1`),用`Add`节点混合,产生更复杂的干涉纹路

    焦散材质节点网络

    2.2 将焦散投影到场景:使用Light Function

    生成的材质不能直接贴在物体上(会破坏原有纹理),正确的做法是做成Light Function,让它像投影仪一样打在场景表面。

    操作路径:
    1. 在Content Browser中,右键刚才的材质 → 创建材质实例
    2. 新建一个Spot Light(或Directional Light,取决于场景)
    3. 在Light的细节面板中,找到`Light Function Material` → 指定为刚才的材质实例
    4. 调整`Light Function Scale`(默认1.0,可调至2-3让光斑更大)

    注意: 焦散光效的强度不要超过主光源的30%,否则场景会显得“脏”。建议在Light的`Intensity`中单独控制。

    实操小练习:
    1. 在场景中放置一个Spot Light,角度对准水面区域
    2. 将材质实例拖入`Light Function Material`槽
    3. 调整`Light Function Fade Distance`(建议500-1000单位)
    4. 播放预览,你会看到水面上有流动的光斑纹路
    5. 如果光斑太清晰(像贴图),在材质中增加`Noise`节点(Perlin噪声,Frequency 0.1)与原有纹路混合,产生“水纹模糊”效果

    2.3 焦散与场景交互:用Distance Field优化(UE5.3+)

    如果你的场景中有复杂几何体(比如礁石、珊瑚),焦散光效默认会穿透它们。在UE5.3中,我们可以用Mesh Distance Field来让焦散只出现在水面上。

    操作路径:
    1. 在材质中,添加`Distance to Nearest Surface`节点(需要开���项目设置中的`Generate Mesh Distance Fields`)
    2. 将`World Position`连入该节点
    3. 输出值通过`SmoothStep`(Min=0, Max=50)来生成遮罩
    4. 用这个遮罩乘以原有的焦散纹路

    效果: 焦散只出现在距离水面0-50厘米的范围内,超出部分(比如空气或深水区)自动消失。

    实操小练习:
    1. 在项目设置中搜索`Mesh Distance Fields` → 开启`Generate Mesh Distance Fields`
    2. 在材质中添加`Distance to Nearest Surface`节点
    3. 添加`SmoothStep`节点,Min=0, Max=50
    4. 用`Multiply`将SmoothStep输出与原有焦散纹路相乘
    5. 结果连到`Emissive Color`,观察焦散如何“贴”在水面几何体上

    三、整合与优化:把气泡和焦散变成一套系统

    3.1 使用Niagara事件驱动焦散(进阶技巧)

    在UE5.4中,Niagara新增了Event Handler功能,可以让气泡破裂时触发焦散光效的闪烁。但这里我们用一个更稳定的方法:用场景位置驱动焦散强度。

    操作路径:
    1. 在气泡Niagara系统中,添加`Generate Event`模块(在Particle Update中)
    2. 事件类型设为`Collision`(气泡碰到水面时触发)
    3. 在材质中,添加`Custom`节点,读取Niagara事件数据
    4. 用事件中的`Position`数据,在焦散材质中创建一个“光晕”效果(类似气泡破裂时的涟漪)

    注意: 这个方法对性能有一定消耗,建议只在特写镜头或关键场景中使用。

    3.2 性能优化:LOD与剔除

    水下特效很容易消耗大量性能,尤其是气泡数量超过200时。建议:

  • 气泡LOD: 在Niagara的`Emitter Properties`中,设置`LOD Distance`(近景用高密度,远景用低密度)
  • 焦散分辨率: 在Light Function材质中,使用`Scene Texture`节点(`SceneColor`)来降低分辨率(用`TextureCoordinate`的`Scale`参数控制)
  • 剔除规则: 在气泡的`Particle Spawn`中,添加`Cull by Distance`模块,让远离摄像机的气泡不生成
  • 实操小练习:
    1. 在气泡Niagara的Emitter属性中,找到`LOD`设置
    2. 添加三个LOD级别:LOD0(距离0-2000单位,SpawnRate=80),LOD1(2000-5000单位,SpawnRate=30),LOD2(5000+,SpawnRate=10)
    3. 在焦散材质中,添加`SceneTexture:SceneColor`节点,用`TextureCoordinate`的`Scale`设为0.5(降低一半分辨率)
    4. 观察性能提升(可用`stat gpu`命令查看)

    总结与进阶建议

    今天讲的两个技巧——气泡的噪声驱动和焦散的数学生成——看似简单,但背后是物理模拟程序化纹理的核心思想。很多学员问我:“老师,有没有一键生成水下环境的插件?”我的回答永远是:理解原理比任何插件都重要。插件可以给你结果,但只有原理能让你在遇到问题时知道改哪里。

    下一步学习建议:
    1. 扩展阅读: 学习UE5官方文档中关于`Niagara Noise`和`Material Functions`的章节
    2. 实战项目: 尝试做一个“水下洞穴”场景,结合今天的技巧,加入体积雾(Exponential Height Fog)和粒子光(Particle Light)
    3. 社区资源: 在Unreal Engine的Discord中搜索`#niagara`和`#materials`频道,看看别人怎么用`Custom HLSL`节点实现更复杂的焦散算法
    4. 进阶挑战: 用`Blueprint`控制Niagara系统,让气泡根据玩家位置动态生成(比如潜水时产生气泡)

    常见问题FAQ

    Q1:我按照教程做了气泡,但上升过程中会突然消失,怎么回事?
    A:检查`Lifetime`设置。如果`Lifetime`是固定值,气泡会在同一时间消失。建议用`Random Range`(2-4秒),并确保`Scale Velocity by Curve`的曲线末端没有归零。另外,检查`Particle Update`中是否有`Kill Particles`模块被误触。

    Q2:焦散光效在场景中看起来像“贴图”一样生硬,怎么解决?
    A:生硬的原因是正弦波太规则。解决方法:1)增加`Noise`节点(Perlin噪声,Frequency 0.05-0.1)与原有纹路混合;2)在材质中加一个`Blur`节点(用`GaussianBlur`或`BoxBlur`,强度0.5-1.0);3)调整`Power`节点的指数到2.5-3.0,让光斑边缘更柔和。

    Q3:气泡和焦散同时开启后,帧率从60掉到30,怎么优化?
    A:这是典型性能问题。首先,气泡数量控制在100以内(用LOD控制);其次,焦散材质中的`Time`节点不要直接连到大量节点(创建`Material Parameter Collection`来统一控制);最后,在项目设置中开启`Support Global Shaders`,让焦散计算在GPU上并行。

    Q4:在UE5.4中,焦散材质用`Light Function`后不显示,怎么办?
    A:UE5.4对Light Function有一些改动。检查:1)材质`Blend Mode`必须为`Additive`;2)光源的`Light Function Scale`不能为0;3)在材质中,`Emissive Color`的输入值必须大于0(可以用`Clamp`节点确保)。如果还是不显示,尝试重启编辑器或重新编译材质。

    Q5:我想让气泡破裂时产生小气泡(子粒子),该怎么做?
    A:在Niagara的`Particle Update`中,添加`Generate Event`模块(事件类型选`Death`),然后在另一个发射器中用`Event Handler`接收这个事件,生成新的粒子。注意:子粒子的`Lifetime`���设为父粒子的10%-20%,大小设为父粒子的30%-50%,否则会显得很假。

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