在游戏开发中,DrawCall的优化是提高游戏性能的关键一环。本文将深入探讨Unity中降低DrawCall的各种策略,从静态批处理到GPU实例化,以及UGUI的优化方法,帮助开发者更好地优化游戏性能。
- 了解DrawCall的本质 在图形渲染中,每次向GPU提交绘制指令就会产生一个DrawCall。因此,减少DrawCall数量可以降低GPU的工作负载,提高游戏性能。
- 如何降低DrawCall? 通过上面的流程就知道DrawCall产生的原因,通过优化DrawCall次数来 在Unity中通常一次绘制是对一个Unity对象(GameObject)进行渲染,例如游戏中有100个对象需要渲染,每个对象需要单独绘制(Mesh Renderer不一样),那就需要进行100次绘制调用,意味着显卡必须执行100次的绘制调用才可以完成场景的渲染。
Unity UI如何渲染? 收集UI数据的主要组件是Canvas组件,Canvas是UGUI系统的核心组件之一,负责定义UI元素的渲染空间,并确定它们在屏幕上的显示位置和顺序。
确定了这些原理之后,思考如何优化这些内容。
游戏场景的优化 我们需要降低渲染批次数量,这样我们的DrawCall个数就会降低。那么如何对多个对象进行同一批的处理呢?Unity给我们提供的方法包括批处理(Batching)、合并网格(Mesh Combining)和使用GPU实例化(GPU Instancing)。这些技术可以将多个物体的渲染合并为一个绘制调用,从而减少渲染的开销,提高游戏的性能。
批处理(Batching):包括静态批处理和动态批处理。常规的需要人为的操作就是静态批处理,当我们在当前的场景中找出不可移动的物体,在Inspector面板中,勾选“Static”复选框,以将对象标记为静态。这样当我们在导出工程的时候,Unity会合并相关Mesh数据等,将多个相邻的静态对象的网格数据合并为一个或多个更大的网格,在运行期间可以在同一批次处理。就是利用内存换渲染效率。综合来说,静态批处理是Unity中常用的优化技术之一,适用于静态场景或对象,并且可以显著提高性能。然而,需要注意其局限性,特别是对于动态对象或具有多样性材质的场景。
GPU实例化(GPU Instancing)是一种在图形处理器上实现的渲染优化技术,它允许多个对象共享相同的网格和材质,但每个实例可以具有不同的变换属性。这种技术可以显著减少绘制调用的数量,提高渲染性能。在游戏加载的流程中,我们需要过滤和统计使用相同网格和材质的对象,这些对象确保该材质启用了GPU实例化(在Inspector面板中启用“Enable Instancing”选项来实现)。在渲染阶段,将实例化数据传递给GPU进行渲染。您可以通过Graphics.DrawMeshInstanced或者Graphics.DrawMeshInstancedIndirect函数来实现。这些函数会告诉GPU如何渲染实例化对象,并将实例化数据传递给GPU。总的来说,GPU实例化是一种强大的渲染优化技术,可以显著提高性能,特别是在大量相似对象需要渲染时。在使用GPU实例化时,需要确保正确设置材质、网格和渲染过程,并根据项目需求进行适当的调整和优化。
静态批处理与动态批处理:
静态批处理适用于那些不需要在运行时改变的物体,例如地形、静态环境物体等。这样可以在构建时预先合并网格数据,以减少在运行时的绘制调用次数。
动态批处理则更适合需要在运行时动态改变的物体,例如玩家控制的角色或动态生成的物体。Unity的动态批处理机制会尽可能地将这些物体的绘制调用合并,但它的性能影响会比静态批处理略高,因为需要在运行时进行实时的批处理计算。
GPU实例化的优势与限制: - GPU实例化适用于大量相似但需要不同变换的物体,例如树木、草丛等。通过GPU实例化,可以将大量相似物体的渲染操作合并为一次,极大地减少了绘制调用的数量,提高了渲染性能。- 需要注意的是,GPU实例化对于不同材质或变换属性不同的物体并不适用。此外,过度使用GPU实例化也可能导致GPU资源的过度占用,因此在实际应用中需要权衡考虑。
UGUI如何优化DrawCall
- 合并画布:尽可能地降低Canvas的数量,如果UI可以放到同一个画布中,并且彼此之间不需要交互等,合并到同一个画布中可以减少绘制调用的次数。
- 使用图集:将UI元素的图像资源合并到纹理图集中,以减少绘制调用的数量。这样可以减少纹理切换和内存开销。
- 减少透明度:尽量避免使用半透明材质或透明效果,因为它们会增加额外的绘制调用。如果可能的话,尽量使用不透明的UI元素。
- 优化UI结构:优化UI的层次结构,尽量减少UI元素的嵌套和重叠。简化UI结构可以减少绘制调用的数量(例如,当前有两个Text,都没有与其他UI有嵌套,这样Unity渲染是Text不会打乱渲染批次,会把Text放到同一个批次处理。如果有嵌套和重叠渲染会被打断,打断的Text会单独一个批次处理)。
- 动静分离:将频繁更新和不更新坐标渲染的UI分割开,减小静态UI绘制频率。
- UGUI优化的进一步考虑:- 除了合并画布和使用图集外,优化UI的动态性也是一个重要的方面。例如,使用对象池技术可以避免频繁创建和销毁UI元素,减少了性能开销。- 另外,避免使用过多的UI特效和动画效果也可以提高性能。尤其是在移动设备上,过多的UI特效可能导致性能下降和电池消耗增加。
版权归原作者 许兵兵 所有, 如有侵权,请联系我们删除。