纳金网

标题: Unity中的优化技术(一) [打印本页]

作者: tianhett    时间: 2015-2-15 16:43
标题: Unity中的优化技术(一)
写在前面
这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Unity Cookie中的一个教程。还有很多其他参考在下面的链接中。

这篇文章旨在简要地说明一下常见的各种优化策略。不过对每个基础有非常深入地讲解,需要的童鞋可以自行去相关资料。


[size=11.8181819915771px][size=13.63636302948px]还有一些我认为非常好的参考文章:
[size=11.8181819915771px][size=13.63636302948px]

[size=11.8181819915771px][size=13.63636302948px]Performance Optimization for Mobile Devices

[size=11.8181819915771px]

[size=11.8181819915771px]4 Ways To Increase Performance of your Unity Game

Unite 2013 Optimizing Unity Games for Mobile Platforms


Unity optimization Tips




影响性能的因素
首先,我们得了解,影响游戏性能的因素哪些,才能对症下药。对于一个游戏来说,有两种主要的计算资源:CPU和GPU。它们会互相合作,来让我们的游戏可以在预期的帧率和分辨率下工作。CPU负责其中的帧率,GPU主要负责分辨率相关的一些东西。

总结起来,主要的性能瓶颈在于:


对于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指的是,我们可能对屏幕上的像素绘制了多次。

了解了上面基本的内容后,下面涉及到的优化技术有:


首先是顶点优化的部分。


顶点优化


优化几何体
这一步主要是为了针对性能瓶颈中的”顶点处理“一项。这里的几何体就是指组成场景中对象的网格结构。

3D游戏制作都由模型制作开始。而在建模时,有一条我们需要记住:尽可能减少模型中三角形的数目,一些对于模型没有影响、或是肉眼非常难察觉到区别的顶点都要尽可能去掉。例如在下面左图中,正方体内部很多顶点都是不需要的,而把这个模型导入到Unity里就会是右面的情景:



在Game视图下,我们可以查看场景中的三角形数目和顶点数目:



可以看到一个简单的正方形就产生了这么多顶点,这是我们不希望看到的。

同时,尽可能重用顶点。在很多三维建模软件中,都有相应的优化选项,可以自动优化网格结构。最后优化后,一个正方体可能只剩下8个顶点:



它对应的顶点数和三角形数目如下:




等等!这里,你可能要问了,为什么顶点数是24,而不是8呢?美术朋友们经常会遇到这样的问题,就是建模软件里显示的模型顶点数和Unity中的不一样,通常Unity会多很多。谁才是对的呢?其实,它们是站在不同的角度上计算的,都有各自的道理,但我们真正应该关心的是Unity里的数目。

我们这里简单解释一下。三维软件里更多地是站在我们人类的角度理解顶点的,即我们看见的一个点就是一个。而Unity是站在GPU的角度上,去计算顶点数目的。而在GPU看来,看起来是一个的很有可能它要分开处理,从而就产生了额外的顶点。这种将顶点一分为多的原因,主要有两个:一个是UV splits,一个是Smoothing splits。而它们的本质其实都是因为对于GPU来说,顶点的每一个属性和顶点之间必须是一对一的关系。UV splits的产生,是因为建模时,一个顶点的UV坐标有多个。例如之前的立方体的例子,由于每个面都有共同的顶点,因此在不同面上,同一个顶点的UV坐标可能发生改变。这对于GPU来说,这是不可理解的,因此它必须把这个顶点拆分成两个具有不同UV坐标的定顶点,它才甘心。而Smoothing splits的产生也是类似的,不同的时,这次一个顶点可能会对应多个法线信息或切线信息。这通常是因为我们要决定一个边是一条Hard Edge还是Smooth Edge。Hard Edge通常是下面这样的效果(注意中间的折痕部分):



而如果观察它的顶点法线,就会发现,折痕处每个顶点其实包含了两个不同的法线。因此,对于GPU来说,它同样无法理解这样的事情,因此会把顶点一分为二。而相反,Smooth Edge则是下面的情况:



对于GPU来说,它本质上只关心有多少个顶点。因此,尽可能减少顶点的数目其实才是我们真正对需要关心的事情。因此,最后一条优化建议就是:移除不必要的[size=13.63636302948px]Hard Edge以及纹理衔接,即避免Smoothing splits和UV splits






欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5