过早优化是万恶之源”——Donald Knuth
        不少开发者在前期开发过程中对算法等类似的开销都甚少关心,而是更倾向于尽可能简单的解决某个问题,后面必要时再进行优化。这能极大加速开发进度,并保证代码简洁。但开发后期通常会出现的瓶颈就是图形资源,而优化图形渲染这一块比较有难度。
        本文将分享作者Lamebait在使用Unity5制作沙盘游戏过程中优化SkinnedMeshRenderers的相关步骤提供给大家参考。

第一次迭代——使用不带动画的网格

每个城市街区约有15个网格,首先最显著的问题就是不断被加载到游戏中Mesh数量。当街区数量增长到数百之后,DrawCall数量也飙升到大多硬件所不能承受之高。Unity支持网格批处理,能减少一部分DrawCall。但所有网格都是有动画的,所以这些网格用的是SkinnedMeshRenderer组件而非MeshRenderer,Unity不支持对SkinnedMeshRenderer进行批处理。

第二次迭代——SkinnedMeshRenderer.BakeMesh()

所有的建筑和树木都只在它们出现和消失的时候有渐入和渐出的动画,一旦稳定下来之后就是完全静止的了,那可否在此期间将它们变为MeshRenderer呢?
        如果使用带有MeshRenderer的无动画网格,通过开关选择使用MeshRenderer还是SkinnedMeshRenderer,结果可能会发现有几个网格与其SkinnedMeshRenderer的最终状态不太匹配,所以这条路不通。
        下图展示了SkinnedMeshRenderer的最终状态与静态网格本身的差别。

SkinnedMeshRenderer中有个BakeMesh()函数,功能是按照网格当前的动画状态创建网格数据快照,并输出这个网格数据用于其它地方。这样就可以将输出的新网格传给MeshRenderer然后享受自动批处理的功能。但事情并非如此简单。
        下面创建包含各种网格类型的字典,以便多个MeshRenderer可以共享同一个网格,然后让Unity进行批处理。不论何时增加了新的网格,它都会被烘焙出来并加到字典中。但这样会爱导致进行网格类型切换后网格的高度略微有点拉伸。这是因为建筑的缩放值不是0,以致SkinnedMeshRenderer输出的网格本身被缩放了一次,而这个网格在应用到GameObject上的时候由于GameObject本身的缩放值又被缩放了一次。解决这种矛盾的办法就是先将建筑的缩放值设为1,烘焙后再设回原始值。
        到此整个切换看起来完全无缝。但这是有代价的,因为Unity也不支持对使用了阴影的MeshRenderer进行批处理。而关闭阴影又会对游戏效果大打折扣,所以必须想想其它办法。

第三次迭代——网格合并

还可以手动批处理,因为网格是可以合并成一张大网格的。当然也有些限制,如网格材质必须相同,单个网格的三角形数量有限等。还好这个游戏的建筑和树木总共才用到了三种不同的材质,所以可以将整个街区合并成最多三张大网格。
        基本上,创建CombineInstance后将BakeMesh()输出的网格传给它并加上Transform。最重要的是确保Transform的变换矩阵中GameObject本身的缩放值都是无效的,否则网格会像上文提到那样错误变形。合并后网格的最终结果会应用到网格之前所在的GameObject,然后在街区状态变为静止后移除。
        整个过程比较棘手。游戏中很多因素都会导致奇怪的效果,对于每个因素及每个可能的组合都要单独测试。但结果证明这是值得的,现在游戏在有阴影的情况下帧率也非常可观!
        合并的红色网格如下图:

第四次迭代——更高一级

这游戏设计的特色之一就是每个阵营最终的街区都会在生成之后被保留,所以如果街区从未改变过,可以将它们合并到一起。一个个合并会遭遇前面提过的网格大小限制。而将城市分为几个格子可以将几个街区的网格合并为单个,从而进一步降低DrawCall。效果如下图:

总结

本文最重要的三点:

  • 不要过早优化,可以适当晚一点。
  • 善于发现漏洞!如果某个东西不适用于X,那能否暂时将它变为Y呢?
  • 用创造性的技巧换取性能。

内容下载链接:
       https://github.com/Ryxali/StateCapital

