美文网首页
Unity的Mesh合并(0)

Unity的Mesh合并(0)

作者: DarkKnightRedoc | 来源:发表于2018-02-04 15:10 被阅读0次

    前言

    unity引擎中渲染代价的指标是场景中网格(Mesh)的数量,对显卡来说渲染一个100面的物体和渲染一个1500面的物体几乎是等价的,于是当多个物体的材质(Shader)相同时,可以把他们的网格合并起来,然后共用一个材料(Material)来降低渲染的成本,达成优化游戏体验的效果。

    这里我们把对材料的共用模糊化了,其实这也是一个复杂的过程,后文中会详细描述其原理和算法。


    什么样的物体可以合并?

    场景中有那么多物体,在进行合并之前,我们需要先确定哪些物体是可以合并在一起的?

    1.shader相同的物体才可以合并

    物体属性面板

    观察物体的属性面板,我们发现物体可能有不同的材料,这些材料会有不同的shader。shader是也是使用编程语言编写的由gpu处理的,不同的shader渲染出的效果是不一样的。因为我们合并起来的物体的网格是一个合并的网格,使用的是合并的材料,每个材料只能有一个shader属性,这也就限制了我们要合并的物体的材料的shader必须要相同。

    合并的物体 合并物体的网格 合并物体的材料

    2.要合并的物体需要处于一定范围内

    多个物体合并了之后,成为一个物体,若这个物体的mesh分布在场景中的各个地方,无疑是对资源的一个浪费。极端地来说,若我们将一万个物体合并成了一个,摄像机所看到了这一万个之中的一个,其他九千九百九十九个虽然对玩家不可见,但因为是同一个物体,所以也渲染了出来,这样的资源浪费是无必要的。

    于是我们在合并之前会将场景划分为多个正方体,每个正方体内的物体才能互相合并在一起,以此避免合并出来物体的mesh分散的情况。

    3.物体的光照贴图需要相同(lightmapindex属性相同)


    一个很General的算法

    变量的数据结构及意义

    在此处先将mesh合并整个过程的大体算法描述出来,细节部分在后篇展开解释。

    当然在描述算法前,先说明算法中用到的变量的数据结构及其意义:

    List<MeshFilter> AllMeshFiltersInScene : 场景中所有meshfilter的链表

    List<MeshRender> AllMeshRenderersInScene : 场景中所有meshrenderer的链表

    List<GameObject> AllGameobjectsInScene : 场景中所有Gameobject的链表

    Dictionary<Shader, Dictionary<Texture2d, List<int>> ShaderToTextures  : 场景中所有的Shader到其贴图的映射(在合并之前,所有贴图都是贴在材料之上的,这些材料有自己的Shader,就视为这个贴图的Shader。只有Shader相同的贴图才能打包到一个图集中,他们的mesh才能合并在一起)

    List<List<Gameobjcet>> CubesOfGameobjects : 场景中的正方体数组,里面存着这个正方体里的物体

    Dictionary<Gameobject, int> GameObjectToIndex : 建立物体到其索引的映射

    算法

    1.FindAllMeshesInScene : 找到场景中所有MeshFilter组件,存在AllMeshFiltersInScene,据其还可以获得带这个组件的物体存在AllGameobjectsInScene 以及这个物体的其他有用组件如MeshRenderer存在AllMeshRenderersInScene

    2.PackAllTexturesInScene && DividingTextures: 将场景内所有的贴图打包成若干个图集(图集,即是贴图的集合;如前所述,Mesh合并之后多个物体成为一个物体,这个物体使用的是一个合并的Mesh,合并的材料,这个合并的材料当然就有一个合并的贴图集合,即为图集)

    3.DoCombine : 遍历场景内的每个正方体,对其内的物体进行合并条件判断后,分组进行合并

    相关文章

      网友评论

          本文标题:Unity的Mesh合并(0)

          本文链接:https://www.haomeiwen.com/subject/qxmmzxtx.html