【转载】UE4 Niagara 激光多次反射效果

287 阅读4分钟

原文链接:UE4 Niagara Multi Lazer Reflection VFX

正文

大家好这里是 WildWolf,菜鸟 TA 一枚,作为公司的技术支持,完成日常任务之后喜欢研究各种类型的效果和实现方法,这次给大家带来的是很早之前自己做着玩的一个效果——激光连续反射效果——Niagara+蓝图制作。

废话不多说,先拨片~~~

juejuejue.gif

实现功能为主,效果比较搓~~~ 各位大佬轻喷 ~~~

这个功能其实难度并不高,主要是蓝图的循环逻辑以及反射角的计算,Niagara 粒子只是基本的操作~~~

首先进入 Niagara

真的就是常规设置

User Exposed 创建两个 Vector3,作为 Beam 的起点和终点,然后再新建一个 Float,给 Spawn Pro, 这个参数官方描述的比较抽象,简而言之 如果这个参数为 0 那么无论是 SpawnRate 或者是 SpawnCount 输入任何值都不会发射粒子,防止当前粒子系统已经摧毁但是粒子发射器还没有停止工作的 BUG~~~ (个人的理解不代表官方 =。= )

接着进入 System State,修改整个 Niagara System 循环周期为 0.1 秒,让 Lifetime 读取系统的 CurrentLoopDuration

然后新建一个简单的材质,作为 Beam 的渲染,也灰常简单~~

Color 部分给了一个简单的曲线

这里需要注意的就是,Curve 默认的 CurveIndex 一般是 NormalizedAge,也就是 粒子的生命周期归一化的值 ,但是面对 Beam 粒子,就需要改成 RibbonLinkOrder,不然曲线是无效的。

粒子的基础设置完成,当然还可以添加 JitterPosition 扰乱效果,各位根据喜好来就行~~

进入蓝图操作,使用 第一人称 模板就行

image.png

简单来说就是使用一个循环来释放 Niagara 粒子,释放同时 Attach 到自己进行位置绑定,然后通过 Tick 来更新每一个 Niagara 的信息。

这里用 Insert 插入数组信息是为了需要用每一个粒子的 Index 来做逻辑判断~~~

进入重点,Niagara 信息更新

image.png

image.png

首先使用第一人称的枪口绑定的 SphereBeamStartLocation,也就是第一束激光的起点

激光方向取当前摄像机的 Forward Vector

新建一个 race Counts 用来决定激光会反射多少次,用来给 For Loop With BreakLastIndex,循环的 Index 则用来标记当前的激光以便后面的逻辑判断

发射出一枚激光之后设置当前激光为 CurrentBeam,同时设置 Beam 的起点信息 Bear Start

接着进行射线检测

image.png

默认设置 5000 个单位的检测距离然后把返回值存为一个变量 Hit?

紧接判断当前射线是否撞击到了阻挡物,若有阻挡(Hit? 为真),则把当前撞击点的位置存为下一根激光的起始点 BeamStart ,同时将其设置为当前激光的终点 BeamEnd,接着根据反射计算下一个激光的反射方向 Beam Start Direction (同时也作为 Hit Normal);若没有阻挡(Hit? 为假),则直接将 Trace End 设为 BeamEnd

其实这一步逻辑很容易理解,当前射线的终点为下一根反弹射线的起点,然后依次类推,直到反弹次数上限或者没有撞到阻挡物为止~~~

那么真正的难点在于如何计算出当前射线撞击到阻挡物之后的反射方向~~~

计算方法不止一种,这里使用向量计算来实现,需要一点数学平面几何的基础~~

这里我们引入一张图,BA 为入射方向,AC 为与撞击表面法线方向重合长度为 1 的向量,N 为表面法线方向,我们需要根据这两个向量求出 AD 的方向~~~

首先假设 BAAD 都为单位向量,向量长度都为 1,构建出一个平行四边形 ABCD,则

AD = AC + CD

求出向量 BA 在法线 AC 上的投影 AE

|AE| = dot(BA,-AC)

|AC| = 2|AE|

AC = N*(2|AE|)

再把 BA 平移给 CD,即

AD = N*(2(dot(BA,-AC))) + BA

代码转化为蓝图则为

image.png

这样反射向量就算出来了~~~,那么就满足了下一条激光射线的位置信息,通过 loop 循环,就实现了激光多次反射~~~

接着完成最后一步,当前射线更新位置遇到前方无遮挡物则需要根据 Index 的编号从高到低销毁对应射线

到这一步整体逻辑完成~~~

接着写几个反射物体,常规操作~~

image.png

使用 TimeLine 做一个简单的循环完事~~~