U3D手游MMOARPG大场景优化实录

发表于2016-11-03
评论0 2.9k浏览
背景介绍:
  ARPG项目需要做比较大的野外场景(400 * 400)+ ,如果按照最简单的场景做法就是把整个场景做成一个Prefab,然后动态加载以后进行一次静态批合。但是对于这种大场景是走不通的,因为运行时的静态批合会产生合并后的一堆Mesh,占用很大块内存在PC上简单测试都有100M+。如果不进行静态批合的话,Drawcall又会多得离谱。所以就需要针对项目本身的一个场景优化,而且这套方案也在实际的运营当中不断的做了一些调整。

优化方案:
  基于格子把场景切块,在移动的时候对附近的格子进行动态加载和释放。

 

  譬如人往右下方格子移动,黄色区域是需要加载的区域,灰色区域是需要卸载的区域

 

  当然这也需要根据摄像机的所在的位置跟角度来计算出来该显示格子区域。这里就不赘述这方面了。
  基于这个大方案前提,针对性的做了以下的一些优化。

优化步骤一:美术规格
  对于美术的同学只有一个原则:材质越少越好,贴图越小越好,越少越好,模型面数越低越好,透贴越少越好。(估计美术同学看到这里都会暴走)
  基于这个原则,我们会把一些场景使用的贴图合并成一张大图,从而减少材质和贴图的数量,最大的贴图大小是2048*2048。但是对于四方连续的贴图(大部分是地表贴图或者墙面贴图等)就没有任何办法了,只能单独出来。


优化步骤二:划分场景物件到各个区域,并且进行Mesh合并生成对应区域Prefab
  由于美术制作场景时都是很多极其细碎的物件,把场景物件划分到对应的格子区域。我们就在想是选用运行时根据区域变化后来进行静态批合呢?还是为了省内存而直接不批合呢?经过实测,前者会在运行时静态批合的时候产生卡顿,而且也会占用大块内存,而后者Drawcall数量也高得惊人,动态批合并没有什么作用。
  所以就萌生出一种的方案,把格子区域内相同材质的Mesh进行合并,把美术制作完的场景通过程序手段进行物件划分合并并且生成新的场景。实施了这个方案以后发现Drawcall大大的降低,内存也还能接受,唯一的缺点就是包体会变大,原因是譬如同一颗树,在场景内有100个,但是他只有一个Mesh,但当跟其他Mesh合并了以后,等于产生了多份。这里使用到的主要就是Mesh类中的CombineMeshes这个接口。

优化步骤三:大场景的光照贴图
  对于这块其实我们也没有特别好的方法,主要是Unity5这个光照烘焙出了各种奇奇怪怪的问题,而且烘焙速度奇慢无比。我们整个大场景都烘焙一张2048*2048的大图,对于大场景来看的话,其实影子的精度是大大够的,但是也只能取舍一下。其实后面我想更好的做法其实是按划分好的区域来去烘焙光图,这样我们也能动态的去根据我们区域加载不同的光图,只是一些区域衔接的地方处理可能要特别注意。
  回归到我们这个方案本身。由于美术制作场景是以细碎的物件制作并且烘焙完光图来给程序使用的。而程序又重新根据区域划分了物件,最要命的还合并了Mesh,这意味着我们要给这个合并后的mesh重新计算光照信息。我们用了比较淫荡的方法,直接修改合并后Mesh的UV2信息为经过计算的光照信息,而MeshRenderer的lightmapScaleOffset永远为0,lightmapTiling永远为1

 

优化步骤四:内存!内存!内存!
  在项目上线测试了一段时间以后,我们还是发现场景的内存占有有点高,我们又着手去优化内存。内存大头肯定就是在合并的Mesh身上。
  一、在区域释放的时候主动调用Resource.UnloadAsset,对Mesh资源进行及时的释放,而并没有通过Resource.UnloadUnused来进行释放。
  二、除了常规的一些设置相关的修改以外,后面发现我们合并出来的Mesh其实有很多的信息是没有用处的,譬如切线,法线,顶点颜色,uv3,uv4等等(当然这要根据实际项目情况来去处理,有需要的还是地保留)。这么一来所有的Mesh占用内存以及文件大小都变小了不少,感觉非常畅快。但感觉还没有到达极限。
  三、针对一些较大的Mesh我们采取了终极手段,裁面!这里不得不说下我们使用过三个裁面插件SimpleLOD,Cruncher, Simplygon。我们把这三大插件都集成到了Unity中去了(千万别问我通过什么手段,=。=)最后发现Simplygon实在是太强大了。因为前面两个都会裁的漏面了,而Simplygon则可以通过设置顶点权重等高级算法裁面(我也不懂)。后面写了一个类似光线照射顶点来生成权重并且交由Simplygon来进行裁面。这样下来内存也抠了不少。
  四、除此以外,我们还把场景使用的图全都压缩一半,譬如2048变1024,1024变512等,然后在高端机型运行时进行材质图片的替换,这样确保了低端机型也能跑得流畅,高端机型也有高清无码的效果。
  洋洋洒洒写了那么多,图很少,字很多,码农文字能力一般,望大家见谅,如有错误望指出,如想深入了解探讨可加Q:65506466。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引