目录
一、有哪些需要进行优化的?
二、DrawCall
1、什么是DrawCall?
2、为什么过多的Draw Call会造成卡顿?
3、如何减少DrawCall?
动态批处理:Unity自动地将满足条件的物体网格合并,传递给GPU使用同一个材质进行渲染。
动态批处理条件:
静态批处理:运行开始阶段把需要静态批处理的模型合并到一个新的网格结构中,进行批量处理。
静态批处理条件:
三、网格重建
1、Layout重建:
2、Graphic重建:
四、Overdraw
1、CPU相关:Draw Call、网格重建
2、GPU相关:OverDraw
在unity中,每次CPU准备数据并通知GPU的过程就称之为一个DrawCall。
在大多数情况下是因为CPU准备数据的时间过长,数据包含但不限于:网格、纹理、着色器、顶点位置、顶点颜色、法线,导致GPU闲置。
把多个DrawCall打包成一个DrawCall达到减少DrawCall目的,又称批处理技术。
批处理分为动态批处理和静态批处理。
3、3D物体的Scale分量不能出现负数。
4、着色器不能有多个Pass块渲染,例如:渲染路径为ForwardAdd至少有2个Pass块。
5、存在阴影投射时,MeshRenderer组件的阴影Receive Shadows属性必须一致,即保证批处理的物体同时接收阴影或不接收阴影。
1、相同的材质。
2、大多数平台上,批处理限制为64k顶点和64k索引,OpenGLES上为48k索引,在macOS上为32k索引。
3、存在阴影投射时,MeshRenderer组件的阴影Receive Shadows属性必须一致,即保证批处理的物体同时接收阴影或不接收阴影。
动态批处理和静态批处理优缺点:
- •动态批处理节省内存,限制较多,消耗一定的性能。
- •静态批处理限制较少,耗费内存。
静态批处理通过将模型顶点转换为世界空间并为其构建一个共享的顶点和索引缓冲区来工作,而动态批处理是每帧将模型顶点转换到世界空间。
网格重建是发生在每次渲染前对需要重建的UI元素进行重建的过程。
在UGUI源码中,网格重建会在上一帧收集需要重建的UI元素,在当前帧渲染前进行排序元素列表,执行重建。
UI元素主要分为Layout元素和Graphic元素。
Layout元素:HorizontalLayoutGroup、VerticalLayoutGroup、GridLayoutGroup、ScrollRect等。
Graphic元素:RawImage、Text、Image。
重建主要分为Layout重建和Graphic重建,Layout重建有布局前、布局时、布局后状态,Graphic重建有渲染前、渲染后状态。
先自下而上地执行Layout元素的CalculateLayoutInputHorizontal/ CalculateLayoutInputHorizontal方法进行计算布局大小、行数、列数等内容,接着自上而下地执行Layout元素的SetLayoutHorizontal/ SetLayoutVertical方法进行调整子物体的位置或调整自身大小等事情。
①更新网格:RawImage/Text/Image使用不同的形式获取到网格数据,若有Shadow/Outline会对网格加工处理,再返回CanvasRenderer进行渲染。
②更新材质:设置材质个数,修改并设置材质,设置主纹理、Image的透明通道纹理。
可通过查看Profiler的Canvas.SendWillRenderCanvas函数来大致了解网格重建的开销。
优化方法:
A)减少Rebuild的影响范围,动静分离,将动态元素放到一个新的Canvas中。
B)使用尽可能少的UI元素,检查层级,删除不必要的UI元素,达到减少深度排序的时间。
C)谨慎使用UI元素的enable和disable,因为它们会触发耗时较高的rebuild,可使用Layer层来显隐UI 或 enable和disable它们的Canvas。
D)谨慎使用Text的Best Fit选项,Unity会为Text使用过的所有字号生成图元保存在altas里,会增大内存压力和增加额外的生成时间。
E)谨慎使用Canvas的Pixel Perfect选项,开启后,在Canvas下的UI位置、大小信息变化后,会引起周围其他UI进行微调大小,导致会有更多元素需要进行Rebuild。
可通过反射方式获取CanvasUpdateRegistry的Layout列表和Graphic列表,获知哪些元素触发网格重建。
Overdraw是指屏幕上的某个像素在同一帧的时间内被绘制了多次。UWA分析报告中,以总填充总数来表达一帧内渲染的像素数量,过多Overdraw可能会引起GPU过载,影响动画的播放和界面响应速度。可通过选择Scene面板的Overdraw选项查看情况,进行针对性优化。
优化方法:
1、尽可能减少UI重叠部分。
2、减少带透明通道的图片非必要的透明部分,因为Alpha为0也会参与渲染。
3、尽可能使用全屏UI,全屏UI显示后可隐藏背后的物体。
4、重叠较多的地方尽可能不重叠。
5、使用RectMask2D代替Mask,Mask的隐藏元素依然会渲染,而RectMask2D完全隐藏部分不会渲染,但部分隐藏的元素会渲染。
6、使用一个继承于Graphic但不参与网格重建、缓存顶点和渲染的脚本,代替透明Image接受事件。