Skip to content

Stage05|Performance ​

Lesson059|GPU 性能:DrawCall、Overdraw、带宽和 Fill Rate ​

Tags: #Creator2.x #Stage05 #GPU #DrawCall #Overdraw #FillRateDifficulty: ⭐⭐⭐⭐☆


真实问题:CPU 只有 6 ms,帧率为什么仍上不去 ​

目标 60 FPS,CPU 主线程每帧约 6 ms,实际却只有 35 FPS。关闭全屏后处理或将渲染分辨率减半后,帧率明显恢复。

这是一组强 GPU 证据:

text
CPU 有余量
降低像素工作量显著改善
→ 优先检查 GPU / Fill Rate / 带宽

一、本课目标 ​

本课把 Renderer 阶段的知识转成性能判断:

  • DrawCall 为什么会影响 CPU 和 GPU。
  • Overdraw、Fill Rate 和分辨率的关系。
  • 为什么透明 UI 常常比不透明背景更贵。
  • 如何区分 GPU 瓶颈和 CPU 提交瓶颈。

二、GPU 每帧要做什么 ​

简化链路:

text
CPU 提交绘制命令
→ Vertex Shader 处理顶点
→ 光栅化生成片元
→ Fragment Shader 计算颜色
→ Blend / Depth / Stencil
→ 写入 Render Target

GPU 成本取决于顶点数量、片元数量、Shader 复杂度、纹理访问和状态切换。


三、DrawCall 的含义 ​

一次 DrawCall 可以粗略理解为 CPU 向 GPU 提交一组绘制命令。它通常包含:

text
材质和 Shader
纹理
Render State
顶点和索引缓冲
绘制数量

DrawCall 多会增加提交和状态切换,但低 DrawCall 不代表 GPU 一定轻松。


四、Overdraw 和 Fill Rate ​

如果同一个屏幕像素被多层透明图片覆盖:

text
背景绘制一次
半透明面板一次
阴影一次
图标一次
文字一次

这个像素可能被处理多次,这就是 Overdraw。Fill Rate 表示 GPU 处理片元和填充屏幕的能力。

常见高风险区域:

  • 大面积半透明面板。
  • 全屏特效。
  • 粒子。
  • 多层阴影和模糊。
  • 大尺寸图片缩放显示。

五、分辨率为什么影响 GPU ​

分辨率越高,片元数量越多:

text
1920 × 1080 ≈ 207 万像素
1280 × 720 ≈ 92 万像素

相同 UI 层数下,高分辨率可能需要处理更多片元。验证 GPU 瓶颈时,降低分辨率或关闭特效是有价值的对照实验。


六、Shader 和纹理带宽 ​

Fragment Shader 中的复杂计算、分支和多次纹理采样都会增加成本。纹理尺寸、格式和访问次数还会影响带宽:

text
更大纹理
更多采样
更高分辨率
→ 更高带宽压力

优化 Shader 时不要只减少代码行数,应观察实际片元执行和目标设备表现。


七、案例:DrawCall 不高但仍然卡 ​

场景可能只有 20 个 DrawCall,但每个都是:

  • 全屏半透明。
  • 多次纹理采样。
  • 复杂 Fragment Shader。
  • 高分辨率 Render Target。

这时瓶颈可能在片元和带宽,而不是 DrawCall 数量。应该检查 Overdraw、GPU 时间和分辨率对照,而不是继续只压 DrawCall。


八、CPU/GPU 瓶颈的对照实验 ​

text
降低分辨率后明显变快 → GPU 可能是瓶颈
关闭半透明特效后明显变快 → Overdraw 可能是瓶颈
减少脚本后变快、分辨率无影响 → CPU 可能是瓶颈
DrawCall 降低但帧时间不变 → 主要瓶颈可能不在提交

对照实验一次只改一个变量,才能解释结果。


九、常见误区 ​

误区一:DrawCall 越少越好 ​

需要结合 GPU 时间、Overdraw、Shader 和分辨率判断。

误区二:所有透明图片都必须删除 ​

应优先减少覆盖面积、层数和不必要的全屏区域。

误区三:降低图片尺寸一定解决 Fill Rate ​

Fill Rate 主要与片元数量和覆盖范围有关,纹理尺寸还涉及带宽和显存。

误区四:开发机 GPU 时间低,目标手机也一定低 ​

GPU 架构、带宽和驱动差异很大,必须在目标设备验证。


十、练习与答案 ​

  1. DrawCall 主要增加哪两类成本?
  2. Overdraw 为什么会让透明 UI 变贵?
  3. 如何用分辨率做 GPU 瓶颈对照实验?
  4. DrawCall 很低但仍卡,应该检查什么?

