#游戏unity-VR场景漫游#游戏中的优化(一)

基于之前制作项目的经历教训——没有报错的代码合在一起整体运行的时候就运行特别卡,深刻认识到了项目优化的重要性;VR游戏的流畅度是影响用户体验的一个很重要的因素,而且,三区的场景模型也是一个有很多面的模型,运行起来会相当占资源,为了解决运行卡顿的问题,就必须在代码以及系统的搭建中时刻注意对资源的合理使用。
所以,我进行了关于游戏优化的相关学习,并将好的博客内容进行了整理。


影响性能的因素

对于一个游戏来说,有两种主要的计算资源:CPU和GPU。它们会互相合作,来让我们的游戏可以在预期的帧率和分辨率下工作。CPU负责其中的帧率,GPU主要负责分辨率相关的一些东西。

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

CPU
●过多的Draw Calls
●复杂的脚本或者物理模拟

顶点处理
●过多的顶点
●过多的逐顶点计算

像素(Fragment)处理
●过多的fragment,overdraws
●过多的逐像素计算

带宽
●尺寸很大且未压缩的纹理
●分辨率过高的framebuffer

对于CPU来说,限制它的主要是游戏中的Draw Calls。那么什么是Draw Call呢?如果你学过OpenGL,那么你一定还记得在每次绘图前,我们都需要先准备好顶点数据(位置、法线、颜色、纹理坐标等),然后调用一系列API把它们放到GPU可以访问到的指定位置,最后,我们需要调用_glDraw*命令,来告诉GPU,而调用_glDraw*命令的时候,就是一次Draw Call。上面说到过,我们想要绘制图像时,就一定需要调用Draw Call。例如,一个场景里有水有树,我们渲染水的时候使用的是一个material以及一个shader,但渲染树的时候就需要一个完全不同的material和shader,那么就需要CPU重新准备顶点数据、重新设置shader,而这种工作实际是非常耗时的。如果场景中,每一个物体都使用不同的material、不同的纹理,那么就会产生太多Draw Call,影响帧率,游戏性能就会下降。当然,这里说得很简单,更详细的请自行谷歌。其他CPU的性能瓶颈还有物理、布料模拟、粒子模拟等,都是计算量很大的操作。

而对于GPU来说,它负责整个渲染流水线。它会从处理CPU传递过来的模型数据开始,进行Vertex Shader、Fragment Shader等一系列工作,最后输出屏幕上的每个像素。因此它的性能瓶颈可能和需要处理的顶点数目的、屏幕分辨率、显存等因素有关。总体包含了顶点和像素两方面的性能瓶颈。在像素处理中,最常见的性能瓶颈之一是overdraw。Overdraw指的是,我们可能对屏幕上的像素绘制了多次。

优化技术

  • 顶点优化
    • 优化几何体
    • 使用LOD技术
    • 使用遮挡剔除技术
  • 像素优化
    • 控制绘制顺序
    • 警惕透明物体
    • 减少实时光照
  • CPU优化
    • 减少Draw Calls
  • 带宽优化
    • 减少纹理大小
    • 利用缩放
      以下进行详细介绍。

顶点优化

优化几何体

在建模时,要有意识的减少三角面片的数量
三维软件里更多地是站在我们人类的角度理解顶点的,即我们看见的一个点就是一个。而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来说,它本质上只关心有多少个顶点。因此,尽可能减少顶点的数目其实才是我们真正对需要关心的事情。因此,最后一条优化建议就是:移除不必要的Hard Edge以及纹理衔接,即避免Smoothing splits和UV splits。

LOD技术

LOD是对模型建立了一个模型金字塔,根据摄像机距离对象的远近,选择使用不同精度的模型。它的好处是可以在适当的时候大量减少需要绘制的顶点数目。它的缺点同样是需要占用更多的内存,而且如果没有调整好距离的话,可能会造成模拟的突变。一般是在解决运行时流畅度的问题,采用的是空间换时间的方式。

  1. 准备3组模型,高精度模型,中精度模型,和低精度模型,并按照复杂程度自高向低的为模型命名
    这里写图片描述

  2. 定义一个空对象,添加LODGroup组件,如图所示:
    这里写图片描述

  3. 分别将刚刚准备好的三种不同精度的模型,拖拽到空对象的LODGroup组件的各个级别上。首先给LOD组件的“LOD 0”(LOD 0 表示摄像机最近距离显示)添加对应的模型。(LOD 0 对应高精度模型,然后拖拽到Add上面即可)如图所示:
    这里写图片描述

  4. 在LOD组件添加模型的过程中会弹出如图所示的提示信息,表明要把添加的模型作为LODGroup组件所属对象的子物体,单击”Yes,Reparent”按钮即可

  5. 为使构造的LOD游戏对象显示得更加自然,需要把LOD下的三个子物体进行”对齐“处理。(将其相对于父物体的坐标置为0)
    这里写图片描述
    最后在Scenes视图中,拖动摄像机分别近距离与远距离观察模型的变化即可。

使用遮挡剔除技术(Occlusion culling)

附上不错的教程 基础

接下来的内容,会在下一篇中进行整理。

猜你喜欢

转载自blog.csdn.net/zys91011_muse/article/details/79940262