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

2023-05-16

               大家好,我是红孩儿,目前在玩吧技术专家组负责技术研发工作,好久不见,作为一名引擎开发者,这次我给大家分享一下基于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的技术解法上做了一些讲述,希望能对各位游戏研发的小伙伴有所帮助。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Spine动画的AVATAR换装系统优化 的相关文章

  • 建站基础:WordPress安装教程图解

    http www metsky com archives 430 html 本文介绍WordPress xff08 WP xff09 安装方法 xff0c 虽然很多IDC都会主动帮站长安装 xff0c 安装过程也很简单 xff0c 但毕竟是
  • 国内众筹

    http www zhihu com question 21022884 rf 61 20050061 非股权众筹网站 xff1a 点名时间 中国最大众筹平台 支持创新的力量 国内领先的众筹网站 xff0c 主打科技新硬件的综合类众筹网站
  • I2C slave address

    1 同一 I2C bus device 之 I2C slaver address 不可一样 2 检查 这些 devices 是否可以变更 I2C slaver address hardware pin control or software
  • FreeRTOS Task switch

    vTaskSwitchContext中看pxCurrentTCB traceTASK SWITCHED OUT 切出 taskSELECT HIGHEST PRIORITY TASK traceTASK SWITCHED IN 切入新的ta
  • cocoapods install

    http blog csdn net home zhang article details 47317751
  • UITableView

    http www cnblogs com kenshincui p 3931948 html
  • 一些网址

    http www chanpin100 com 点击打开链接

随机推荐

  • win10下的docker桌面端配置ubuntu进行访问

    前言 xff1a win10下安装了docker桌面端 xff0c 想使用linux系统来访问docker 1 win10下docker安装好之后 xff0c 可以直接使用powershell来访问docker环境 xff0c 如下 xff
  • ROS的基本用法二 服务通信

    第一节 xff1a ROS的服务 摘要 xff1a 介绍ROS的服是双向的通信 xff0c 客户端提交 xff0c 服务端处理后返回到客户端 1 理论介绍 自定义数据类型 xff0c 根据自定义数据类型进行处理 xff0c 客户端请求 xf
  • Ubuntu22安装docker-ce

    阿里云 span class token function sudo span span class token function apt get span remove span class token function docker s
  • C语言之字符数组和字符串末尾加‘\0‘情况浅述

    在字符数组中 xff0c 以字符串形式存入 xff0c 机器会自动加上 39 0 xff1b 在字符数组中 xff0c 以字符形式存入 xff0c 机器不会自动加上 39 0 39 在字符串中 xff0c 效果一样 在C语言中 xff1a
  • Ubuntu 16.04+ROS kinetic+rviz模拟turtlebot机器人时出现的问题-

    鉴于ROS kinetic 版本主能兼容 ubuntu 16 04和15 01版本 xff0c 而16 04的版本由于环境比较新 xff0c 感觉还有很多问题需要解决 博主在进行RVIZ模拟仿真机器人跑时 xff0c 出现了以下问题 xff
  • Win10下 Ubuntun1604LTS双系统安装

    1 下载Ubuntu 16 04 https www ubuntu com download alternative downloads 下载 16 04LTS版 2018 03 10 Ubuntu 16 04 4 LTS Ubuntu 1
  • 主祷文

    主 祷 文 我们在天上的父 xff0c 愿人都尊你的名为圣 愿你的国降临 愿你的旨意行在地上 xff0c 如同行在天上 我们日用的饮食 xff0c 今日赐给我们 免我们的债 xff0c 如同我们免了人的债 不叫我们遇见试探 xff0c 救我
  • 嵌入式Linux系统串口通信协议设计

    1 设计基础 这里指的协议是应用层协议 xff0c 针对应用协议的设计 xff0c 需要注意的有几个基本点 xff1a 可识别 xff0c 兼容性 xff0c 访问控制 xff0c 可追溯 xff0c 数据完整性校验 首先是可识别 xff0
  • 什么是导航?导航具有什么样的作用?

    导航 xff08 Navigation xff09 是引导载体从起始点安全 可靠地引导到目的地的过程 xff0c 导航的基本作用就是回答我在哪里 xff1f 通常用载体在空间的即时位置 速度 姿态和航向等参数来描述导航过程 xff0c 这些
  • 一个失败的程序员

    一个失败的程序员 第一次写博客 xff0c 看了别人的很久 xff0c 也想了很久 xff0c 觉得无论文笔有多不好 xff0c 分享的内容有多糟糕 xff0c 都应该有这个勇气迈出第一步 xff0c 记录生活 抒写回忆 xff0c 等到回
  • 学习FreeRTOS前的准备工作

    转自 http bbs armfly com read php tid 61 1552 了解FreeRTOS之前 xff0c 一定要搞清楚FreeRTOS xff0c SafeRTOS和OpenRTOS之间的关系 1 先说FreeRTOS和
  • Linux网络编程(一)

    Linux网络编程博文均选自 unix网络编程 Richard Stevens xff0c 仅限于学习与查漏补缺只用 xff0c 原址 xff1a http blog csdn net hongchangfirst article deta
  • vscode配合gitee同步云设置

    更换开发设备后 xff0c 新安装的vscode软件 xff0c 是没有原先的配置的 xff0c 诸如快捷键 xff0c 快捷代码段生成 安装的各个插件 xff0c 插件的配置等都木大了 xff0c 开发起来会很别扭 xff0c 网上最多的
  • 升压减压以及充电电路设计

    供电电路在整个硬件系统中都是极其重要的 xff0c 只有能产生稳定电压与电流的供电电路才能保证整个硬件系统的正常工作 在本系统中 xff0c STM32F103C8T6需要的电压为3 3V xff0c 同时还有其他的模块需要5V的电压 xf
  • Java枚举详解及常见用法

    1 枚举的使用场景 枚举是一个被命名的整型常数的集合 xff0c 用于声明一组带标识符的常数 枚举在曰常生活中很常见 xff0c 例如一个人的性别只能是 男 或者 女 xff0c 一周的星期只能是 7 天中的一个等 类似这种当一个变量有几种
  • ros编译时与opencv发生冲突的解决办法 opencv_imgcodecs3.so.3.3.1: undefined reference to `TIFFReadDirectory@LIBTIFF

    在编译ros项目的时候 xff0c 遇到下面的错误 xff1a 38 Building CXX object cube slam detect 3d cuboid CMakeFiles detect 3d cuboid dir src ma
  • ROS的一些常用的命令

    下面是ros下面的一些常用操作 xff0c 先做个总结 xff0c 方便后续使用 1 只编译工作空间下面的一个包 catkin make DCATKIN WHITELIST PACKAGES span class token operato
  • realsense相机两种获取相机内外参的方式

    realsense相机出厂的时候一般都标定好了 xff0c 直接读取他们的内参即可 终端输入 xff1a rs sensor control 然后按照提示操作即可 方法 xff1a https blog csdn net mystyle a
  • 【Python开发利器-TKinterDesigner 】 :第一讲:TkinterDesigner的基本功能介绍

    Python开发利器 TKinterDesigner xff1a 第一讲 xff1a TkinterDesigner的基本功能介绍
  • 基于Spine动画的AVATAR换装系统优化

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