Niagara 高级模块详解:Emitter、Particle、Renderer 核心机制
上周有位学员在项目里遇到一个棘手问题:他需要制作一个“粒子沿螺旋路径运动并逐渐消散”的特效,但无论怎么调整Spawn Rate和Lifetime,粒子要么乱飞,要么消失得太突兀。我打开他的Niagara系统一看——Emitter模块里只挂了简单的Spawn Burst,Particle模块只有常规的Add Velocity,Renderer用的默认Sprite材质。
问题核心在于:他没有理解Niagara三大模块(Emitter、Particle、Renderer)各自承担什么职责,以及如何联动。今天我们就从底层逻辑拆解这三个模块,用两个完整案例带你掌握它们的设计哲学。
一、三大模块的职责边界与数据流
在UE5.4中,Niagara系统通过Emitter Stack组织模块。每个Emitter包含三个层级:
- Emitter模块:控制粒子的“出生”和“生命周期”,比如生成速率、初始位置、系统级行为(如LOD)。
关键原则:Emitter模块生成粒子时,会携带一组初始属性(如Position、Velocity);Particle模块在每个时间步更新这些属性;Renderer模块读取最终属性并输出到屏幕。
> 版本提示:本文基于UE5.4.2,Niagara V3系统。如果你使用UE5.3或更早版本,部分节点位置可能不同,但逻辑一致。
现在,我们通过两个案例来实践。
二、案例1:螺旋消散粒子系统(Emitter + Particle + Renderer联动)
目标
制作粒子沿螺旋路径运动,并在生命周期内逐渐缩小、变透明,最终消散。
步骤1:配置Emitter模块——生成与初始位置
1. 新建Niagara系统,选择Empty模板,添加一个Sprite Renderer。
2. 在Emitter Stack中,点击“+”添加模块:
– Spawn Rate:设为50(每秒生成50个粒子)。
– Lifetime:设为2.0秒。
– Add Velocity:删除默认的“Add Velocity”,改用Add Velocity from Point——这个模块能让粒子从某个点向外扩散,适合螺旋效果的基础。
3. 关键步骤:在Emitter模块下添加Set Particles by Index。这个模块允许我们为每个粒子分配一个索引(0,1,2,…),用于后续螺旋计算。参数:
– Index Mode:`Unique`(每个粒子独立索引)
– Increment:`1.0`
步骤2:配置Particle模块——螺旋运动与衰减
1. 在Particle模块下,添加Custom HLSL节点。双击打开,输入以下代码(这是螺旋的核心逻辑):
// 获取粒子索引
int ParticleIndex = (int)Attributes.ParticleIndex;
// 计算时间偏移,让每个粒子有不同相位
float TimeOffset = ParticleIndex * 0.1;
// 计算当前时间
float CurrentTime = Attributes.Age + TimeOffset;
// 螺旋半径随时间变化(从10到0)
float Radius = 10.0f * (1.0f - Attributes.Age / Attributes.Lifetime);
// 角度随时间增加(速度:2圈/秒)
float Angle = CurrentTime 2.0f 3.14159f * 2.0f;
// 计算位置
float X = Radius * cos(Angle);
float Y = Radius * sin(Angle);
float Z = CurrentTime * 50.0f; // 沿Z轴上升
// 输出位置
Out_Position = float3(X, Y, Z);
2. 添加Scale Color模块,设置:
– Color Mode:`Curve`(曲线)
– 点击曲线编辑器,设置Alpha从1.0线性下降到0.0(在Lifetime的80%处开始快速下降)。
– Scale Size:勾选,设置为从1.0到0.1的曲线。
3. 添加Solve Forces and Velocity——保持默认,确保物理模拟正确。
步骤3:配置Renderer模块——外观优化
1. 在Sprite Renderer中:
– Material:选择`M_DefaultSprite`(或你的自定义粒子材质)。
– Blend Mode:`Additive`(叠加模式,适合发光粒子)。
– Sort Mode:`None`(粒子数量少时,关闭排序提升性能)。
2. 添加SubUV(子纹理动画):如果材质包含多个帧,可以设置SubImage Index为`Particle.Age / Lifetime * 总帧数`。
效果验证
运行系统,你应该看到粒子从原点螺旋上升,并在2秒内逐渐缩小、变透明。如果粒子不螺旋,检查Custom HLSL中是否使用了`Attributes.ParticleIndex`——这是从Emitter模块传递过来的数据。
三、案例2:粒子碰撞与反弹(Particle模块高级应用)
目标
粒子从空中落下,撞击地面后反弹并碎裂成更小的粒子。
步骤1:Emitter模块——生成与初始速度
1. 新建Niagara系统,添加Sprite Renderer。
2. Emitter模块:
– Spawn Burst:一次性生成200个粒子。
– Lifetime:随机范围3.0-5.0秒(让粒子不同时消失)。
– Add Velocity:设置Z方向速度为-500(向下),X和Y随机在-100到100之间。
步骤2:Particle模块——碰撞与子粒子
1. 添加Collision模块(在Particle模块下搜索):
– Collision Type:`World`(与世界碰撞)。
– Friction:`0.5`(摩擦系数,影响滑动)。
– Restitution:`0.3`(弹性系数,0表示完全不弹,1表示完全弹性)。
– Collision Radius:`5.0`(粒子碰撞半径,单位厘米)。
2. 添加Event Handler模块——这是生成子粒子的关键:
– Event Name:`CollisionEvent`
– Spawn Particles on Event:勾选
– Spawn Count:`3`(每次碰撞生成3个碎片)
– Spawn Location:`Collision Location`(在碰撞位置生成)
– Spawn Attributes:保留默认,但需要手动传递“父粒子速度”。
3. 在Emitter模块下添加Handle Event:
– Event Name:`CollisionEvent`(与上面匹配)
– Particle Spawn:勾选,设置Spawn Rate为`0`(我们不希望额外生成,只由事件触发)。
步骤3:Renderer模块——碎片材质
1. 为子粒子(在同一个Emitter内)添加Sprite Renderer,使用M_DefaultSprite。
2. 在Particle模块中,为子粒子添加Scale Size:设置为0.1-0.3随机(比父粒子小)。
3. 添加Lifetime:0.5-1.0秒(碎片快速消失)。
效果验证
粒子落下后撞击地面(需要场景中有地面网格体),会弹起并分裂成3个小碎片。如果粒子直接穿过地面,检查Collision模块的Collision Type是否设为`World`,以及场景中是否启用了碰撞。
四、Renderer模块的进阶:自定义渲染
除了Sprite和Mesh Renderer,UE5.4的Niagara还支持Light Renderer(粒子作为光源)和Ribbon Renderer(带状粒子)。这里重点讲Ribbon Renderer,常用于制作拖尾、光束。
Ribbon Renderer配置要点
1. 在Renderer中添加Ribbon Renderer。
2. Ribbon Width:设为`Particle.Size.X * 2.0`(宽度随大小变化)。
3. Ribbon Texture Mode:`Stretch`(拉伸纹理对齐粒子路径)。
4. Sort Mode:`Age`(按年龄排序,确保拖尾方向正确)。
实战:激光扫射特效
五、总结与进阶建议
核心回顾
1. Emitter管“生”(生成策略、���始属性、事件触发)。
2. Particle管“活”(运动、变化、碰撞、自定义逻辑)。
3. Renderer管“死”(最终绘制、材质、排序、性能优化)。
进阶建议
如果你在项目中遇到“粒子不按预期运动”或“性能卡顿”,先检查三大模块的数据流——大概率是Emitter的初始属性没有正确传递给Particle模块。
常见问题 FAQ
Q1:为什么我的粒子在Custom HLSL中修改了位置,但Renderer还是显示在原位?
A:检查你的HLSL是否写入了`Out_Position`变量。另外,确保在Particle模块中没有其他模块(如`Add Velocity`)覆盖了位置。建议在Custom HLSL后添加`Solve Forces and Velocity`模块来保持一致性。
Q2:Emitter模块的Spawn Rate设置为100,但实际生成的粒子远少于100?
A:检查是否开启了LOD或Culling。在Emitter模块的Performance选项卡中,关闭`Cull Particles`或调整`Max Particles`。另外,如果场景中有多个Emitter,全局粒子上限(Project Settings -> Niagara)也会限制。
Q3:粒子碰撞后直接消失,没有生成子粒子?
A:确认两点:1) Event Handler中的`Spawn Particles on Event`已勾选;2) 在Emitter模块下添加了`Handle Event`并匹配事件名称。如果子粒子没有Renderer,也会看不见。
Q4:Ribbon Renderer的拖尾总是断断续续?
A:Ribbon需要粒子连续运动。确保粒子的`Age`不重置(不要使用`Reset Age`模块),并且粒子的速度方向变化不要太剧烈。可以增加Ribbon Tesselation(在Renderer中)来提高平滑度。
Q5:如何在蓝图中动态控制Niagara粒子的颜色?
A:在Niagara系统中,将颜色参数暴露为User Exposed(在参数面板中右键 -> Expose to User)。然后在蓝图中使用`Set Niagara Variable`节点,选择该参数并传入颜色值。注意:参数类型需匹配(如`LinearColor`)。

评论(0)