简单来说,Drawcall就是屏幕渲染一次所需要的开销,为了较少消耗,提高性能.
什么是DrawCall以及如何对DrawCall进行优化操作。
一、什么是DrawCall?
在unity中,每次CPU准备数据并通知GPU的过程就称之为一个DrawCall。
具体过程就是:设置颜色-->绘图方式-->顶点坐标-->绘制-->结束,所以在绘制过程中,如果能在一次DrawCall完成所有绘制就会大大提高运行效率,进而达到优化的目的。
二、DrawCall为什么会影响效率?
说道为什么会影响效率,就首先要了解一下他的工作原理:为了CPU和GPU可以进行并行工作,就需要一个命令缓冲区,就是由CPU向其中添加命令,然后又GPU从中读取命令,这样就实现了通过CPU准备数据,通知GPU进行渲染。
在每次调用DrawCall之前,CPU需要向GPU发送很多内容,主要是包括数据,渲染状态(就是设置对象需要的材质纹理等),命令等。CPU进行的操作具体就是:
准备渲染对象,然后将渲染对象从硬盘加载到内存,然后从内存加载到显存,进而方便GPU高速处理
设置每个对象的渲染状态,也就是设置对象的材质、纹理、着色器等
输出渲染图元,然后向GPU发送DrawCall命令,并将渲染图元传递给GPU
所以如果DrawCall数量过多就会导致CPU进行大量计算,进而导致CPU的过载,影响游戏运行效率。
注意:
场景中有100个gameobject,它们拥有完全一样的Material,那么这100个物体很可能会被Unity里的Batching机制结合成一个Batch。所以用“Batches”来描述Unity的渲染性能是不太合适的,它只能反映出场景中需要批处理物体的数量。那么可否用“Draw calls”来描述呢?答案同样是不适合。每一个“Draw calls”是CPU发送个GPU的一个渲染请求,请求中包括渲染对象所有的顶点参数、三角面、索引值、图元个数等,这个请求并不会占用过多的消耗,真正消耗渲染资源的是在GPU得到请求指令后,把指令发送给对应物体的Shader,让Shader读取指令并通知相应的渲染通道(Pass)进行渲染操作。
我的上篇博文【U3D】进入shader编程的世界里有简单介绍过Shader,不懂的童鞋可以去看看。接着上边的问题进行说明,场景上有1个gameobject,希望能显示很酷炫的效果,它的Material上带有许多特定的Shader。为了实现相应的效果,Shader里或许会包含很多的Pass,每当GPU即将去运行一个Pass之前,就会产生一个“SetPass call”,因此在描述渲染性能开销上,“SetPass calls”更加有说服力。
三、如何优化DrawCall?