- 前言:面试Unity开发,很多时候都会被问及有没有做过DrawCalls的优化(Unity旧版的性能面板上可以看到的一个属性),然而DrawCalls又是个什么东西呢?我们又应该如何去优化它。而Batches则是现在新版的Unity性能面板上面的一个参数属性,也是新版强调的一个参数,而弱化了DrawCalls的显示,这又是为什么呢?首先我们先来看看DrawCalls和Batches的定义来找到它们的区别吧。
- DrawCall:CPU每次调用图像编程接口 glDrawElements(OpenGl中的图元渲染函数)或者 DrawIndexedPrimitive(DirectX中的顶点绘制方法)命令GPU渲染的操作称为一次Draw Call。Draw Call就是一次渲染命令的调用,它指向一个需要被渲染的图元(primitive)列表,不包含任何材质信息,glDrawElements 或者 DrawIndexedPrimitive 函数的作用是将CPU准备好的顶点数据渲染出来。
- Batch:把数据加载到显存,设置渲染状态,CPU调用GPU渲染的过程称之为一个Batch。这其实就是渲染流程的运用阶段,最终输出一个渲染图元(点、线、面等),再传递给GPU进行几何阶段和光栅化阶段的渲染显示。一个Batch必然会触发一次或多次DrawCall,且包含了该对象的所有的网格和顶点数据以及材质信息。把数据加载到显存是指把渲染所需的数据从硬盘加载到内存(RAM),再将网格和纹理等加载到显卡(VRAM),这一步比较耗时。设置渲染状态就是设置场景中的网格的顶点(Vertex)/片元(Fragment)着色器,光源属性,材质等。Unity提供的动态合批(Dynamic Batching )合并的就是这一过程,将渲染状态相同的对象合并成一个Batch,减少DrawCall。
- 关于定义和区别相关的可以看看:【https://blog.csdn.net/wei_yuan_2012/article/details/88677172】
- 总结:一个Batches必定会执行一个或多个DrawCall,优化BatChes的数量也就是优化了DrawCall。那么我们又该如何去优化呢?一般来说DrawCalls优化的常用的方法是批处理,就是把一些渲染的东西合并再一次,然后一次性地让系统去渲染,从未节省了调用多次DrawCalls的时间。
- 批处理:批处理的方法有好几种,动态批处理、静态批处理、合并图集批处理等等,在这里简单地介绍一些批处理的具体方法和一些关键点。
- 动态批处理:Unity自带的一种处理方式,不需要开发者做额外的操作,Unity会把使用相同材质的游戏物体进行批处理。当动态批处理有限制条件,就是默认进行动态批处理的游戏物体需要用到同一种材质,仅支持小于900顶点的网格无皮,如果着色器使用了顶点位置、法线和UV三种属性,那么只能批处理300顶点一下的物体等等……具体的一些条件可以参照:【https://www.cnblogs.com/lancidie/p/5875742.html】。
- 静态批处理:不限制同种材质,但一般是将在游戏中不会运动的静态物体进行批处理,需要手动选择,在游戏物体的属性面板上面的右上方选择Static,Unity就会对相应的游戏物体进行静态批处理。静态批处理就是讲物体的网格模型进行合并,然后一次性渲染出来,从而节省了Batch的开支,减少DrawCall。一般来说静态批处理会提高内存的占用,但会提高渲染的性能,也就是空间换性能。
- 图集批处理:如材质的贴图等、UI的素材图片等等。用了相同材质的游戏物体,但如果贴图不同的话会额外增加DrawCall的调用,提高渲染的开支。但把同一个材质的游戏物体的所有贴图进行图集处理,然后再在材质上调用同一张图(图集)则可以减少这个开支。同样UI素材图片等,同一个UI层级的或者同样节点上的可以进行同样的图集处理,合并在同一个图集中,也一样可以减少渲染的开支。
- 总结:批处理一般是将一些游戏物品上的某些属性或者部件进行合并渲染处理,从而达到优化的效果。除了上面提及的批处理优化DrawCalls的方法外,还有一些其它的方法减少DrawCalls的开销,但我个人感觉大多数其实都是离不开批处理的概念。
- 额外方法:硬性减少方法处理:开发的时候尽量避免使用很多顶点的游戏物体,减少光照和阴影的使用等等,即高精度的模型可以用低精度的模型来处理等等……烘焙处理:对使用了光照和阴影的场景地图等静态物体进行烘焙处理,将阴影以及一些复杂的渲染流程效果等转换成贴图的形式,从而减少DrawCall的开销。模型合并处理:对于一些多顶点但联合关联在一起的游戏物体,如父子节点等等,而又不需要相互移动的游戏物体,可以直接进行合并模型处理,可以减少顶点,节省部分渲染的性能(模型合并规则:非同样的静态模型、U午重复的模型可以用Mesh Baker合并,重复则会出错,有需要颗在制作软件合并、不同材质不能合并、合并模型贴图大学要满足2的n次冥)。烘焙以及合并可参照:【https://blog.csdn.net/leeby100/article/details/89596950】【https://www.jianshu.com/p/502ef6cc24ad】
- 总结:DrawCalls的优化具体还得看具体的项目,方法一般只是参照,要根据实际的需要,从而选择最优化的方案,以上仅是我个人的一些经验和看法,参照了一些大佬的文案,具体链接在文中,有兴趣的同学也可以点进去看看。
Unity的DrawCalls和Batches的优化处理
最新推荐文章于 2023-12-07 11:50:38 发布