关于 性能优化指标
前言
引擎和小游戏都有提供一个性能面板,给开发者们暴露了以下几个性能指标
# 一. Frame time
Frame time(ms)
每一帧的时间。
《RAIL模型》建议在 10 毫秒或更短的时间内制作动画中的每一帧。从技术上讲,每帧的最大预算为 16 毫秒(1000 毫秒/每秒 60 帧≈16 毫秒),但是浏览器需要大约 6 毫秒才能渲染每帧,因此建议每帧 10 毫秒或者更短。
# 二. Framerate
Framerate(FPS)
帧率, 也叫每秒传输帧数(FPS:Frames Per Second).
是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数;每秒钟帧数越多,所显示的动作就会越流畅,举个例子电影的帧频是 24,也就是说 1s 需要播放 24 张图片,但是实际上在游戏过程中一般人能接受的最低 FPS 约为 30Hz。
帧率也非越高越好,因为显卡处理能力=分辨率×刷新率,分辨率不变的情况下,帧频越高,GPU 处理的数据量也会激增,引起卡顿。
同理,分辨率也不是越高越好。在某些终端的性能面板下也会展示这三个相关的参数:
rt-fps
:实时帧率;ex-fps
:极限帧率:可以理解为在不受驱动帧率的限制下(大部分手机微 60fps);仅仅计算 js 运行耗时,可以达到的极限帧率min-fps
:最小帧率;
# 三. Draw call
CPU 和 GPU 是并行工作的,它们之间存在一个命令缓冲区。当 CPU 需要调用图形编程接口的时候,就会往命令缓冲区里面增加命令,当 GPU 完成上一次渲染命令的时候,就会继续从命令缓冲区中执行下一条命令,命令缓冲区里面的命令有很多种,而drawcall就是其中的一种。
CPU 在提交drawcall
的时候需要处理很多东西,比如一些数据、状态、命令等等。有些渲染卡顿问题就是因为 GPU 渲染速度比drawcall
的提交速度快,可能上一次渲染完了,CPU 还在计算drawcall
,所以drawcall的性能瓶颈在于 CPU。
优化 drawcall
最有效的方法: 合批渲染,就是把大量小的drawcall
合并成大的drawcall
,来减少drawcall的数量。
# 四. game logic
game logic的时间代表 update 中逻辑的耗时.
# 五. Renderer
Renderer的时间代表渲染的耗时 .
Frame time = Game Logic + Renderer
# 六. Tris、Verts
Tris
、Verts
是渲染的三角面数以及顶点数,在 webgl 中只有三种基本图元,分别是点、线段和三角形,无论多么复杂的模型本质上都是由这三个基本图元绘制而来的,无论形状多么怪异,它们的本质都是由一个个顶点组成,GPU 将这些点用三角图元绘制成一个个的微小平面,再把这些三角网格互相连接,就能绘制出各种复杂的物体了;
一般来说模型的顶点和三角形数越低,模型的复杂度就会越低,所以这两个参数在 3D 模型中比较有参考意义,设计师在输出 3D 模型的时候一般都会帮忙去合并一下网格。但是在大部分情况下,我们都会认为性能瓶颈在drawcall
上.
比如有两种情形,情景一是有 1000 个物体,每个物体的顶点数是 10,情景二是有 10 个物体,每个物体的顶点数是 1000,哪个情景的性能更好?
首先我们要明白 GPU 的渲染速度是非常快的,渲染 10 个顶点组成的三角图元和 1000 个顶点组成的三角图元通常没啥区别,所以这两种情形中产生drawcall
更少的情景二性能更好。当然如果你在 shader
里面对顶点做了一些特殊的处理,比如复杂的计算啥的,那就得权衡一下这两个指标的大小影响了。