时间2021年12月29日,距离学习后到毕业已经过去3年时间了。这3年也在一直用Unity开发一些2D游戏,但感觉自己的技术一直没有什么精进。是时候静下心来,反思一下自己的过往,并继续拿出刚入行时的气势,去学习一些新东西了。今天主要是记录下,自己学习的关于DrawCall的知识。
首先,DrawCall就是渲染一次拥有一个网格并携带一种材质的物体便会使用一次Draw Call。可以理解为调用一次DC就换一种画笔在画板上画一个物体。具体过程就是:设置颜色-->绘图方式-->顶点坐标-->绘制-->结束,所以在绘制过程中,如果能在一次DrawCall完成所有绘制就会大大提高运行效率,进而达到优化的目的。
然后,每次调用DrawCall之前,CPU又会发送一大堆内容给GPU,其中包括渲染方法,要渲染的物体等等。第一步:将要渲染的物体从硬盘加载到内存,再从内存加载到显存,方便GPU使用。第二步:设置好要渲染的状态,也就是对应物体的材质,纹理,着色器等。第三步:渲染输出图元,并向GPU发送DrawCall指令,进行渲染。由此可见,如果DrawCall命令过多,会导致我们的程序运行效率降低。
一、相同材质和纹理的UI素材打包成图集
在降低Drawcall方面,一个非常重要的概念就是Batch,因为一次Drawcall相当于CPU与GPU进行一次沟通的成本,如果CPU能一次多打包一些信息给GPU,那么Drawcall数量自然就下来了,这个打包传输信息给GPU的过程就叫做Batch,批处理。那么什么情况下这些信息可以打包呢?从uGUI的角度,如果你的UI中组件的材质与纹理均相同,这几个组件就可以被Batch。在Image组件中,材质对应Source Image,纹理则对应Material;在Text组件中材质对应Font,纹理也是Material。
? ? ? ?然后,我们根据上面的批处理方法,可以将一些UI元素打包成一张图集,一次性传给GPU,然后根据不同位置,让GPU渲染不同的图,这样就可以在1次Drawcall中完成大部分UI素材的显示,从而减少DrawCall,增加性能。
二、注意渲染层级问题
? ? ? ?但在批处理中,也会存在一些层级的问题,这也是需要注意的点。例如,在同一个Canvas下绘制A,B,C这3个UI,已知AB为相同材质和纹理,而C为不同材质。此时渲染后DrawCall理应为2。但如果变换Canvas下层级顺序,变为绘制A,C,B,则DrawCall会变为3。具体原因是,批处理的过程中,AB虽然相同,但中间夹杂了C物体,导致CPU重复给GPU多发送了一次DrawCall。下面是看大神总结的Canvas层级计算方式。UGUI性能优化之Drawcall详解_Aison_的博客-CSDN博客_ugui优化
同一个Canvas内,UGUI的层级计算方式: 1、一个UI元素,在它所占的屏幕范围内(通常是矩形),如果没有任何UI在它的底下,那么它的层级号就是0(最底下); 2、如果一个UI在其底下且该UI可以和它合批,那它的层级号与底下的UI层级一样; 3、如果一个UI在其底下但是无法与它Batch,那它的层级号为底下的UI的层级+1; 4、如果有多个UI都在其下面,那么按前两种方式遍历计算所有的层级号,其中最大的那个作为自己的层级号。
三、注意尽量少使用实时光照
Unity DrawCall详解_yu1368072332的博客-CSDN博客_drawcall
以上内容,都是这位大佬总结的,我只是写个观后感,方便自己记住。当然,如果大家有什么更好的降低DrawCall的方法,也可以回复我。感谢!!!
?
|