基于TexturePacker的骨骼动画压缩

发表于2016-05-20
评论0 3.1k浏览

基于TexturePacker的骨骼动画压缩

项目动画表现选型

1、骨骼动画,导出资源小,动作细腻度稍差

2、32序列帧动画, 导出资源相对比较大,但是能提供丰富的动作。动画品质得到提高。

    那么能否结合32序列帧动画以及骨骼动画的优势,以及更高的序列帧压缩比来提供适合自己的工具了。


优化1

    如下图13D直接渲染的32 的序列图。图2是渲染两次再在flash里面拼接出的导出图,很显然,图2的方式能减少一些公用的图片,这对我们游戏,分红蓝配色是很有帮组的,我们可以让用于红蓝区分的部位单独渲染出来,然后在flash里面进行拼接导出骨骼动画。在游戏中动态控制红来骨骼的显示隐藏来做出红蓝区分。


1

 

2

 

优化2

    导出图优化。在之前的版本中,我们是基于矩形块拼接的(如图3),这种拼接方式比较简单,速度快,但是缺点是透明空白区域比较多,后面发现TexturePacker有一种基于多边形的压缩(如图4),这无疑是拼接的福音。当即决定使用TexterPacker来压缩导出图。


3

4

  最终决定对原有flash 骨骼动画进行一次升级。

 

基于flash骨骼动画的unity实现

    接下来就是如何将texturePacker的多边形压缩集成到现有的骨骼动画工具之中了,在这个集成之中,要解决几个问题,

1、如何在工具中运行TexturePacker

2、如何保存骨骼动画中的骨骼锚点信息

3、如何在骨骼动画播放器中支持多边形渲染

    由于现有骨骼动画导出工具是基于AIR开发的,所以集成TexturePacker的最好方式就是在AIR调用TexturePacker的命令行模式运行。

TexturePacker assets

      createsout.plist (cocos2d) and out.png from all png files in the 'assets' directory

      trimming allfiles and creating a texture with max. 2048x2048px

    实验证明这个办法是可行的。

    针对骨骼动画锚点信息这个是一个比较棘手的问题,由于flash坐标系和unity坐标系的Y轴方向是相反的。以及如何保存锚点信息到texturepacker中。后面发现Texturepacker 提供TPS工程文件,工程文件中可以对需要压缩的图设置锚点信息。(如图5),对应图6中锚点信息。但是细心会发现, 两处的锚点信息y轴数据不一样。其实这里是texturePacker自己做的一个处理,项目文件中保存的是left-top00点,而在TexturePacker工具里面则是left-bottom0,0  但是这个不影响最终的时候,只是在设置工程文件的时候需要从left-top的坐标系设置。


5

 

 

6

 

    如此我们只需要在工具中对需要压缩的图片依次添加到TexturePacker的工程文件,以及设置好其锚点信息,在flash中即 -pivot.x/img.width,-pivot.y/img.height。最终生成一个用于命令行导出的工程文件,最后在程序中执行

     TexturePacker --sheetC:\Users\ruisonzhou\u8001r\u8001r_t0.png --texture-format png --formatunity-texture2d --data C:\Users\ruisonzhou\u8001r\u8001r_sheet --algorithmPolygon  --trim-mode Polygon C:\Users\ruisonzhou\u8001r\u8001r_t0.tps

    即可导出最终压缩版的资源。

    最后一步是在unity中渲染,在之前的基础上需要修改的即,将原来的骨骼矩形渲染,修改为现在多边形渲染。在这之前,需要将texturePacker的压缩文件读取出来。文件如图7


7

    其文件每行即是一张图片的压缩信息。依次是图片名,大图中位置区域,图片锚点位置,顶点个数,[顶点位置...],三角形个数,[三角形索引....]

    有了这些信息之后,我们就可以在unity中还原出我们想要的骨骼动画了。

    以下代码是还原骨骼图片顶点的代码

public static voidBuildSmartVerticesByMatrix(ref Vector3[] vertices,

                                                   ref Matrix m,

                                                   BlitFrameSmartDatasmartData,

                                                   int startIndex,

                                                   float scaleX = 1f,

                                                   float scaleY = 1f)

       {

           //scaleX = scaleY = 1f;

           // 取得所有顶点 法线 uv

           float xx;

           float yy;

           float xMin = -smartData.SpriteForRender.pivot.x * scaleX;

           float yMin = -smartData.SpriteForRender.pivot.y * scaleY;

           for (int ix = 0; ix < smartData.VerticesCount; ix++)

           {

               xx = smartData.Vertices[ix].x + xMin;

               yy = smartData.Vertices[ix].y + yMin;

               vertices[startIndex + ix].x = m.tx + (m.a * xx - m.c * yy);

               vertices[startIndex + ix].y = -m.ty - m.b * xx + m.d * yy;

           }

       }

    其中Matrix flash中骨骼在当前帧的矩阵信息。

    骨骼UV设置如下:

       public static void BuildSmartUVByMatrix(ref Vector2[] uvs, Sprite sprite,BlitFrameSmartData smartData, int startIndex)

       {

           Texture2D texture = sprite.texture;

           for (int ix = 0; ix < smartData.VerticesCount; ix++)

           {

               uvs[startIndex + ix].x = (smartData.Rect.x + smartData.Vertices[ix].x) /texture.width;

               uvs[startIndex + ix].y = (smartData.Rect.y + smartData.Vertices[ix].y) /texture.height;

           }

       }

最终效果如下:


 

    根据项目测试,多边形压缩方式可提高20%-30%的压缩比,虽然这个数字看上去不是很明显,但是有时候往往就是这20%将影响到你的图 1024*1024  还是1024*2048 如果压缩之后能在1024*1024内,那在显存和内存中将提供事半功倍的效果。

     最后感谢在这次升级过程中帮组的同事.alencui, minichen

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引