跳过正文
  1. 文章/

UE奶瓜学习笔记

Lickba
作者
Lickba
一个热爱游戏的玩家

title
#

UE奶瓜学习笔记
#

UE快捷键:
#

在场景中播放奶瓜粒子:选中时 /? 未选中时 shift + /?

开头:
#

定值参数 float浮点 Vector矢量等等 + 表达式 随机值 曲线 最大最小值等 = Emitter节点(节点的先后顺序不同,结果不同。节点互相之间可能有继承和需求关系。)

一个或者多个Emitter节点 组成 Emitter发射器(一个系统可由多个发射器组成)(发射器类似Unity中ps粒子定位,不过自定义程度高很多)

Emitter发射器 组成 Niagar粒子效果(这是在UE场景中能被调用的最小资源单位)

image

重点:奶瓜本质是一个点属性模拟器,本质是一堆点的各种参数数据在进行运算模拟(用纯理性纯数据去模拟各种美术效果)

0201:发射器
#

发射器运算顺序:Emitter Spawn → Emitter Update → Particle Spawn → Particle Update → Render

emitter spawn只在该发射器被激活的那一帧计算,例如初始位置等(类似void Start)

emitter update在游戏运行时的每一帧都在运算,例如速度对粒子的位置影响等(类似void Update)

particle spawn只在粒子被发射出来的那一帧计算,例如初始位置,颜色等

particle update在游戏运行时的每一帧都在计算,例如速度对粒子的位置影响等

Render在收集了当前帧的所有粒子属性后,使用这些属性渲染最终的模型和材质效果。一个发射器可以有多个render,读取不同属性渲染不同效果。

使用的属性会被binding,所以在debug时通常是从binding往回找。例如位置不对,看一下位置binding是哪个属性,通过这个属性运算的过程找问题。

image

0202:属性用法实战
#

创建完全空置发射器→创建属性,为属性直接赋值

			→修改binding,使用自定义属性渲染粒子

			→位置 速度 加速度 阻力 的运算关系

引擎自带的属性是和其他自带节点配套使用的。

Emiter state 决定了发射器的时间概念

Scratch Pad 提供给你临时写个节点的功能,仅能被当前粒子系统引用。(所有自己写的module,如果搜索不到,可能是你没有正确设置使用位置,默认只能被用在粒子里,而不能用在发射器或者系统里)

注意谨慎在update模式下使用random等每帧求知的函数,可能造成效果错误,要明确究竟是初始时(spawn)赋值合适,还是运行时(update)赋值合适。

image

位置 速度 加速度 阻力 的运算关系是重中之重!

0203:手写自定义解算器
#

创建module并内置运算逻辑 → 一但特定module被引用则在系统内的属性会被上锁,避免错误修改。

					→ 在module内写算法时,逻辑关系很重要,一定要逻辑清晰(不要跨节点set和get值)

					→ 通过View Option观察节点的输入和输出属性

					→ 在写复杂的节点时,时刻记得写comment备注你的思路。

					→ 正确设置节点的使用位置(默认只在粒子里用到,参照0202)

					→暴露到library中,才能被调用到,这个经常性被遗忘。

image

在module内写算法时,逻辑关系很重要,一定要逻辑清晰(不要跨节点set和get值)

0301:发射器的创建和继承
#

单独显示发射器,点击发射器左上角的小人图标

Dynamic Impute的值,如果和默认值不同,则是黄色回车图标,点击回归默认值。绿色回车图标代表和父级不同,点击回归父级默认值

创建新的发射器-继承(继承的发射器创建后会有父级关系(继承模板发射器则不会有))

创建新的发射器-模板(从模板创建的发射器没有基础关系,相当于copy了所有的属性和节点成为新的发射器。)

发射器继承 → 一个被继承的发射器,右上角有小图标,并且名称右侧有一个灰色的名字,是其父级发射器名字。

		→	**发射器的继承,本质是继承了所有节点,以及节点的默认值。** 

		→	在子级Emitter修改节点内的数据,造成和父级不同时,则父级的修改不会影响子级

		→	任何父级的节点增加删减,都会同步到所有子集发射器。

		→	你可以重新设置新的父级,或者删除父级(删除后父级的任何操作不影响子集)

		→	<u>建议你在创建系统时确定系统关系,并保持所有关键发射器的继承关系以便于后续增加和修改功能。</u>

		→	父级发射器的节点在子级不可被删除,只能被Disable。

		→	任何子级的修改都不会影响父级。

		→	继承关系可以很长,叫做继承链条。

