规则总结:
在NGUI中优化drawcall的最优先解决方案原则:尽量少穿插使用不同图集,减少DC合并的打断
UITexture尽量只在大图的情况下用,能用图集就用图集
不同的字体都使用一个depth,并且这个depth最好不要与图片sprite有交叉,最好放在最上层
优化步骤:
I、运行游戏,打开想要排查的界面
II、打开NGUI工具 Panel Tool,找到对应UI名,右侧有几项参考数据,分别是WG(widget数量),DC(drawcall数量),Clip(是否裁切),Tris(三角形数量)
III、关注DC指标,可以观察到该界面的DC为12
再打开NGUI工具 Draw Call Tool,发现,在优化前目前运行状态下一共有38个DC,该界面是从3开始直到14,一共12个
主要的目的是 通过合并DC达到减少DC数量,具体的做法是
1、查看间隔的DrawCall是否使用了相同的材质球
2、如果相同的话,再查看具体的widgets,是否存在可改动的层级设置,可以工具中的Widgets,定位到该DC下具体的控件
IV.优化后
检查发现有部分Label层级设置问题,导致使用UI_New图集的widget无法合并DrawCall,第一次优化后,将DC从12降低到了9
优化后继续查看DrawCallTool,发现这几个DC由于UI_A8和UI_New的互相打断,存在合并的可能
第二次优化后,继续通过设置widget的层级,将UI_A8和UI_New的打断解除,使得UI_New都在一个DC中,最终将DC降到了7
关于UI中的DC需要知道的几个问题
什么是DC?
在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。
DrawCall是CPU调用底层图形接口。每一个的渲染都需要去调用一次底层接口,而每一次的调用CPU都需要做很多工作,那么CPU必然不堪重负。但是对于GPU来说,图形处理的工作量是一样的。所以对DrawCall的优化,主要就是为了尽量解放CPU在调用图形接口上的开销。
NGUI是如何决定控件的渲染顺序?
每一个UIWidget的显示顺序由depth值决定,跟z轴没关系,而这个depth值是由两部分组成的
UIWidget所在的UIPanel的depth和UIwidget自身的depth值
为什么图集能减少DC?
图集的功能是,将密切相关的图打到一起,使用同一个材质,使得存在DC合并的可能。
打成图集后是否就真的能降低DC?
需要控制好渲染顺序,减少渲染被打断,才能控制DC,在NGUI下,统一使用depth来进行渲染顺序的控制
一个比较好理解的例子:
假设3个对象使用不同的材质/纹理,那么无疑会产生3个DrawCall
这3个对象使用2个材质,A和B使用材质1,C使用材质2,这时候来看,应该是只有2个DrawCall,或者3个DrawCall
但发现有时候是2个,有时候是3个。具体原因就是和渲染顺序有关
1.渲染A,使用材质1
2.渲染B,使用材质1
3.渲染C,使用材质2
在这种情况下是2个DrawCall
在下面这种情况下,则是3个DrawCall
1.渲染A,使用材质1
2.渲染C,使用材质2
3.渲染B,使用材质1
没有控制好渲染顺序(或者说没有去特意控制),所以导致了额外的DrawCall。因为A和B不是一次性渲染完的,而是被C打断了,所以导致材质1被分为两次渲染
参考阅读:
https://www.cnblogs.com/smallboat/p/5549624.html
https://www.cnblogs.com/123ing/p/4000082.html
UWA《NGUI开发优化技巧》视频 https://v.qq.com/x/page/j0336jncwn5.html