降低游戏的Drawcall,是渲染优化很重要的手段,接下来从以下4个方面来分析如何降低DrawCall:
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。
降低Drawcall的意义是什么?如何查看游戏的Drawcall
游戏引擎遍历游戏场景中的所有的物体,然后得到一个物体的渲染顺序,然后按照顺序提交给GPU来绘制游戏画面出来。每次渲染时,CPU把每次绘制要使用的数据传递给GPU,然后向GPU下达绘制DrawCall指令,GPU接收到指令以后”开机”绘制游戏物体出来。假设我们有100个物体需要渲染,如果分100次提交给GPU,每次GPU渲染一个,完成后再渲染下一个,这样CPU就要向GPU传送数据100次,同时下达100次的渲染命令。如果是这样,CPU提交数据给GPU,下达指令会有额外的开销,GPU每次可以处理很多个面,但是由于每次只送进来一个物体,导致GPU的处理能力没有发挥出来。假设把100个物体一次提交给GPU一起绘制, CPU不用反反复复的给GPU下达指
如何查看游戏运行时Drawcall的数目,如下图所示:
总结一下降低Drawcall次数的意义:
Drawcall合批的常用的技术手段原理与优缺点
尽可能的让我们的游戏场景的物体能最少的批次完成渲染,一次渲染尽可能多的物体,降低Drawcall能提升渲染的性能。Unity游戏开发中有哪些常用的技术能将物体合批,降低Drawcall呢?
静态合批:
游戏引擎会将"能够合批“(同一个材质球)的"静态物体"(所以你要标记为静态不可移动物体) 预先合并好成一个新的整体的网格,提交给GPU渲染。
静态合批处理的局限性(缺点)
动态合批:
游戏引擎将"能够动态合批"的(同一个材质球) 物体的每个顶点,根据世界变换矩阵,用CPU来计算合批物体的每个顶点对应的世界空间的坐标,然后就把计算后的物体的顶点(世界空间下的顶点)与单位矩阵一起提交给GPU,GPU一起把他们渲染出来出来。
动态合批是引擎会自动处理的,所以引擎会对能够动态合批的物体,会有一些条件的限制,引擎和系统给的合批的限制是顶点数目不应过多;
最后总结一下动态合批的缺点:CPU的开销和drawcall减少得到性能提升之间来做平衡;
GPU Instancing合批:
同一个网格对象的N个实例的绘制可以采用GPU Instancing合批。它的本质就是提交一次网格物体给GPU, GPU绘制出这个物体的N个实例到不同的地方(位置,旋转,缩放)。如1000个小兵采用GPU Instancing 合批,提交一个小兵的网格对象给GPU, GPU根据1000个小兵的位置来绘制出来我们1000个实例。
组织项目让Drawcall更小需要注意的点
合理的安排物体, 注意不要打乱物体的合批。3D物体的渲染顺序是引擎自动计算出来的,尽可能的在3D场景里面让物体使用同一个材质,尽可能的在同一个渲染队列里面使用同一个材质,尽可能的在3D场景里面使用同一个种shader,不要根据物体渲染的需顺序来回切换shader(Set Pass Call开销很大)。2D UI物体尽可能的安排同一个图集的物体在一起,如任务系统UI,尽量的让任务系统这些UI物体在一个图集里,这样可以合批渲染;
将多个物体的纹理合并到一起,如游戏地图上的障碍物,可以将这些障碍物与地图的纹理合并到一起,这样地图和障碍物可以由合批的可能。
最后 美术把能合批的物体生成到一个fbx模型里面,这样从美术的层次来减少渲染批次。
今天的分享就到这里了,关注我们可以获得更详细的官方给出的合批的一些规定,帮助大家优化Drawcall。