image

image

0301:火花Emitter模板
#

NoiseForce 强度和频率参数

Engine ower position 指的是粒子系统在世界中的位置。simulation position 模拟位置,根据local space 和非 local space 判断使用位置

Size by speed 根据粒子速度缩放粒子尺寸

initial Location to Velocity 节点,创建基于初始位置的速度节点。以后会经常用到。

Velocity facing 基于速度的朝向

Curve+Random 来重分配数值,得到权重数据的方法。

image

0302:火花Emitter模板的材质
#

依照速度控制贴图读取,伪造更好看的动态模糊(奶瓜自由度很高的一种体现,类似把粒子速度放到了Unity粒子里的CustomData里调用)

Niagara和材质的沟通其实也就是Binding!!! → 使用Dynamic Parameter传参数到材质

								→	类似ParticleColor也是通过一样的方法传递信息的,只是名字不同而已。如果可能,你甚至可以强行覆盖一些属性传递自定义的值(例如将color当做自定义										的density使用)

								→	Dynamic Parameter 支持最多四组Vector4,注意在节点内调用时,不要覆盖其他值。(类似CustomData)

image

0303:蓝图施法和效果优化
#

时刻在正式游戏中观察效果,确保效果在场景中正确,它可能和预览窗口里差别非常大! (替换Default Game Effect蓝图模板中的NiagaraTemplate,就可以在游戏中看到效果了。)

Emitter必须Apply后,才能看到System里的更新。

一定注意当前修改的是Emitter还是System,很容易错误操作。

材质中的ResponseAA是透明材质中会影响到小粒子的重要参数,在用小粒子和细碎物体的情况下,需要勾选上。

可以为文件夹添加颜色或用favorite文件夹。方便查找目录

image

0304:Flare主材质制作
#

MaskPick节点(选择一个RGBA通道遮罩)(黑白图一般选绿色质量更高说是)

image

DepthFade节点依据深度对透明物体做淡化。注意这依赖引擎的深度通道(材质instance是主材质的分支,有主材质暴露出的参数可以调整,以产生不同的变体效果。)

材质和材质instance(实例)(有些参数隐藏于function中,打开才可以看到。)(每一个静态材质开关相当于创建了额外的分支,在项目中尽量避免超过4个static以上的开关。)

image

0305:Flare的Emitter制作
#

Flare光斑效果的表现(反比例衰减)(中心很亮,衰减很快(比较接近真实物理感))

CameraOffset功能,其实是将粒子的渲染位置贴近摄像机,注意不是粒子的实际位置,并非particle.postion

F2快捷键,所有UE的重命名操作几乎都是这个快捷键。

按G隐藏场景图标(其实是隐藏所有标记为hidden in game的组件。)

按T取消选择场景中的透明物体,直接选中Opaque(不透明)物体。

Play时按X可以变速(游戏模板功能)

image

0306:粒子灯光
#

灯光对场景的影响,可以让特效更脚踏实地,但消耗也非同一般。

如果你没看到灯光,可能是亮度不够强,或者是范围不够大,这两个参数要紧密配合才能看到结果。(使用optimization view mode - lightcomplexity观察灯光复杂度)(灯光范围是非常容易被过度调大的参数,需要加以重视。)

预览粒子效果快捷键/?(需要选中想要在场景中预览的粒子)

Volumetric雾效果,需要开启height fog中的volumetric fog(体积雾)(这个雾会受到光强度和scattering强度影响,在亮度过高时衰减会过慢。)

部分灯光的默认属性,没有在原有属性库中,需要创建新属性,并从binding中抄过来

所有在spawn时设置的值,都保存了初始值(带有initalnamespace)在Update时可以读取使用

在特效中最常用的是指数衰减的灯光模式,可避免中心过渡曝光,以及边缘过于暗的情况。(通常特效的灯光衰减指数为2-5为好)

image

0307:特殊情况下的效果优化
#

CameraFade在接近摄像机时渐渐隐去效果。

ParticleShrink在接近摄像机时使particle收缩变小。

