Unity3D的SRP,Static Batching、Dynamic Batching和GPU instancing

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

所谓的draw call batching绘制批处理),就是指对将要绘制的N个网格,在保持渲染结果正确的前提下,将draw call进行合并,以一整批,而不是单个的方式,向GPU提交这些draw call操作。 绘制批处理有若干种实现方式,有些方式只是减少了提交draw call的次数,但执行draw call的次数没变少。有些方式则是直接减少了draw call的数量。

在《Unity DrawCall、Batch、SetPassCall的区别》一文中对Batching的解释很到位,摘录如下:

Batch 把数据加载到显存,设置渲染状态,CPU调用GPU渲染的过程称之为一个Batch。这其实就是渲染流程的运用阶段,最终输出一个渲染图元(点、线、面等),再传递给GPU进行几何阶段和光栅化阶段的渲染显示。一个Batch必然会触发一次或多次DrawCall,且包含了该对象的所有的网格和顶点数据以及材质信息。把数据加载到显存是指把渲染所需的数据从硬盘加载到内存(RAM),再将网格和纹理等加载到显卡(VRAM),这一步比较耗时。设置渲染状态就是设置场景中的网格的顶点(Vertex)/片元(Fragment)着色器,光源属性,材质等。Unity提供的动态合批(Dynamic Batching )合并的就是这一过程,将渲染状态相同的对象合并成一个Batch,减少DrawCall。

还有对SetPassCall的解释也很好,摘录如下:

SetPassCall Shader脚本中一个Pass语义块就是一个完整的渲染流程,一个着色器可以包含多个Pass语义块,每当GPU运行一个Pass之前,就会产生一个SetPassCall,所以可以理解为一次完整的渲染流程次数。

由此可见,一个Batch包含一个或多个DrawCall,都是产生是在CPU阶段,而目前普遍渲染的瓶颈恰恰就是CPU,GPU的处理速度比CPU快多了,Draw Call太高,CPU会把大量时间花费在处理Draw Call调用上。如果Batch太大,CPU需要频繁的从硬盘加载数据,切换渲染状态,这个消耗要比DrawCall大,所以后面Unity才逐渐弱化了DrawCall的显示。

再提一下,优化的时候还要关注下Statistics窗口上的三角形数(Tris)和顶点数(Verts),这两个数据也是会影响到性能,比如单个物体的顶点数最好不要超过900,不然会影响到Unity的动态合批。Unity的Statistics窗口上的三角形数(Tris)和顶点数(Verts)并不仅仅是视锥中的梯形内的三角形数和顶点数,而是Camera中 field of view所有取值下的三角形数和顶点数。也就是说,即使当前Game视图中看不到这个 cube,只有 field of view在1-179 范围内都看不到这个cube,stats面板才不会统计,GPU才不会渲染,否则都会渲染,而且Unity不会把模型拆分,这个模型哪怕只有1个顶点需要渲染,Unity也会把整个模型都渲出来。

四种优化方式的适用场合

四种优化方式的适用场合

优化方式的优先级

优化方式的优先级

一些细节笔记

参考网页

Unity DrawCall、Batch、SetPassCall的区别 浅谈Draw Call和Batch的区别 Unity渲染优化的4种批处理:静态批处理,动态批处理,SRP Batcher 与 GPU Instancing Draw call batching 为什么baches(draw calls)数那么高? 它们有什么意义? 请教Unity中的Draw Call Batch规则