65.GPU影响因素之OverDraw

65.性能优化-GPU-影响因素-OverDraw


65.1 知识点

OverDraw 的基本概念

OverDraw(过度绘制、叠加绘制)指同一个屏幕像素在一帧中被重复绘制多次,上一次计算结果会被覆盖或叠加。

举例:

  1. 不透明物体
    后面被挡住的像素,仍然会运行片元着色器,只是最后写入时可能被深度测试(ZTest)丢弃。
  2. 半透明物体
    因为需要叠加混合(Alpha Blend),所以每个透明层都会真实运行片元着色器并参与混合。
  3. UI、粒子、屏幕特效
    当 UI 元素、粒子特效、屏幕后处理效果层层叠加时,OverDraw 现象更严重。

为什么 OverDraw 会影响性能

OverDraw 会影响性能,主要原因是会增加计算开销、消耗内存带宽、消耗填充率。

  1. 片元着色器重复执行
    不透明物体即便被遮挡,也需要跑一次片元着色器。半透明物体一定要逐层计算,无法依赖深度丢弃。
  2. 带宽浪费
    每次片元计算都会读取纹理并写入帧缓冲,增加显存带宽消耗。
  3. 填充率压力
    屏幕像素总数固定,但 OverDraw 会造成每个像素要算多次,GPU 的填充率预算会被快速耗尽。

以下场景很容易出现 OverDraw 现象:

  1. UI 界面
  2. 粒子特效
  3. 密集树叶

这些画面看起来挺简单,但其中隐藏的 OverDraw 会让 GPU 消耗暴涨。

关于 OverDraw 的优化思路

针对不透明物体优化

1. 从前向后渲染

Unity 内部处理不透明物体就已经采用了这种方案,会自动按相机到物体的距离,从近到远排序进行渲染。
也可以手动调整渲染队列或排序层,让对象先渲染,这样后面挡住的片元会被 Early-Z 丢弃,不跑片元 Shader。

Early-Z(提前深度测试):
在片元着色器运行之前,GPU 先把即将绘制的片元的深度和 Z-Buffer 比较。如果判定它在后面(被遮挡),直接丢弃,根本不跑片元 Shader,可以节省大量 GPU 开销。
当透明或半透明物体关闭深度写入等情况时,Early-Z 会失效。

2. 遮挡剔除(Occlusion Culling)

使用 Unity 提供的 Occlusion Culling,可避免完全不可见的物体进入渲染。

针对半透明物体优化

  1. 减少透明层数、面积
    UI 背景、HUD 尽量合并图层,少用大面积透明混合。
  2. Alpha Test 替代 Alpha Blend
    树叶、栅栏,用 Alpha Test(Clip)代替 Alpha Blend,让深度测试能提前丢弃片元。
  3. 排序优化
    透明物体按从远到近绘制,减少不必要的重复混合。
  4. 特殊替代方案
    粒子系统远处改用广告牌效果,降低粒子数量和透明叠加。

针对 UI 系统优化

1. 图集 + 批处理
减少 DrawCall,但也要避免大图集带来过多 OverDraw。

2. 减少叠层
UI 设计时避免多层全屏半透明面板。

3. RectMask2D / Stencil 替代全屏 Mask

用普通 Mask 相当于多了一层全屏绘制,浪费填充率。

  • 如果只需要矩形裁剪,使用 RectMask2D
    RectMask2D 是 Unity 提供的一个更轻量级的 UI Mask,它不是通过额外绘制 Mask 图层,而是用矩形裁剪(裁剪坐标系),不会产生额外的全屏 OverDraw,性能比普通 Mask 好很多。

  • 如果想要复杂形状裁剪,用 Stencil。
    Stencil Buffer(模板缓冲)是 GPU 提供的一种逐像素标记机制,可以在自定义 Shader 中利用它来实现。

4. UI Renderer 独立渲染
避免和 3D 场景互相叠加 OverDraw,相当于 UI 和场景用两个摄像机单独进行处理。


65.2 知识点代码

Lesson65_性能优化_GPU_影响因素_OverDraw.cs

public class Lesson65_性能优化_GPU_影响因素_OverDraw
{
    #region 知识点一 OverDraw的基本概念

