版权声明
大规模角色渲染的DrawCall开销
什么是DrawCall?
通常下我们所说的DrawCall,就是Cpu发送给Gpu的一次渲染调用指令,每当进行一次渲染调用,CPU就要给图形管线发出一个指令,告诉GPU去渲染多少个三角形,这些三角形可能是某个角色的三角形。那么这个调用就会造成GPU开始一轮新的渲染。那么开始一轮新的渲染就意味着GPU要等前一次渲染结束以后才能开始本次渲染。所以说每一次CPU往GPU发送一个渲染调用,都会产生较多的渲染开销。也就意味着我们需要尽可能多的减少DrawCall,从而减轻性能开销,使游戏更加流畅。
性能开销分析
性能开销主要是在于unity要渲染角色的时候,它会产生两个巨大的开销:
以人型渲染为例:
因为角色是人形的,是以一种动画树的形式展开的,那么就必须要计算从角色的盆骨位置往上到角色的第一节躯干,到角色的第二节躯干,到角色的第三节躯干,然后到角色的头部、肩膀、上肢、前臂、手,这样的一整条树形的结构,必须要全部计算。
例如要让角色身体前屈,就要把身体的每一个关节的运动都在每一帧当中重新计算一遍。所以说如果有1万个角色,乘以每个角色的骨骼数,仅仅去计算这些角色的位置运动,就要进行百万数量级的运算。由于这些运算是在GPU当中进行的,GPU并没有大规模并行运算的能力,所以计算速度是比较慢的。
网格顶点动画技术
像图中左边的飘扬的旗帜,它并没有角色的骨骼。它的运动其实就是对旗帜上面的顶点去做位置的变化而已。它用的是另外一种动画技术,叫做顶点动画,就是调整顶点的位移,而不是去逐层计算骨骼,所以这种运算它的开销就比骨骼动画要小得多。
那么既然角色身体的骨骼要从盆骨位置往上一层一层往躯干、往头部、往肩膀去计算。那能不能一次性的把它做成顶点动画呢?是可以的。我们可以按照固定的频率对角色动画进行采样,并且记录这个角色从站立到兵器砍出去,每一帧的动画位置信息,全部记录记录在一张贴图上,这张贴图就叫动画贴图。
因为我们要记录的是顶点的位置变化,而我们贴图上每一个像素刚好是有四个颜色分量通道红、绿、蓝、透明度,所以就可以把每个顶点的位置变化信息按照逐帧地记录在一张贴图里。
烘培一张动画贴图
对应刚才的角色动画,我们可以制作出来这样的一个贴图。横向是每一个顶点,纵向是每一帧。
在图中这条红色竖线上,它的颜色从绿色变成青绿色,再变到偏黄色。这说明什么?我们记录了某一个顶点在每一帧之间它的变化信息,这个变化对应的就是颜色变化,因为颜色里面存的并不是颜色值,而是顶点的位置信息。
性能压力从CPU转移到GPU
当网格动画信息的顶点变化烘焙到动画贴图里以后,所有顶点变化就可以放在GPU里进行运算。为什么可以放在GPU呢?因为骨骼unity计算骨骼动画只能在CPU中,而渲染模型可以在GPU中。那么经过这种处理后,就可以不再使用骨骼动画的方式来进行渲染了。
有了这张动画图后,首先把这个模型加载到GPU当中。然后通过动画图的信息来控制角色,第零帧时把角色的位置调到第零帧对应的位置。第一帧时把角色调到第一帧对应的位置,第二帧时把角色调到第二帧对应的位置。所以这时所有的计算都是在显卡,也就是在GPU当中。
当然如果要利用动画贴图,把动画渲染出来,还需要配合另外一样东西,就是Shader。只要配合shader,就能够在GPU里面进行动画运算。
使用GPU Instancing完成DrawCall优化
前面提到的渲染开销主要来自于两方面,一是骨骼动画计算,二是DrawCall。那么现在骨骼动画计算已经被优化了,DrawCall并没有降低所以其实优化只完成了一半,GPU仍然是一个模型运算一次,所以性能开销并没有减小,所以我们需要进行下一步优化。
什么是GPU Instancing?
GPU Instancing 可以用来优化同模型的渲染开销。如果角色模型是相同的模型,那么就可以通过GPU Instancing来优化。像大批量的同屏同模角色,就可以使用GPU Instancing进行优化。
那么使用骨骼动画的时候,为什么不能使用GPU instantly来优化渲染效率呢?答案是Unity不支持。Unity中使用GPU Instancing的前提是这个模型不能是一个骨骼动画模型。利用动画贴图进行渲染,就可以开启GPU Instancing 。当然开启GPU Instancing 时,还需要实现一个动画shader,在shader中要开启GPU instantly 选项。
这样一来,我们的渲染优化就完成了!
技术进阶思考
1.角色顶点数量较大怎么办?
Unity能够接受的最大分辨率为4096*4096。如果顶点数量超过了4000个,那这时还能不能使用这中动画优化技术呢?
2.角色坐标范围较大怎么办?
角色坐标范围很有可能会大于256,由于RGB最大值为256,这时使用RGB来存储是不够的。这是就会存在一个问题——精度丢失。这时如何处理呢?
参考
进一步学习交流,请关注我
完整视频请点击本链接观看:大规模实时角色动画的渲染