3.1 帧率预算与发热治理:先立账本,再谈优化

核心结论

移动端性能不是"尽量快",而是"稳定地达到目标帧率且不烫手"。这需要一本预算账本:每帧 16.6ms(60 帧)或 33.3ms(30 帧)的时间,CPU/GPU/渲染线程各花多少,上限写死,超了就砍。

预算账本(中端机 60 帧目标示例)

线程/类别 预算(ms) 常驻内容
游戏线程(Game) 5.0 Gameplay 逻辑、AI、碰撞
渲染线程(Render) 5.0 DrawCall 组织、可视性
GPU(前向渲染) 6.0 着色、光照、后处理
合计 16.0 留 0.6ms 给系统波动

30 帧目标则预算翻倍到 33.3ms,发热显著缓解。我的建议:中端机定 30 帧,高端机定 60 帧,用设备描述文件区分(见第一章)。

发热:被忽视的"第三条命"

手机没有风扇,持续高负载会触发系统降频——帧率突然掉到个位数。发热治理的核心指标:

  • GPU 频率漂移:用 stat gpu 或平台工具看频率是否被压。
  • 机身温度:真机玩 20 分钟摸温度(专业点用热成像或内置温度传感器)。
  • 电量:每小时掉电 >20% 的游戏活不长。

降发热三板斧

  1. 降目标帧率:30 帧足够时不要 60 帧——发热与帧率不是线性的,而是近平方关系(电压随频率涨)。
  2. 降分辨率:见 0302,渲染分辨率是 GPU 负载的第一杠杆。
  3. 场景做"近处精细、远处省":LOD+雾遮挡,GPU 平均负载能降一半。

账本怎么落到项目里

1. 性能基线关卡

做一张"性能关卡":把游戏最重的场景(满怪、全特效、大地图)做成可重复运行的关卡。每次大版本提交前跑一遍,记录三线程时间。

2. 自动化记录

用 exec 或者命令行跑性能关卡并 dump stat unit 输出到文件:

# 大致流程(细节按项目)
-Game -ExecCmds="stat unit; stat gpu; ... dump"

把每个版本的数字贴到 wiki 表格里,帧率回归一眼可见。

3. 超预算处理规矩

情况 处理
渲染线程超 查 DrawCall(>2000 就高)、半透明粒子数
GPU 超 降 Screen %、砍后处理(见 0203)、减光照
游戏线程超 查 tick 的 Actor 数、AI 复杂度、作弊的蓝图逻辑

常见坑与解法

坑 1:编辑器里测的性能与真机差三倍

原因:编辑器本身(UI、调试视图)有开销;ES3.1/Vulkan 编译差异也是主因。

解法:所有性能结论必须来自真机的 Development/Shipping 包。编辑器数字只能看趋势。

坑 2:帧率在部分手机上忽高忽低

原因:系统温控降频(thermal throttling),尤其玩 10 分钟后。

解法:做"压力测试"(连续 30 分钟),不只测冷机性能;发热没治理前别宣传 60 帧。

坑 3:DrawCall 不明所以地高

解法:stat scenerendering 看 DrawCall 数;常驻元凶是"每件小物体一个材质实例"——用材质合批(同一材质多网格)与 Hierarchical LOD。

相关节点速查

  • 三线程时间:stat unit
  • GPU 时间:stat gpu
  • DrawCall:stat scenerendering
  • 冷启动到稳定发热:stat startfile / stopfile(会出详细 profile)

心得:我曾经在项目后期被"低帧率"追着打,每周都在救火。后来花一周做了账本+性能关卡+版本记录表,后面所有优化都有据可依,救火变成了"这周砍了 0.8ms 渲染"的例会。性能优化不是技术问题,是工程管理问题。