• unity 渲染性能分析工具


    目标

    既然要优化,肯定要有个目标:
    pc上一般要求:一秒渲染60帧
    移动端:一秒渲染30帧
    这应该是最低的要求,如果游戏运行时,游戏帧率有变化,人眼能够明显的感觉到帧率下降。
    优化的首要规则是找到性能问题的所在。
    一般出现问题不是在cpu就是gpu。

    profiler

    unity内置了性能检测工具,
    在这里插入图片描述
    可以在Window->Analysis->Profiler 打开,由于在编辑器内调试准确率有问题,一般推荐打包调试
    在这里插入图片描述
    打包调试记得开启调试模式,并开启自动连接调试器并支持深度调试,这样等打包完成自动打开场景时,unity会自动连接profiler,省得我们自己去连接。
    在这里插入图片描述
    上图为跑了一些帧后的每帧时间占用。
    在这里插入图片描述
    我们还可以在这里切换成Hierarchy模式查看每个函数列表耗时。当你选择函数时,上面图标也会高亮相关内容。
    在这里插入图片描述
    这一块可以看到每一部分占用的时间,左侧为什么类型,右侧是占用时间的变化,点击选择一帧。
    在这里插入图片描述
    在下面会看主要分了三大部分,这一帧总耗时16.74ms
    左侧是代码逻辑部分占用时间,我这个测试项目没有多少逻辑占用,所以性能占用很少。中间这一部分是调用渲染占用时间,可以看到占用了2.15ms,然后是最后的同步占用时间13.61ms。相当于电脑可以一直按满帧率去跑。
    如果脚本的问题话,需要让程序去排查,TA一般需要查看右边的两部分问题。
    在这里插入图片描述
    多线程的我们还可以看到渲染线程给我们分出来了,让我们查看渲染线程做的操作。灰色的部分是在等待主线程耗时上面会显示Gfx.WaitForGfxCommandsFromMainThread,而蓝色部分为实际渲染时的批次提交耗时。而在urp渲染管线,后处理的操作是在主线程做的。
    在这里插入图片描述
    上图可以看到,应该是我开启了垂直同步,导致同步时间过长,如果在排查问题,推荐将垂直同步关闭。让其使用最大性能运算。
    在这里插入图片描述
    上图为关闭了垂直同步后的视图,为每帧真实的渲染时间。但是你看画面会有撕裂感,这也是垂直同步带来的好处,调试时,我们是可以关闭的。

    每帧渲染

    在cpu上,每帧需要处理的事情:

    1. 逻辑相关:脚本,物理,动画
    2. 渲染:剔除,排序,绘制
      • DrawCall包含了单个玩个的数据以及相关的渲染信息纹理矩阵等,然后提交渲染的命令
      • SetPassCall用来设置用于渲染网格材质的所有渲染状态数据,
      • Batches是包含了一个共享顶点和索引的缓冲区数据包,不用提交顶点数据,速度很快,批处理的意义在于减少了渲染状态的切换,它不能减少DrawCall,但是可以减少其它状态的切换,相对来说调用DrawCall的耗时比SetPassCall耗时更少。
    3. 同步:同步的问题一般会有垂直同步和帧率限制的问题,同步时都会有等待的状态,
      • 垂直同步是在你的渲染帧率高于屏幕显示器最高帧率时,它会自动限制帧率和显示器保持同步。
      • 帧率限制也是为了保证每秒的帧率平衡,不产生撕裂感。
      • 如果同步里出现WaitForTargetFPS,是因为垂直同步的问题,调试时不建议开启。
      • 如果出现GfxDeviceD3D11.WaitForLastPresent,表明CPU所有线程已经完成任务,正等待CPU,可能存在gpu性能瓶颈。
      • 如果出现Gfx.WaitForPresentOnGfxThread,表示主线程已经完成非渲染任务,正在等待渲染线程,但渲染线程尚未完成。1. 若此时渲染线程正在进行Camera.Render,并且Camera.Render耗时过高,则表明性能瓶颈在cpu端渲染部分。2. 若此时渲染线程正在进行Gfx.PresentFrame,则表明性能瓶颈在gpu端。

    在gpu上,影响gpu渲染效率的是像素填充率(filling rate),填充率=屏幕像素Shader复杂度Overdraw,可以影响到效率的主要内容有:

    1. 屏幕分辨率
    2. 后处理效果
    3. Shader复杂度
    4. Overdraw 重复绘制,指屏幕的同一像素进行多次绘制,一般是因为
    5. 带宽瓶颈:内存带宽是指gpu可以读取和写入内存的速率。当gpu当前渲染数量太大,内存无法及时传输给gpu,会造成等待耗时。常见情况在延迟渲染中常驻Gbuffer及各种缓冲区和RT,占用内存非常大,并且一直在读写。移动平台gpu的带宽性能和纹理处理能力比较低,需要注意此问题,这也是移动端很少使用延迟渲染的原因。
    6. 同屏三角面数,顶点数,为什么顶点的影响小,可以这样计算,一张1k的图片就是一百万个像素,而一百万个顶点的模型我们很少用。
      总结一下:区分问题哪里的问题看同步的那几个函数,而在gpu上,主要看像素的计算量,屏幕分辨率是主要原因,屏幕像素渲染量是指数增加,后处理也是基于屏幕分辨率计算的,而半透明是因为模型所处的区域全部需要绘制,因为它的渲染顺序是基于相机的位置从远到近绘制的,没有被半透明遮挡的位置全部需要绘制。我们可以感觉到gpu上的计算量非常的大,毕竟每个像素都需要跑一次片元着色器内的内容。

    性能分析工具

    1. unity内置的Profiler 上面讲的
    2. FrameDebugger 帧调试器,主要渲染效果调试,查看当前每帧渲染的内容
    3. FPS Counter 场景组件,可以直接添加到场景内,查看渲染情况
    4. UPR unity官方提供的性能工具 UWA 第三方专业做性能的公司
    5. RenderDoc 截帧工具 XCode 是ios平台使用的调试工具,一般调试苹果手机使用

    场景优化

    1. 场景结构,层级推荐不要太复杂,动态生成的直接放在Root下面。
    2. 尽量使用Profab,而不是直接使用GameObject。
    3. Shader通用一套,保证物体使用同一个Shader,这是合批的前提。
    4. LightMap推荐2048,数量太多会影响合批。
    5. 检查ReflectionProbe,它也会影响合批
    6. 对静态物体尽量保证材质球共有,图片合并
    7. 对大量的树,草,石头使用GPU Instancing
    8. 检查剩余物体是否能够srp合批。
    9. 检查最终资源的是否有占用过大的情况
    10. 根据同屏面数确定是否使用LOD
    11. 优化场景Shader以及光照和阴影设置。
  • 相关阅读:
    猿创征文|Vue源码分析(响应式)
    AcWing 827. 双链表
    冬季如何养胃?羊大师建议水果蔬菜不可少!
    【C++】内存管理——new与delete
    图片怎么加满屏水印?
    node使用puppeteer生成pdf与截图
    计算流体力学的基本方法简介(有限差分法、有限元法、有限体积法)
    Linux 内存性能指标
    行为型:观察者模式
    Flume配置3——拦截器过滤
  • 原文地址:https://blog.csdn.net/qq_30100043/article/details/130440015