基于Spine动画的AVATAR换装系统优化

               大家好,我是红孩儿,目前在玩吧技术专家组负责技术研发工作,好久不见,作为一名引擎开发者,这次我给大家分享一下基于Spine动画的AVATAR换装优化,希望能够对有类似需要的小伙伴有所帮助。

               很多游戏开发团队都正在使用Spine动画软件来制作人物AVATAR动画,作为一款广泛应用于游戏中的2D动画制作软件,Spine提供了良好的骨骼动画功能和库接口来实现人物AVATAR动画。

                  

              自从Spine支持顶点网格以来,很多用来表现长发,长裙动画的身体部件,会使用比矩形区域更复杂的顶点网格来制作,以更好的体现部件中的摇动细节。这些部件从一个简单的四个顶点矩形区域,变成了由多行多列顶点组成的平面模型。顶点从左上到右下进行UV展开,映射到纹理图区域。在表现长发摇动,长裙摆动等细节动画时,只需要通过对相应位置的网络顶点进行移动就可以实现。

              主角人物长发的网格

                主角人物长裙的网格

 

           在AVATAR系统开发中,我们经常会制作包含人物所有部件和动画信息的基础Spine动画,这个基础款的Spine动画纹理会使用所有部件的纹理拼图来优化批次,使得基础人物可以在1个批次完成动画渲染。

           人物AVATAR换装的过程就是需要将对应身体部件的纹理区域换成新的图片。但在渲染AVATAR动画时,渲染批次在遇到需要切换纹理时就会被将之前使用基础拼图的顶点缓冲区提交进行渲染,然后设置新的纹理对部件进行渲染,这里会增加1次DC,渲染完后再重新设置回之前的拼图纹理,继续后面的部件渲染。每替换一次不同部件的图片,总的批次都会增加。

                这就麻烦了,如果不做优化,那AVATAR在实际使用时效率就是个完全不可控的黑洞了。一个人物身上往往几十个部件,如果不注意管控,运气好的话,百八十个批次就出去了。

               伴随纹理图片的更替,部件的UV也需要按照新的图片纹理区间进行映射,部件的顶点UV从左上角到右下角只需要重新按照裁剪矩形信息(裁剪后矩形区域,原始图片大小,裁剪后左上角像素偏移)重新计算一下就可以了。这些信息在atlas文件中记录供读取使用。

                懂得引擎优化知识的开发者也会对拼图进行空白边缘裁剪,以使得图片文件和游戏使用时显存占用得以减小。

                截图:(未裁剪拼合贴图1680x1284大小)

 

用Spine3.6裁剪后完毕,变成1811x187大小。

 

        裁剪后的小图可以由其对应的xy,size,orig,offset信息推算出原始未裁剪前正确的图像位置。

        拼图算法看起来很棒,这明显是一个利用率很高的图片。但我们在CocosCreator 中运行却明显出现错误:

 

           不久前,Spine官网曾明确表示不支持网格部件的裁剪的,这是2021年11月底的官网说明:

 

           但12月初官网去除了相关说明,经过在论坛的咨询得知,从Spine Editor 3.7.77开始支持了对网格部件的裁剪,只是一直未对中国用户同步相关文档。

 

           这个事情实际上是我们优化的关键步骤之一。虽然Spine官方已经宣称实现了这个功能,不过知其然,也应知其所以然,我按照自已的方案实现了这一步,下面我来解释一下其中奥妙,为此我特意开发了一个工具软件并以目前所用的一套基础女的Spine动画文件为例来辅助解释:

           截图A:(裁剪前后脑部头发,为了适应长辫子应用了网格,对应右上角红色区域纹理,可以看到在短发情况下有巨大的浪费)

 

