对《虚幻独立开发日2019:UE4里的性能分析和优化》的摘抄和笔记,归档发表;
UE4里的性能分析和优化:
优化首先判断的是GPU还是CPU的性能瓶颈:
在性能评估时,尽量避免在编辑器里进行性能分析,最好在实际的运行平台上做调试;如果是开发PC游戏,必须在编辑器中调试的时候,也记得在Stand alone模式下运行(还有具体注意事项见上图);
Game线程计算所有的游戏逻辑、数据等等,这些结果和数据被Draw线程使用,算出不需要渲染的内容,最后GPU线程会在屏幕上实际渲染出最终的像素;所谓的瓶颈就可能是在某个线程拖延过久,造成下个线程的等待;
StartFPSChart和StopFPSChart命令可以获得stat unit的输出结果,并记录到格式为CSV的文本文件;
用stat startfile和stat stopfile命令对CPU进行分析也很有用,且会生成相关分析文件;
Unreal Insights工具与Profiler类似,但是个独立程序;
Game线程:
通常Game线程中的性能问题,元凶都是Tick事件(帧事件)中的复杂逻辑;如果在游戏场景中,有许多Actor都在使用Tick事件,很可能会严重拖累游戏性能;
stat game命令可以显示游戏逻辑在特定情况下的每帧耗时,dumpticks命令可以列出正在Ticking的Actors;
在必须使用Tick事件计算复杂逻辑的时候,可以计时器或减少Tick调用频率等方式降低Tick周期,也可以禁用距离玩家太远的Actor的Tick;
一些性能开销比较大的函数;比如Get all actors of class可以在运行开始调用,然后把相关数据存储到数组,方便之后使用;
当Tick事件中的逻辑相当复杂时,可以考虑使用C++;UE4中有相关功能可以转换Blueprint成C++;
UE4可以使用混合编程的方式,所以可以把最复杂的函数转为C++,公开给蓝图使用;
Draw线程:
上图中的圆柱是不同的对象,数字代表Draw Call的数量,右边的其中一个圆柱使用了两个不同的材质,所以多耗费了一次Draw call;
Draw Call的问题对性能的影响非常大,除了相关的命令行外,像RenderDoc等开源工具也可以帮助分析Draw call;
相比起多边形对性能的影响,Draw calls对性能的冲击要大的多;
减少Draw calls的方法比较常见的如使用合并后的大模型代替数量众多的小模型;但会带来一些副作用,比如影响了剔除计算等;
模块化构建关卡虽然方便,也会增加draw calls,注意随时合并模型;
实例化渲染也可以减少draw calls,如植被系统就是自动实例化渲染的,其它类型的模型需要一些手动的设置;
HLODs功能的原理和Merge Actor类似,但区别是HLODs是自动执行合并,并且是非破坏性的合并,比如烘焙一组物件后生成HLODs,虽然像LOD一样远距会切换成烘焙出来的HLODs,但在编辑时仍然可以单独调整每个物件(当然之后要重新烘焙HLODs);
GPU线程:
GPU线程会最终在屏幕上绘制像素;在这个阶段寻找性能问题,最简单的方法是用各种命令关掉各个功能特性;
ProfileGPU不但可以在编辑器中调用,而且还可以在开发版本中生成相关文件;
一些减少Shader复杂度的技巧;使用Feathure level switch来切换针对不同平台的Shader代码;
粒子系统一定要使用Particle Cutout功能,它能自动裁剪图像让其更贴近Alpha通道,减少Overdraw;但植被这些就需要自己手动裁剪模型了(可参考制作高质量植被);