UGUI优化 OverDraw

Unity基础:性能杀手Overdraw详解 - 知乎 (zhihu.com)

Overdraw介绍

    Overdraw是指屏幕上的某个像素在同一帧的时间内被绘制了多次。

3.2 Overdraw影响什么

    过多Overdraw可能会引起GPU过载,影响动画的播放和界面响应速度。

3.3  降低Overdraw

    1.将Mask(自带两层Overdraw)替换为RectMask2D(自带一层Overdraw)

    2.全屏遮挡的情况,则为被遮挡的canvas添加CanvasGroup 组件,然后在被挡住时将其alpha值设为0,不参与绘制,没有 DrawCall也没有Overdraw,同时顶点也不会参与重绘。

    3.unity的文字显示中自带阴影组件shadow/Outline减少使用,自带overcall。

    4.UI摆放,减少UI的叠加效果。

    5.将不想显示的物体直接禁用,而不是将其透明度改为0,仍会产生overcall。
    

如何降低OverDraw

减少不透明OverDraw

与流行的游戏开发理念相反,渲染不透明的几何形状可能会导致大量OverDraw。

不透明几何产生的OverDraw相比透明几何产生的OverDraw开销更低,因为不透明渲染只是替换像素。透明渲染通常会与Alpha Blend一起使用,这对于移动设备来说有更加昂贵。

但是,不要低估不透明OverDraw产生的性能开销。浪费内存带宽的开销依然很昂贵。

Unity会尽最大努力从近到远渲染不透明元素。这就是说,我们首先渲染距离摄像机更近的元素,以便使用Z-Test剔除被遮挡的物体的像素。

该排序基于相机与每个对象的边界框中心之间的距离。

这种排序非常有利于GPU性能。

但是,在某些情况下,会导致渲染队列排序混乱,这会使OverDraw增加。

你知道是什么时候吗?

由于低效率的渲染策略,导致GPU OverDraw

事情是这样的:某些网格肯定是麻烦制造者。

假设你位于巨大的倒球面的中心,就像力场效应一样。

好吧,你到球面的距离是多少?

它接近于零,因为球体的中心恰好是摄影机所在的位置,这意味着将先渲染该球体,即使可能会在其前面绘制一些对象。这将导致OverDraw。

这就是为什么在Unity中应该把渲染天空盒放在渲染不透明几何图形之后的原因。首先渲染天空盒会产生大量OverDraw。

Unity Batching导致GPU OverDraw增加

我喜欢批处理。而且你也应该喜欢。

批处理可以帮助你我减少渲染线程的CPU负载,这在未经优化的游戏中通常是一个巨大的瓶颈(CPU瓶颈)。它能够将多个绘制调用合并在一起提交给GPU。

但是,合并绘制调用意味着Unity将不再能够对其按原有的顺序进行排序,因为现在已经合为一体。这可能会导致严重的OverDraw。

这在所有类型的批处理中都会发生:静态,动态和GPU Instance。通常发生的环境不是确定性的,这会使你的性能分析工作更加困难。

可悲的是,常见的解决方案是禁用麻烦对象的批处理(或者按区域手动来进行批合)。

另一种解决方案是通过将渲染队列更改为Geometry-1,Geometry + 1等来手动设置Unity渲染顺序。这几乎可以完全控制渲染顺序,但这带来了责任/风险(常见的是把地表、天空盒进行延后渲染)。使用Standard材质要求检查器处于调试模式

减少透明渲染的OverDraw

半透明对象是导致OverDraw最常见的元凶

由透明度引起的OverDraw对性能特别不利,因为渲染通常伴随Alpha Blend,这需要额外的读取和算术运算。

更糟糕的是,透明材质通常不会写入Z-buffer,因此最终会写入更多无法丢弃的像素。

你要做的是减少绘制的透明像素数量及其成本

  • 减少渲染的透明层的数量。
  • 减小透明几何图形所需的屏幕尺寸
  • 您可以按比例缩小透明对象的(屏幕)大小。
  • 尽最大可能从精灵中删除100%透明纹理像素。
  • 制作紧密的网格,以减少完全透明的区域。

Unity UI通常会导致OverDraw,因为系统仅支持全四方渲染。将可绘制的UI元素彼此堆叠非常容易。这些渲染为完整的四边形而不是紧密的网格。

但是,精灵渲染器支持绘图网格,这些网格可以更准确地表示精灵的不透明部分,以减少过度绘制。