很多客户端性能问题看 Profiler 时 CPU 不高,draw call 也不夸张,但低端手机就是热、掉帧、耗电。这时要小心 GPU Overdraw。简单说,Overdraw 就是同一个屏幕像素被重复绘制太多次。UI 半透明遮罩、全屏特效、粒子烟雾、发光边框、背景模糊、多个弹窗叠在一起,都可能让 GPU 一遍遍刷同一块屏幕。
Overdraw 最容易被低估,因为单个元素看起来都很轻。一个半透明黑底不重,一个弹窗阴影不重,一个粒子烟雾不重,一个技能光圈也不重。但它们叠在一起,尤其在移动端,就会变成持续 GPU 压力。玩家感受到的不是“Overdraw 高”,而是发热、掉帧和电量掉得快。
一个大厅 UI 的真实问题
某个移动游戏大厅帧率一直不稳定。战斗场景反而能跑 50 多 FPS,大厅只有 35 到 40 FPS。大家最初怀疑大厅入口太多、红点太多、动画太多。后来打开 Overdraw 视图,发现主界面底下有三层全屏背景:动态背景、半透明氛围层、模糊遮罩;弹窗关闭后还有一个透明度为 0 的全屏遮罩没有禁用渲染;几个入口按钮的光效一直播放。CPU 没什么问题,GPU 却一直在重复刷屏。
修复后没有大改 UI,只做了几件事:合并背景层,关闭不可见遮罩渲染,入口光效按需播放,弹窗打开时暂停底层部分动效。大厅帧率明显稳定,耗电也下降。
UI Overdraw 的常见来源
UI 是 Overdraw 重灾区,因为它天然有很多透明图层。常见来源包括:
- 全屏半透明遮罩。
- 多层背景叠图。
- 大面积渐变和阴影。
- 透明按钮热区仍然渲染。
- 不可见节点只改 alpha,不禁用渲染。
- 滚动列表里大量半透明卡片。
- 弹窗套弹窗。
- 模糊背景和后处理。
UI 设计时要问一个问题:这个像素到底被画了几次?如果一个普通大厅界面从背景到最上层按钮要画五六次,低端机很难舒服。
特效 Overdraw 更隐蔽
粒子特效经常使用透明贴图,比如烟、火、光、雾、冲击波。它们看起来柔和,但对 GPU 很不友好。特别是大面积软粒子、全屏闪光、叠多层发光材质,很容易造成 Overdraw。
特效优化不是简单减少粒子数量,还要看屏幕覆盖面积。一个粒子数量少但铺满屏幕的烟雾,可能比几十个小火星更重。技能特效评审时,建议同时看普通视图和 Overdraw 视图。美术能看到哪一层最贵,优化就更有方向。
不可见不等于不渲染
很多 UI 和特效对象隐藏时只是 alpha 变成 0,或者移到屏幕外。某些引擎和组件仍然可能参与布局、更新或渲染。客户端要明确区分:
- 视觉透明。
- 不参与交互。
- 不参与布局。
- 不参与渲染。
- 完全禁用或回收。
如果一个全屏遮罩 alpha 为 0 但仍然被提交渲染,它对玩家不可见,却对 GPU 可见。开发包里最好有工具列出当前屏幕上所有活跃 Canvas、全屏图层和透明渲染对象。
合批不是万能解药
UI 性能讨论里常提到合批。合批能降低 CPU 提交成本,但不能消除 Overdraw。十个透明元素合成一个批次,GPU 仍然要画覆盖区域。不要因为 draw call 降了,就认为 UI 渲染已经轻了。
真正的 Overdraw 优化要减少绘制面积和层数:
- 合并静态背景。
- 裁剪不可见区域。
- 减少全屏半透明层。
- 关闭底层不可见动效。
- 列表只渲染可见项。
- 使用不透明图替代透明叠层。
- 对低画质关闭部分发光和阴影。
模糊和后处理要谨慎
弹窗背景模糊很常见,但移动端成本不低。实时模糊通常需要额外采样和全屏处理。如果每个弹窗都触发一次模糊,多个弹窗层叠时成本更高。
可以考虑:
- 用预模糊背景图替代实时模糊。
- 弹窗打开时截屏一次再模糊,而不是持续实时模糊。
- 低端机关闭模糊,改用半透明暗底。
- 避免弹窗套弹窗时重复模糊。
视觉高级感要服务体验。如果一个模糊效果让大厅发热掉帧,它就不是高级感,而是负担。
调试和验收方法
Overdraw 优化必须可视化。建议建立几个固定验收场景:
- 大厅待机。
- 商城弹窗。
- 背包列表。
- 多层活动弹窗。
- 战斗大招。
- 团战特效峰值。
- 结算奖励页。
每个场景用同一批设备记录 GPU 时间、温度趋势、帧时间和 Overdraw 截图。不要只看单次峰值,还要看持续 10 分钟后的变化。移动端 GPU 压力会和发热降频叠加,短测很容易误判。
上线前检查清单
- 是否检查过大厅、弹窗、战斗峰值的 Overdraw 视图。
- 全屏遮罩是否按需启用和禁用渲染。
- 不可见 UI 是否仍然参与渲染或布局。
- 粒子特效是否评估屏幕覆盖面积。
- 模糊和后处理是否有低端机降级。
- 滚动列表是否只渲染可见项。
- 弹窗打开时底层动效是否暂停。
- 性能报告是否同时看 CPU、GPU、温度和耗电。
结语
Overdraw 优化的核心是少画没必要的像素。它不总是体现在 draw call 上,也不一定能从 CPU Profiler 里直接看出来。客户端要把 UI 图层、透明特效、模糊、遮罩和低端机 GPU 压力放在一起看。屏幕上每一层雾、每一道光、每一个透明卡片,都在向 GPU 要预算。
进一步工程化落地
Overdraw 优化要避免变成一次性专项。建议给项目建立固定截图基线:大厅、商城、背包、活动弹窗、战斗峰值、结算页,每个版本用相同设备截一组 Overdraw 图和 GPU 时间。这样某个版本 UI 看起来没变,但多了一层全屏遮罩时,团队能立刻发现。
第二步是把 UI 资源规范写进验收。大面积背景能合并就合并,透明卡片不要无限叠,关闭的节点必须禁用渲染,弹窗遮罩不能套三层,低端档关闭实时模糊。规范最好配合工具,比如在开发包里列出当前全屏透明层数量、活跃 Canvas 数量、持续播放的 UI 动效数量。
第三步是让美术看到成本。只说“这个太重”没有说服力,给出 Overdraw 热力图、屏幕覆盖面积和低端机 GPU 时间,讨论就会具体很多。美术可以选择换贴图、减层数、缩小覆盖范围或做低配版本,而不是盲目删效果。
最后要把耗电和发热纳入验收。Overdraw 问题经常不是一秒钟掉帧,而是持续五分钟后 GPU 压力导致降频。短测只看 FPS 会漏掉这类问题,长时间大厅待机和团战压力测试更接近玩家真实体验。
团队协作与验收方式
Overdraw 优化不能变成客户端单方面要求“少做几层”。更好的协作方式是给 UI、特效和技术美术一套共同指标:目标机型、目标 GPU 时间、可接受层数、低配降级规则。大家讨论的不是主观好不好看,而是在预算内怎样保留重点表现。
验收时建议同时看三张图:正常画面、Overdraw 热力图、低端机帧时间曲线。正常画面说明视觉是否达标,热力图说明哪里重复绘制,帧时间说明玩家实际是否受影响。只看其中一个,都可能误判。
另外要关注运营活动带来的增量。活动弹窗、限时入口、节日背景和礼包光效经常临时加入主界面,如果每次都只看单个资源,很容易把大厅变重。发布前可以统计当前大厅活跃图层、透明层和循环动效数量,超过阈值就需要明确谁来降级或关闭。
排查指标与复盘模板
这类系统上线后,建议保留一份简单复盘模板:问题发生的版本、命中的资源和配置、玩家操作路径、最近一次状态变化、是否有异常日志、是否可回放、最终根因属于规则、表现、资源、网络还是工具缺失。复盘不要只写“已修复”,还要写“下次如何提前发现”。如果是事件没解绑,就补事件订阅检查;如果是配置引用错误,就补构建校验;如果是低端机长测才出现,就补自动长测场景。
指标也要持续观察。实体数量、对象池峰值、未释放资源、事件订阅数、UI 绑定数、重连恢复耗时、异常降级次数,都可以成为开发包或灰度包里的诊断指标。它们不需要全部上报到正式环境,但团队要有办法在问题出现时快速查看。
真正有效的工程改进,往往不是修一次 Bug,而是把这次 Bug 变成一个检查点、一个自动测试、一个调试面板字段或一个构建期错误。这样文章里讲的经验才不会只停留在经验,而会变成项目的一部分。
结尾补充:低配不是简单关特效
Overdraw 的低配策略要保护信息层级。危险范围、按钮状态、关键技能提示不能随便关;可以关的是装饰光、背景动态、额外阴影和氛围层。低配不是把画面砍到难看,而是在性能预算内保留玩家判断所需的信息。
最小验收标准还包括低端机大厅待机十分钟,确认帧时间和温度趋势没有持续恶化。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。