答案:

  1. CPU 提交/状态管理成本和 GPU 绘制批次成本。
  2. 同一片元被多次处理和混合。
  3. 只改变渲染分辨率,比较 GPU Frame Time 和总帧时间。
  4. Overdraw、Shader、纹理带宽、分辨率和同步等待。

判断 GPU 瓶颈的对照实验 ​

在不改变业务逻辑的前提下:

降低分辨率 ​

若帧时间显著下降,Fragment/带宽嫌疑上升。

关闭全屏透明层和后处理 ​

若改善,检查 Overdraw、采样和 RenderTexture。

用简单 Material 替换复杂效果 ​

若改善,Shader/纹理采样嫌疑上升。

保持画面但减少 DrawCall ​

若 CPU 改善而 GPU变化小,瓶颈可能在提交。

单个实验不是绝对证明,组合结果形成证据链。

Creator 2.4.x 实验:CPU 与 GPU 两组压力 ​

GpuEvidenceProbe.ts ​

ts
const { ccclass, property } = cc._decorator;

@ccclass
export default class GpuEvidenceProbe extends cc.Component {
    @property(cc.Node)
    overdraw: cc.Node = null;

    @property(cc.Node)
    manySmallNodes: cc.Node = null;

    toggleOverdraw() {
        this.overdraw.active = !this.overdraw.active;
    }

    toggleManyNodes() {
        this.manySmallNodes.active =
            !this.manySmallNodes.active;
    }

    scaleOverdraw(value: number) {
        this.overdraw.scale = value;
    }
}

Overdraw 组使用少量全屏透明层;ManySmallNodes 使用大量小节点但控制覆盖面积。

记录 ​

状态CPUGPU/总帧DrawCall覆盖面积
基线实测实测实测小
大量小节点实测实测实测小
全屏透明层实测实测实测大
透明层缩半实测实测实测约 1/4

目标是区分提交/脚本与像素阶段,而非得出跨设备固定数值。

带宽问题不只来自大 Texture ​

GPU 带宽包括:

  • 纹理读取;
  • FrameBuffer 写入;
  • Blend 读取目标颜色再写回;
  • 多 Pass RenderTexture 读写;
  • 高精度格式;
  • MSAA/深度模板;
  • CPU→GPU 动态数据上传。

一个低算术复杂度 Shader 也可能因为多次大纹理采样而带宽受限。

真实项目故障:RenderTexture 特效在 2K 屏幕翻倍变慢 ​

效果使用全分辨率两个中间 RenderTexture 和三次全屏 Pass。分辨率提升后像素数不是线性按宽度增长,而是宽×高共同增长。

优化:

  • 中间纹理降采样;
  • 合并可合并 Pass;
  • 降低格式精度;
  • 缩小效果区域;
  • 静态内容按需刷新;
  • 低端档关闭。

验收必须在不同 GPU 和分辨率测试,不能用开发机独立显卡代替移动设备。

GPU 故障诊断 ​

DrawCall 高但 GPU 不高 ​

可能 CPU/驱动提交瓶颈,先看 CPU;合批仍可能有收益。

DrawCall 低但 GPU 高 ​

看覆盖、Shader、纹理带宽、RenderTexture、分辨率和粒子。

降分辨率无改善 ​

像素瓶颈证据变弱,检查 CPU、同步、顶点、DrawCall 或实验设置是否真改变渲染分辨率。

版本边界与练习答案 ​

Creator 内置 Profiler 对 GPU 的可见度有限,Web/Android/iOS 应结合对应 GPU Frame 工具。不同图形后端行为不完全一致。

  1. 为什么分辨率减半实验有价值? 宽高各减半可显著降低片元与 RenderTarget 像素量,隔离像素成本。
  2. DrawCall 是 CPU 还是 GPU 指标? 它同时关联提交和 GPU 工作入口,但数量本身更常用于判断 CPU/状态批次,不能代表 GPU 总成本。
  3. Blend 为什么消耗带宽? 通常需要读取目标颜色、计算混合并写回。
  4. 如何证明 Shader 是主因? 在相同几何/覆盖下替换简化 Shader,结合 GPU 帧时间和平台 Frame Capture。

十一、本课总结 ​

text
DrawCall、Overdraw、Fill Rate、Shader 和带宽是不同维度。
GPU 优化必须结合实际 GPU 时间和目标设备。

十二、下一课预告 ​

text
Lesson060|Texture Memory:图片为什么最容易吃掉内存?