    //OverDraw(过度绘制、叠加绘制) 指
    //同一个屏幕像素在一帧中被重复绘制多次
    //上一次计算结果会被覆盖或叠加

    //举例:
    //1.不透明物体
    //  后面被挡住的像素,仍然会运行片元着色器,只是最后写入时可能被深度测试(ZTest)丢弃

    //2.半透明物体
    //  因为需要 叠加混合 (Alpha Blend),所以每个透明层都会真实运行片元着色器并参与混合

    //3.UI、粒子、屏幕特效
    //  当UI元素、粒子特效、屏幕后处理效果层层叠加时,OverDraw现象更严重

    #endregion

    #region 知识点二 为什么OverDraw会影响性能

    //之所以OverDraw会影响性能
    //主要原因就是会增加计算开销,消耗内存带宽,消耗填充率

    //1.片元着色器重复执行
    //  不透明物体即便被遮挡,也需要跑一次片元着色器
    //  半透明物体一定要逐层计算,无法依赖深度丢弃

    //2.带宽浪费
    //  每次片元计算都会 读取纹理 并 写入帧缓冲
    //  增加显存带宽消耗

    //3.填充率压力
    //  屏幕像素总数固定,但 OverDraw 会造成 每个像素要算多次
    //  GPU 的填充率预算会被快速耗尽

    //在以下场景时,很容易出现OverDraw现象
    //1.UI界面
    //2.粒子特效
    //3.密集树叶
    //等等
    //这些画面看起来挺简单,但是其中隐藏的OverDraw会让GPU消耗暴涨

    #endregion

    #region 知识点三 关于OverDraw的优化思路

    //优化OverDraw的主要思路为:
    //1.针对不透明物体优化
    //  1-1.从前向后渲染,Unity内部处理不透明物体就已经采用了这种方案
    //      会自动按 相机到物体的距离,从近到远 排序进行渲染
    //      我们也可以手动调整渲染队列或排序层,让对象先渲染
    //      这样后面挡住的片元会被Early-Z 丢弃,不跑片元 Shader
    //      Early-Z (提前深度测试)
    //      在片元着色器运行之前,GPU 先把即将绘制的片元的深度和 Z-Buffer 比较
    //      如果判定它在后面(被遮挡),直接丢弃,根本不跑片元 Shader
    //      这样可以节省大量 GPU 开销
    //      当透明或半透明物体时,关闭深度写入等情况,它会失效
    //  1-2.遮挡剔除 (Occlusion Culling)
    //      使用Unity提供的Occlusion Culling,可避免完全不可见的物体进入渲染

    //2.针对半透明物体优化
    //  2-1.减少透明层数、面积
    //      UI 背景、HUD 尽量合并图层,少用大面积 透明混合
    //  2-2.Alpha Test 替代 Alpha Blend
    //      树叶、栅栏,用 Alpha Test(Clip)代替 Alpha Blend,让深度测试能提前丢弃片元
    //  2-3.排序优化
    //      透明物体按从远到近绘制,减少不必要的重复混合
    //  2-4.特殊替代方案
    //      粒子系统远处改用 广告牌效果,降低粒子数量和透明叠加

    //3.针对UI系统优化
    //  3-1.图集 + 批处理
    //      减少 DrawCall,但也要避免大图集带来过多 OverDraw
    //  3-2.减少叠层
    //      UI 设计时避免多层全屏半透明面板
    //  3-3.RectMask2D / Stencil 替代全屏 Mask
    //      用普通 Mask 相当于多了一层全屏绘制,浪费填充率
    //
    //      如果只需要矩形裁剪,使用RectMask2D
    //      RectMask2D 是 Unity 提供的一个 更轻量级的 UI Mask
    //      它不是通过额外绘制 Mask 图层,而是用 矩形裁剪(裁剪坐标系)
    //      不会产生额外的全屏 OverDraw,性能比普通 Mask 好很多
    //
    //      如果想要复杂形状裁剪,用 Stencil
    //      Stencil Buffer(模板缓冲)是GPU 提供的一种逐像素标记机制
    //      我们可以在自定义Shader中利用它来实现
    //  3-4.UI Renderer 独立渲染
    //      避免和 3D 场景互相叠加 OverDraw
    //      相当于UI和场景用两个摄像机单独进行处理

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