在Unity 5中优化SkinnedMeshRenderer的更多相关文章

  1. Unity优化方向——优化Unity游戏中的图形渲染(译)

    CPU bound:CPU性能边界,是指CPU计算时一直处于占用率很高的情况. GPU bound:GPU性能边界,同样的是指GPU计算时一直处于占用率很高的情况. 原文:https://unity3 ...

  2. 【Unity优化】如何实现Unity编辑器中的协程

    Unity编辑器中何时需要协程 当我们定制Unity编辑器的时候,往往需要启动额外的协程或者线程进行处理.比如当执行一些界面更新的时候,需要大量计算,如果用户在不断修正一个参数,比如从1变化到2,这种 ...

  3. 【Unity优化】怎样实现Unity编辑器中的协程

    Unity编辑器中何时须要协程 当我们定制Unity编辑器的时候,往往须要启动额外的协程或者线程进行处理.比方当运行一些界面更新的时候,须要大量计算,假设用户在不断修正一个參数,比方从1变化到2.这种 ...

  4. Unity优化方向——优化Unity游戏中的垃圾回收(译)

    介绍 当我们的游戏运行时,它使用内存来存储数据.当不再需要该数据时,存储该数据的内存将被释放,以便可以重用.垃圾是用来存储数据但不再使用的内存的术语.垃圾回收是该内存再次可用以进行重用的进程的名称. ...

  5. Unity 几种优化建议

    转: http://user.qzone.qq.com/289422269/blog/1453815561?ptlang=2052 Unity 几种优化建议 最简单的优化建议: 1.PC平台的话保持场 ...

  6. 通过profiler对unity进行针对性优化

    转 : http://user.qzone.qq.com/289422269/blog/1453815629?ptlang=2052 通过profiler对unity进行针对性优化  1. CPU U ...

  7. i3D的一篇Unity教程中的笔记

    原地址:http://blog.sina.com.cn/s/blog_72b936d80100wwej.html 以下是i3D的一篇Unity教程中的笔记. i3D的这篇教程是[i3D.Next-Ge ...

  8. Unity 绘图性能优化 - Draw Call Batching

    Unity 绘图性能优化 - Draw Call Batching Unity官方链接:http://docs.unity3d.com/Manual/DrawCallBatching.html 转载请 ...

  9. Unity UI性能优化技巧

    本文将介绍一些提升Unity UI性能的技巧.更多优化技巧,可以观看Unity工程师Ian Dundore在Unite Europe 2017的演讲<使用Unity性能提升技巧>. 1.划 ...

随机推荐

  1. CentOS6.7编译安装mysql5.6

    可能因为有各种情况,无法通过yum安装mysql,这里记录一下编译安装的简单步骤 使用yum安装一些依赖 yum -y install make gcc-c++ cmake bison-devel  ...

  2. The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker

    题目链接:https://nanti.jisuanke.com/t/41408 题目意思很简单,就是个模拟过程. #include <iostream> #include <cstr ...

  3. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  4. 解决samba共享虚拟机第二块磁盘的难题

    linux下使用samba共享文件到window下已经实现过了   点此链接 但是共享时磁盘空间是有限的,如果空间使用完了该怎么处理呢?这是个头疼的问题,不知道samba支持不支持共享第二个文件夹,由 ...

  5. Escape character is ‘^]’什么意思?怎么使用telnet

    在linux/unix下使用telnet(telnet ip 端口号)连接主机时提示“Escape character is '^]'.”,这是什么意思?“^”是Ctrl键的意思!1.这个提示的意思是 ...

  6. ActiveMQ消息可靠性-签收

    非事务模式下消费者签收 动签收就像快递到达时,快递寄送点给你签收了,不用你自己去签收,而手动签收就是必须我本人签收, 自动签收(默认为自动签收) 手动签收:能够避免消息的重复消费 当设置为手动签收时, ...

  7. 前端html页面,手机查看

    在写前端页面中,经常会在浏览器运行HTML页面,从本地文件夹中直接打开的一般都是file协议,当代码中存在http或https的链接时,HTML页面就无法正常打开,为了解决这种情况,需要在在本地开启一 ...

  8. 简要说明盒子模型和flex布局

    盒子模型:可以看做是一个盒子,包括外边距.边框.内边距.实际内容. flex布局:弹性布局,灵活性好. 当给元素设置display:flex时,它就是flex容器,它的所有子元素自动成为容器成员,称为 ...

  9. 洛谷p1458顺序的分数题解

    抱歉,您们的蒟蒻yxj不知道怎么插入链接qwq就只好粘个文本的了qwq:https://www.luogu.org/problemnew/show/P1458 没错,是个黄题,因为你们的小蒟蒻只会这样 ...

  10. 10-排序6 Sort with Swap(0, i) (25 分)

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...