截图B:(裁剪后在渲染时,使用网格的部件都出现了放大效果的渲染错误)

 

         解决这个问题的关键,是弄明白裁剪后网格部件的顶点要如何重新进行UV映射。我们来看一下基础人物在使用裁剪图时,网格部件的UV映射难点是什么?

         我们先来看一下后脑部头发的网格:

 

        因为网格部件是由一个几行几列的顶点组成,裁剪完的图像矩形区域最终都还是要通过矩形来映射UV,但是直接裁剪后的图要想渲染到正确的位置,矩形区域对应在网格中必须有一圈顶点来支撑UV映射,同时要把圈外的顶点所包括的区域透明,可是有么?并没有,所以没办法裁,如果硬裁,只会造成将整个拼图中的一大部分图像内容映射到网格里造成错误。

         也许这才是问题的关键,

         不过,虽然裁剪后的矩形对应在网格中没有一圈顶点,可是我们只要把包含图像的三角形顶点UV映射正确不就行了,省不到100%,能省80%也可以啊。

         网格Mesh,归根到底,还是一堆三角面,如果你不理解这一点,那就好好找本基础引擎的书先入入门。

        好了,我们遍历一下部件的网格三角形,把有非透明像素点的三角形选出来。

       核心算法其实也不难,我们以三角形所在矩形来遍历像素值,取ALPHA是否大于零,如果大于零,再判断它是否在三角形内就可以了。因为这部分工作可以自已写个工具软件进行外部处理,所以这个算法我暂时没有进行优化,经过处理后的结果如下图:

       为了方便分析,我把顶点UV也以青色字样显示在屏幕上了。

 

          大红盖头内的三角形,才是真正有价值的三角形,不是么?除此外的三角形,实际上都是看不到的透明三角形。所以说,为了渲染一个网格部件,将会产生比较多的透明纹理浪费和渲染时顶点计算浪费。

           我们既然已经得知有效三角形了,完全可以按照有效三角形所占据的矩形区域来裁剪,这样UV映射的问题就好解决了,如果在动画计算和渲染时再去掉无效三角形。那效率岂不是杠杠的提升一大截?

          说干就干,首先第一步是要计算出当前部件纹理的裁剪矩形。这个就是常规算法,只需要对部件对应纹理的像素遍历,判断ALPHA值计算就可以得到。

         第二步是遍历当前部件所有的三角形,然后通过mesh的uvs取得当前三角形的三个顶点的uv数值来映射纹理中的三角形区域像素,对这个三角形的像素值进行透明度判断。如果当前三角形有像素,就把三角形的三个顶点所在的位置与裁剪矩形进行判断,如果顶点在矩形外,就对裁剪矩型进行扩展。

 

          UV映射解决好了,最后将所有顶点按照在裁剪图中的位置重新进行UV值计算,并用新的UV进行裁剪,同时把新的UV值重新写入到Spine的JSON文件中,这个模型的裁剪问题就算基本解决了。

          结果如图:可以看到左边第一个是明显有一些空白区的,就是上面经三角形对裁剪矩形进行扩展后的结果。

(976x462大小)

 

           这是Spine动画优化的一个基础难点,做完这一步,AVATAR的图片利用率会明显上升,显存使用会明显下降。不过AVATAR的优化才只算做了一半,之前我们提到,当进行部件换装时,新图片会造成渲染批次的增加,除此外,原拼合图中被替换部件占据的显存不再复用也会造成理论上的浪费。

           只有主角一个人的场景,因为换装造成的批次提升,或者因为没有使用裁切图片而造成的显存浪费,玩家和测试几乎是感知不到的。所以浪费精力解决这些理论存在但现实看不到的问题意义并不是很大。

          但当主角需要进入到一个大厅场景,在表现多人同屏时,批次的明显增加和大量的显存占用,就会让体验感迅速下坠。这时候,你就必须要做一些处理来让体验感恢复到一个水平之上。

 截图A(只有一个人,流畅运行)

截图B(多个人及小动物,变慢) 

游戏引擎方面的优化问题一般主要还是围绕两件事:

  • 显存占用的优化,一般能做的手段无外乎是裁剪空白,减小图片,降低像素格式。
  • 渲染批次的优化,一般能做的手段主要是合批,合批,再合批。

         那么,我们能不能在换装时做一下动态合图来使每一个角色有一个最优的拼图纹理,并在一个批次内完成人物的换装渲染呢?

         当然是可以的,只需要使用新的拼图算法对涉及到的服装进行重新合拼就可以了,这里不再赘述了,网上比较多,大家可自行查阅。

 

           讲到这儿,本次的优化实操算是告一段落,不过这些工作只是针对AVATAR换装中涉及的显存和批次优化,伴随人物数量增多,骨骼计算的压力可能就会凸显,如果想要实现多人同屏,仅仅关注纹理大小,显存和批次的压力也是不够的,如果CPU计算量的压力过大,也要进一步考虑改造方案进行优化,如果场景使用大量的Spine动效,穿插大量Additive渲染,优化的重点也有所不同,具体每种优化的方式,不在这里进一步展开了,有机会再做深入。

             最后说一句:虽然引擎底层的优化技术很酷,但在实际工作中,很多引擎性能层面的优化问题,并不单单是一个局部问题,应该当作一个项目方案去设计,从策划想法,美术规范,程序算法,引擎使用,工具辅助等多个层面跟据项目做出合适的解决。如果不能做到共识,最后程序小伙伴的后期优化压力就会很大。今天只是从AVATAR的技术解法上做了一些讲述,希望能对各位游戏研发的小伙伴有所帮助。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火云洞红孩儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值