写在前面
这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Unity Cookie中的一个教程。还有很多其他参考在下面的链接中。
这篇文章旨在简要地说明一下常见的各种优化策略。不过对每个基础有非常深入地讲解,需要的童鞋可以自行去相关资料。
影响性能的因素
首先,我们得了解,影响游戏性能的因素哪些,才能对症下药。对于一个游戏来说,有两种主要的计算资源:CPU和GPU。它们会互相合作,来让我们的游戏可以在预期的帧率和分辨率下工作。CPU负责其中的帧率,GPU主要负责分辨率相关的一些东西。
总结起来,主要的性能瓶颈在于:
- CPU
-
- 过多的Draw Calls
- 复杂的脚本或者物理模拟
- 过多的Draw Calls
- 顶点处理
-
- 过多的顶点
- 过多的逐顶点计算
- 过多的顶点
- 像素(Fragment)处理
-
- 过多的fragment,overdraws
- 过多的逐像素计算
- 过多的fragment,overdraws
- 带宽
-
- 尺寸很大且未压缩的纹理
- 分辨率过高的framebuffer
- 尺寸很大且未压缩的纹理
对于CPU来说,限制它的主要是游戏中的Draw Calls。那么什么是Draw Call呢?如果你学过OpenGL,那么你一定还记得在每次绘图前,我们都需要先准备好顶点数据(位置、法线、颜色、纹理坐标等),然后调用一系列API把它们放到GPU可以访问到的指定位置,最后,我们需要调用_glDraw*命令,来告诉GPU,“嘿,我把东西都准备好了,你个懒家伙赶紧出来干活(渲染)吧!”。而调用_glDraw*命令的时候,就是一次Draw Call。那么为什么Draw Call会成为性能瓶颈呢(而且是CPU的瓶颈)?上面说到过,我们想要绘制图像时,就一定需要调用Draw Call。例如,一个场景里有水有树,我们渲染水的时候使用的是一个material以及一个shader,但渲染树的时候就需要一个完全不同的material和shader,那么就需要CPU重新准备顶点数据、重新设置shader,而这种工作实际是非常耗时的。如果场景中,每一个物体都使用不同的material、不同的纹理,那么就会产生太多Draw Call,影响帧率,游戏性能就会下降。当然,这里说得很简单,更详细的请自行谷歌。其他CPU的性能瓶颈还有物理、布料模拟、粒子模拟等,都是计算量很大的操作。
而对于GPU来说,它负责整个渲染流水线。它会从处理CPU传递过来的模型数据开始,进行Vertex Shader、Fragment Shader等一系列工作,最后输出屏幕上的每个像素。因此它的性能瓶颈可能和需要处理的顶点数目的、屏幕分辨率、显存等因素有关。总体包含了顶点和像素两方面的性能瓶颈。在像素处理中,最常见的性能瓶颈之一是overdraw。Overdraw指的是,我们可能对屏幕上的像素绘制了多次。
了解了上面基本的内容后,下面涉及到的优化技术有:
- 顶点优化
-
- 优化几何体
- 使用LOD(Level of detail)技术
- 使用遮挡剔除(Occlusion culling)技术
- 优化几何体
- 像素优化
-
- 控制绘制顺序
- 警惕透明物体
- 减少实时光照
- 控制绘制顺序
- CPU优化
-
- 减少Draw Calls
- 减少Draw Calls
- 带宽优化
-
- 减少纹理大小
- 利用缩放
- 减少纹理大小