编者按 批量渲染其实是个老生常谈的话题,在日常开发中,通常说到优化、提高帧率时,总是会提到它。本篇的主题是优化骨骼蒙皮动画,以及两种常用的批量渲染方式:烘焙顶点动画与烘焙骨骼矩阵动画,这也是本系列的最后一篇。
作者:枸杞忧天
(本文内容由公众号“偶尔学学Unity”提供,转载请征得同意。文章仅为作者观点,不代表GWB立场)
系列回顾: 第一篇传送门: 静态合批 第二篇传送门: 动态合批 第三篇传送门: 实例化渲染![53d73b1cfda41b740806fd3ec711a198.png](https://img-blog.csdnimg.cn/img_convert/53d73b1cfda41b740806fd3ec711a198.png)
试想一下,当我们在游戏场景中放置大量(成百上千)带有骨骼蒙皮动画的单位时,会发现帧数已经开始下降,这是为什么呢?
经过多年研究,我发现,造成这种情况的根本原因是:放的太多了。
然而,在开发某些类型的游戏(如策略或即时战略等)时,通常又需要尽可能的多放些小兵或者怪物,来烘托战场气氛。
需要呈现大量的角色,又需要保证性能,是一件挺麻烦的事情;如果你也在尝试解决这个问题,并且暂时还没有找到合适的方法,那接下来要讲的内容可能会帮到你;因为我们将进入这一系列的下半部分:总结目前较为成熟的针对骨骼蒙皮动画的优化方案。
1.1 骨骼蒙皮动画的开销
“欲练神功,必先自宫”是笑傲江湖中非常有名的一句台词,它也是神功《葵花宝典》和《辟邪剑法》武功秘籍上的第一句话。以前听到它时只是感觉这就是邪魔外道武功的一个符号罢了;但现在想来,当时还是年轻了,没看懂。它其实是一条学习任何技能、知识的诀窍,也是一把打开成功之门的钥匙。
其实,这句话想传达的真正意思是:做事情,要打好基础。
所以,要优化骨骼蒙皮动画,就要先简单了解下它的性能瓶颈所在。
1.2 骨骼蒙皮动画的流程
可以简粗(简单粗暴)的将骨骼蒙皮动画的工作流程分为以下几个阶段:
播放动画阶段
动画控制器会根据关键帧信息等,调整骨骼的空间属性(旋转、缩放、平移)。
计算骨骼矩阵阶段
从根骨骼开始,根据层级关系,逐一计算出每一根骨骼的转换矩阵。
这个矩阵连接的是这根骨骼的本地坐标系和角色坐标系(通常会是角色脚下);也就是说通过它可以在某一帧动画结束后,将(某一根)骨骼坐标系下的坐标或向量,转换到角色坐标系下。
蒙皮阶段
更新网格上每个顶点的属性。
由于动画改变的是骨骼而不是顶点的空间属性;而且网格中的顶点是相对于网格坐标系下的,并非在角色坐标系下。所以在这一阶段,我们首先要依据创建骨骼蒙皮动画时,被记录下来的顶点和骨骼的关系,找到对应的骨骼(Unity中通过Mesh.boneWeights获取,一个顶点最多可受到四根骨骼影响)。
其次,通过网格坐标系到骨骼本地坐标系的转换矩阵(Unity中通过Mesh.bindposes获取),来建立从网格坐标系到骨骼坐标系的桥梁;结合上阶段得到的骨骼坐标系到角色坐标系的转换矩阵,实现将动画对骨骼的影响最终作用到顶点上,并将其更新到角色坐标系下。
![0b5f797f06f7466f1247e02a542d0ec4.gif](https://img-blog.csdnimg.cn/img_convert/0b5f797f06f7466f1247e02a542d0ec4.gif)
渲染阶段
更新动画的开销
计算骨骼矩阵的开销
蒙皮开销
渲染开销
![06d92b194ac3dbe62f59986555f61e6c.png](https://img-blog.csdnimg.cn/img_convert/06d92b194ac3dbe62f59986555f61e6c.png)
![db9ab442b3af4e46da408e4428fe8b87.gif](https://img-blog.csdnimg.cn/img_convert/db9ab442b3af4e46da408e4428fe8b87.gif)
![9af5b25fc3ba15d1e73f4afdfa4f73b2.png](https://img-blog.csdnimg.cn/img_convert/9af5b25fc3ba15d1e73f4afdfa4f73b2.png)