这种优化依据不同的项目类型时需要取舍的,有些项目可能特效尺寸相对固定,有些则变化很大。都需要根据特定情况选择。

image

EX01:完美光斑
#

材质混合模式AlphaComposite:亮的地方用Translucent(相乘),暗的地方用Add(相加),最后的效果会看起来比较舒服,暗部不会有相乘带来的黑边剔除亮部也保留了细节(但是要注意在粒子里需要同时K颜色跟透明度两个值控制消失,单用A或者单用RGB都不行,结束时两个都需要为0)

image

SD里用两个噪波图叠加后加极坐标遮罩做出光斑贴图

image

0401 0402:材质基础 数值化思考
#

UE计算时,如果调用了单通道和多通道计算,则默认视为单通道分成等值的三通道。(这个描述中指的不是最终输出的颜色,是指运算过程中产生的计算。例如Emissive是输出RGB结果,而Opacity则只有单通道R。)

Power 幂运算 快捷键E → 幂大于1时,输入值大于1则值增加。输入值小于1则值减小。

				→	幂为1时结果不变。

				→	幂小于1时,输入值大于1则值减小。输入值小于1则增加。

材质编辑器按T键导入在Content中选中的贴图。

加(A)减(无) 乘(M)除(D)(输入值为负数时结果为0)

Lerp(A* (1-C)) + (B* C) 快捷键L(超出值域的值计算,请通过线形图来脑补)(你不太可能用到Alpha输入三维数的情况,但它是可执行的。)

