解释Quad Overdraw与Fragment Quad利用率

解读

国内 Unity 面试中,面试官抛出这对概念,通常想一次性验证三件事:

  1. 你是否真的在 移动平台 GPU 带宽瓶颈 上踩过坑;
  2. 能否把 GPU 硬件 2×2 像素四元组 的运作机制讲清楚;
  3. 能否把“理论指标”翻译成“落地优化动作”,比如 降低片元着色器指令数、减少无效 Alpha Blend、合批+Z-Prepass 等。
    回答时先给定义,再给出量化公式,最后结合 Overdraw VisualizationFrameDebugger 讲调优套路,基本就能拿到高分。

知识点

  1. Quad(2×2 像素四元组):GPU 最小执行单元,任何三角形只要覆盖到 1 个像素,也必须一次性处理 4 个像素,目的是计算偏导数(ddx/ddy)。
  2. Quad Overdraw:同一帧中,同一 2×2 像素块被多次重复光栅化的次数,反映 片元冗余计算 的严重程度。
  3. Fragment Quad 利用率:单个 2×2 像素块里真正属于当前三角形的像素占比,公式 = 有效像素数 / 4。利用率越低,GPU 做无用功越多。
  4. 移动 SoC(Mali、Adreno、PowerVR)在 隐藏面消除(HSR) 之前就会生成 Quad,所以 Alpha Test、Alpha Blend、细小三角形 都会放大 Overdraw。
  5. Unity 内置工具:
    • Scene View → Overdraw 模式:只能看“层数”,不能看 Quad;
    • FrameDebugger → RenderPipeline 节点:可统计片元数;
    • Xcode/AGI/Snapdragon Profiler:可抓 Quad/Fragment 比值,直接算出利用率。
  6. 优化三板斧:
    • Z-Prepass 或 Opaque Only 渲染顺序,让 HSR 提前剔除;
    • GPU Instancing + SRP Batcher,减少小三角形数量;
    • 简化片元着色器(采样次数、ALU 指令),降低每个 Quad 的开销。

答案

Quad Overdraw 指同一 2×2 像素四元组在一帧中被多次光栅化的现象;Fragment Quad 利用率指该四元组内真正属于当前三角形的像素占比,公式为 有效像素 ÷ 4
在 Unity 移动项目中,Quad Overdraw 过高会直接放大 片元着色器带宽与算力消耗,典型表现是 GPU 时间高但顶点数低
量化排查时,先用 Scene 视图 Overdraw 做粗筛,再用 Xcode GPU CaptureAGI 抓帧,查看 Fragment/Quad 比值;若比值远大于 4,说明利用率低、Overdraw 严重。
落地优化:

  1. 透明材质 从 Alpha Test 改为 Alpha Blend 并排序到队列最后
  2. 复杂场景 先做 Z-Prepass,再用 “仅深度测试” 的着色器渲染一次,确保主 Pass 只绘制最终可见片元;
  3. 粒子、UI、草叶 这类小面片,合并成 GPU Instancing 批次,减少 2×2 边缘浪费;
  4. Shader 里用 clip() 时,尽量把 discard 区域集中,避免零散镂空造成 Quad 利用率暴跌。
    通过以上步骤,可把 Quad Overdraw 从 8× 降到 2× 以下,GPU 帧时间普遍能 缩短 30%–50%,在 中低端安卓机 上效果尤其明显。

拓展思考

  1. TBR/TBDR 架构 下,Quad Overdraw 与 Tile Memory Write 次数强相关;若 Quad 利用率低于 50%,即使 HSR 剔除了片元,Tile 仍要多次读写颜色缓冲,导致 系统内存带宽 暴涨。
  2. URP 的 Forward+ 渲染路径中,Unity 使用 Clustered Light List 提前裁剪光源,虽然减少了片元光照计算,但 细小三角形 仍会因 2×2 规则浪费 Quad;此时可引入 Mesh LOD + 动态曲面细分,让远处物体自动合并三角形,提升利用率。
  3. 对于 XR 应用,双眼渲染把 Overdraw 直接放大两倍,建议开启 Single-Pass Instanced 并做 Quad-Aligned 渲染,让同一 Quad 同时服务双眼,减少重复光栅化。