一减 1-x 快捷键O(大部分情况下作为反转使用,在作为反转使用时,切记输入值的范围为(0-1)结果才正确。

UV,是一个横纵分别为RG线性增长的坐标系。其范围默认是0-1,也对应了整张贴图的横纵重复。

Clamp 钳制限制值到一个具体的范围里,大多数情况下为限制到0-1,则这种情况下可以直接用saturate以节省性能。

勾选 allow negative value 使材质输出负值,光照模式必须选择为unlit。

image

0403:灰尘材质
#

SilenceMoon_Dissolve原创的超好用溶解节点 → 所谓的溶解dissolve,都是在用减法的方法处理贴图数据,根据灰度信息优先剔除部分像素,辅助一些调控参数。

									→	Dissolve数值可能在0-1范围之外,这是跟edge sharpness有关的,需要调整时注意

									→	edge sharpness越高则边缘越锋利(软溶解跟硬溶解)

									→	输入的ramap map范围应该在0-1之内

									→	offset功能可以让你依据同样的纹理独立出另一套有滞后/提前的效果。

在贴图中分通道存储数据,并在材质中调用后着色/计算溶解等,可以最大优化材质,并提供更高的灵活性。

如果数据不需要每帧动态控制材质,尽量不要麻烦dynamic parameter,因为每一个通道都要Niagara传递信息给材质,有额外的开销。例如静态的颜色,静态的参数。(静态值完全可以通过material instance来赋值和做变化。)

image

0404:灰尘模拟
#

非常轻的粒子形态的模拟要点:体积大质量小阻力大(不会有过高的速度),容易被空气乱流影响(高noise),节奏不宜太强。

在调整类似的粒子效果时,可以先选择一条路线,通常是先完成物理形态的模拟,再进行亮度,透明度等调整。最后整体观察来做最后微调。

灰尘在烧尽时,发的光不会太强,如果做的太强会反常识,因为余烬的温度一般是低的。

在处理节奏时,这种灰尘/余烬通常是在主要效果表现完成后,作为环境元素存在的,给玩家一种主要的故事(爆破)讲完了但(残余能量)“余韵犹存”的感觉。

image

0405:烟雾材质
#

在Particle Color用于控制Base Color后,你可以使用三个dynamic paramter通道控制自发光效果。

Sub UV Blend:在两帧图像之间混合,提升图像过渡的流畅性,多用于棱角清晰的subUV,但采样数x2

Motion Vector:这是一个通过偏移上一帧纹理到下一帧(近似)进一步避免帧混合过于明显的技术。需要一个预烘焙的MotionVector数据贴图(低精度即可)

课程提供的SilenceMoon_SubUVMotionVectors自带两种技术,非常推荐你在做高精度烟雾时使用。(你并不需要自己写MV算法或者使用SubUV采样器)(但仍然需要打开Nigara中的subUVBlend选项)

image

0406:向量(重点!!!)
#

贴图、材质里的颜色,可以表达颜色、位置,方向和强度三种数值,而它们的本质都是向量。

向量的两个重要属性,方向和长度。 → 乘以等值时(相当于等比放大坐标系),可以等比例增加长度但方向不变。

							→	向量维度不同,可以表示定值(1D,单轴),平面向量(2D,XY直角坐标系);空间向量(3D,XYZ三维直角坐标系)

							→	2D向量主要用于贴图置换,UV坐标操作,平移等。

							→	3D向量主要用于三维世界位置移动,缩放,计算光影(法线),旋转等。

一般软件生成的贴图(非HDR)只能存储正值的数据,所以类似法线贴图,向量贴图等,会以0.5作为中值,以牺牲精度的方法存储负值。

3Blue1Brown线性代数的本质,形象生动,必看,强烈推荐!【官方双语/合集】线性代数的本质 - 系列合集_哔哩哔哩_bilibili

image

0407:半透明材质光照
#

半透明材质是特效使用最多的一种材质,而在UE中,这种类型的材质对光照的支持是很有限的,因为UE的延迟渲染框架的原因。

调整半透明材质的Shading mode → volumetric光照按照体素方法计算,无论外形如何。(你可以通过命令:r.TranslucencyLightingVolumeDim增加体积光照细分,但每增加一倍,性能下降8倍(理论上),默认值为64)

						→	PreVertex只计算每顶点,不适用于需要增加细节的情况,但是性能很好。

						→	**开启Directional才能启用法线**

						→	Surface TV有比较好的反射,可以做玻璃和水。

						→	ForwardShading是非常昂贵的渲染模式,但拥有Opaque的高质量光影渲染效果(但延迟渲染的功能会失效)

烟雾的法线只能近似和模拟,不能完美实现。这是因为光会在烟雾中散射,而不是像接近表面一样直接反射。 → 课程中使用的EmberGen制作的所有烟雾贴图,但建议大家再等一等,Niagara很快也会推出更适合UE的类似插件、工具。

																					→	六点图模式可以实现2贴图6角度的光照,比课程中的2角度要有更好的效果。但只能将光照计算过程放在材质里,对UE的多光源支持并不好。不推荐项目使用。

使用DepthFade接近地面的值来做假AO提升与环境接触的感觉。

image

0501:烟雾模拟
#

根据实际使用的过程,适当修材质,增加必要的dynamic parameter。这在你构建模板的过程中需要仔细思考。每增加一个调整点都会增加调整的复杂度,增加性能消耗

烟雾效果想要做好? → 与实体的交互(opacity based depth fade)伪造AO

				→	随机化(随机的subuv贴图,随机选择)

				→	**烟雾越薄,AO,Normal应该越弱(蒸汽/寒气/干冰)烟雾越厚,AO,Normal应该越强。(燃油烟,大型爆炸,火灾)** 

				→	正确合理的光照(lit mode,normal)(写实风)

				→	尽量保证烟雾粒子之间的连接(尺寸变化,发射数量)

烟雾是特效中性能最容易爆炸的部分 → 使用ParticleCutout功能来裁切无用的subUV像素,可以一定程度缓解烟雾高消耗的问题。

							→	保持烟雾粒子之间连续即可,尽量减少重叠。通过透明度调整厚度感,而非数量。

							→	**烟雾的方片和高材质消耗很容易造成overdraw,所以切记不要通过疯狂发射数量来提升烟雾细节,这非常不专业。** 

一定要在PIE的模式下看效果哦。

image

0502:石块材质
#

Roughness是目前PBR渲染中最有特点的部分,能模拟物体微表面对光的反射。

Roughness越高则反射越模糊 → Mesh在渲染时的耗费远高于默认的sprite,尤其是面数较高的情况,所以要尽量少用低面模型(修改最低最高Lod),或者直接烘焙成subUV贴图使用。

						→	了解mesh editor中对于模型load编辑的部分。主要是Lod数量,每一级的占屏比/面数 减少级别。

						→	目前Niagara还不支持动态模型LOD,所以依据物体大小正确评估你需要的模型面数并合理使用最合适的LOD,在项目中至关重要。

使用不透明材质,并且直接配合贴图即可

Static Mesh LOD根据模型占屏比例调整面数,以节省性能。

由于默认情况下(非光线追踪)UE计算反射是烘焙的反射球(reflection capture)+屏幕空间反射SSR。所以并不准确。因此物体反射在材质预览窗口与场景里大不相同也是常有的情况。

发射的最终效果取决于场景中的反射情况,以及高光强度,越强则反射越亮。

image

0503:碎块发射器
#

碰撞(它只能近似,不能完全的真实)碰撞距离,可以改善物体与地面的穿插,mesh approx size可以在静态模型面板中找到

							→	摩擦力影响在倾斜平面上的加速度

							→	弹力每次碰撞后弹跳的高度(修改每次碰撞的随机角度可以让效果看上去更真实,也是对微表面的一种模拟)

							→	Rest模式用于避免多次碰撞的粒子反复碰撞。

							→	CPU模式(ray trace,准确计算,消耗CPU很高)适合做少量的,准确的。

							→	每一个System里的Emitter都相当于是父级Emitter的子级

							→	GPU模式适合做巨量的	→	SceneDepth可能在画面之外或者遮挡处失效,不支持透明物体(没有写入Depth通道的)

													→	Distance Field需要在项目设置中打开;精度根据distance field,支持透明物体。

													→	**在移动端模式下,对GPU的支持非常有限,也不建议开启任何基于表面的碰撞,性能开销很大。** 

													→	Mesh distance field需要在mesh设置中添加和更改精度。形状越复杂的物体,例如有镂空等,需要更高的精度。越高占用显存越大

image

0504 0505:力与质量
#

在Niagara中集成了力系统,想要发挥它的作用,让做出来的效果物理更准确,可以为粒子指定Mass属性 → 当你决定使用Niagara的物理部分算法时,时刻记住先调整出正确的物理形态,再加入美术的随机感觉,否则会陷入混乱!

																				→	因为在观感上,物体的大小差别并不大,而mass则差别很大。所以很容易产生大的物体很迟缓,小的物体速度特别快的情况。这是正常的(物理的)。																		→	**为了解决上述问题,我们可以人为修改Mass的比例,让大物体的Mass更小,小物体的更大,就有了NM_MassExp节点,通过重新调整Mass的指数增长曲线来得到效果。(3为线性,1为原始效果)** 									→	当你使用了Mass和Force后,请避免直接设置物体的Velocity等物理属性,容易出现意外之外的效果。

F=M*A力学公式-from牛顿。其中A=F/M则受到相同力的情况下,速度(加速度的结果)取决于Mass

M=V*D其中V为体积(长宽高之积)D为density为物体的密度。是固定常值。

出于使用Force的原因,我们重新调整了NM_InitialPosToVel的节点,使其能够为速度服务,也可以使输出值为Normalized结果。与位置解耦。涉及到了动态Bool变量来改变结果。值得注意的是,动态Bool的两条路线都会参与计算,且可以在运行时修改。如果差别很大,建议转化为静态。 → 涉及到了Bool静态变量来切换负值。这种方式的Bool不能动态修改。

部分属性,例如Transient(临时的)会被隐藏,需要你点小眼睛才能看到。Transient类型在每帧解算一次后会重置/销毁,以节约内存

image

0506:旋转
#

Mesh有三个轴向,所以旋转不再是单独的值控制,而是三个轴向上的 → 计算Mesh旋转的物理相关节点:rotationforce与rotationsolver,需要单独添加否则结果不正确,注意会增加额外的消耗(你可通过meshorientation和updateorientation来制作更cheap的旋转方式但这并不物理)

													→	Collision上勾选结算碰撞旋转,可以让mesh在碰撞时产生更合理的旋转,建议勾选。

效果Polish → 必须在Niagara Object上勾选Cast Shadow才能投射阴影。GE模板默认已经带有该功能。

		→	**勾选light模块里的affect translucent才能照亮烟雾**

		→	**材质里调整respond to decal避免decal贴在某些物体上(此处测试有bug,物体仍然被贴花影响)可以通过在object上取消勾选receive decals完全避免贴花影响(教程中讲解了如何修改GE模板)** 

Bug修复!请大家注意我们在0504 0505两节中修改NM_InitialPosToVel的参数名,导致之前制作的发射器丢失了默认值,请把参数名称改回来即可修复。该Bug属于Niagara系统不完善,应该会在后续修复。(4.27已修复)

image