GameRes游资网

 找回密码
 立即注册
返回列表
查看: 1296|回复: 1

游戏中的整容术! 《Honey Select》捏人系统剖析

[复制链接]
发表于 2018-11-1 11:47:57 | 显示全部楼层 |阅读模式
游戏程序
平台类型:  
程序设计: 2D图形 3D图形 
编程语言:  
引擎/SDK: Uneal/虚幻 
v2-9f87af6e586b680cb9f9f7009ecf14d2_1200x500.jpg

文/ xoyojank 授权游资网发布

关于游戏中的捏人系统,很少有资料提到怎么做,印象中只有《天涯明月刀》分享过.前段时间关注了个VR资源分享的公众号,经常推送HS的捏人作品,所以才引发了我的好奇心,决定一探究竟。

image002.jpg

HS之所以能够有这么强的定制能力,是因为第三方MOD工具的存在,玩家可以自由导入导出游戏中的资源,这也就为我们分析游戏的实现机制开了个后门。

image004.jpg

上图中我们可以看到,脸部有很多骨骼,尝试把模型导出来,对其进行分析:

image005.jpg

针对鼻子上的骨骼,进行平移/旋转/缩放,嗯,看起来捏脸就是这么回事了。

image006.jpg

比如鼻翼骨骼影响这点顶点,那我们对其调节就可以产生这样的效果:

image008.jpg

再比如下巴

image009.jpg

image011.jpg

那骨骼都用来捏脸了,面部的表情动画怎么办呢?

image013.jpg

对模型资源的规格进行分析,发现存在大量的morph动画.也就是说,HS中的的头部骨骼,全部是用于捏脸的,表情动画使用MorphTargets驱动。

那身体总不能也用MorphTargets做动作吧?

image015.jpg

对其模型资源进行析,发现MorphTargets个数为0,而骨骼数超越以往的经验值。

image017.jpg

查看其蒙皮信息可以发现,所有影响顶点的骨骼名字全部带有"_s_"字样,其父骨骼都是不带"_s_"的同名骨骼.也就是说,HS的身体骨架中,父骨骼负责动画,子骨骼负责蒙皮。

游戏中的女角色脸部有67项调节参数:

image019.jpg

女角色身体共有34项调节参数,其中2项为物理参数,跟骨骼无关

image021.jpg

我们来看看这些滑杆能不能跟骨骼一一对应上:

image023.jpg

对于"鼻子整体上下"来说,的确是只需要调节NoseBase的Y值就可以了,我们需要做的就是根据滑杆在最大值和最小值之间进行线性插值。

image025.jpg

对于"眉毛角度Z轴"的调节,这时只调节一根骨骼就不对了,需要左右对称着来.也就是说,有一些调节项需要同时调节左右对称的两根骨骼。

image027.jpg

对于"眉毛左右位置",如果在直线上两个端点之间进行插值,很容易就跟面部三角形穿插了.所以这里的插值路径只有最大值和最小值已经满足不了需求了,而是需要按照曲线进行位置插值,并且配合旋转插值贴合面部的法线方向.也就是说,一个调节项的插值可能是基于曲线(或多个关键帧),而且可以同时影响骨骼Transform的多个分量。

image029.jpg

眼睛的大小调节是最复杂的,一共影响6根骨骼.也就是说,一个调节项是可以对应多根骨骼的。

我们总结一下,脸型(或体型)调整原理就是:

  • 本质上修改的是骨骼的Local Transform(Translation,Rotation,Scale)
  • 一次只修改Local Transform的某个分量(或多个):Tx/Ty/Tz/Rx/Ry/Rz/Sx/Sy/Sz
  • 使用滑杆在预设的调节范围之间进行插值
  • 插值不一定是线性的,可能是有多个关键帧
  • 每个调节项可能对应不只一根骨骼


以此为指导思想,继续结合ILSpy对HS进行逆向分析,终于找到了骨骼的配置数据。

首先是骨骼分类表:

image031.jpg

  • 第1列,类别编号:每个编号代表UI上的一根滑杆.重复出现的编号代表影响多根骨骼
  • 第2列,骨骼名
  • 第3~11列,Transform Mask:代表调节Bone Local Transform的哪些分量,比如000000100代表只影响Sx,即只缩放X轴


其次是骨骼调节关键帧表:

image033.jpg

  • 第1列:骨骼名
  • 第2~N列:关键帧数据,每一帧是9个float,正好是一个Transform,总共25帧。


可以说,I社的捏人系统,最核心的就是这两张表格的数据了,是他们这么多年捏人游戏的经验积累.也正是这个原因,他们舍不得每次新做一套骨架就重新调一版数据,结果就是,游戏中的骨架跟表格对不上:

image035.jpg

游戏中的骨架,不管是数量也好还是命名也好,都跟表格对不上.那这之间是怎么映射的呢?

image037.jpg

原来是硬编码的,真让人崩溃...好了,那整个捏人的核心逻辑就搞清楚了:

1.根据骨骼分类表生成所有的调节滑杆,并从预置的文件加载滑杆的默认值集合

2.如果滑杆值变了,查分类表得到骨骼名(可能多个),再根据骨骼名查关键帧表得到关键帧集合,根据滑杆值插值出Local Transform

3.使用代码逻辑把老的Transform数据转换成新骨架能用的骨骼Transform

4.把骨骼Transform全部更新到模型上

尝试在UE4中使用PoseableMesh复刻了一下,效果还不错:

image039.jpg

PoseableMesh的问题是不兼容动画,所以如果要修改SkeletalMesh的BoneTransforms话,就只能在AnimationBlueprint里实现一个自定义的AnimNode了:

image041.jpg

配上动画,贴上材质,效果就好多了:

image043.jpg

image045.jpg

image047.jpg

image049.jpg

image051.jpg

image053.jpg
(随便找了件衣服遮一遮)

最后,顺便提一下捏人之外的东西,因为对于角色的定制来说,捏人起的作用还不如换一件衣服.

image055.jpg

对衣服的资源进行分析可以发现两点值得学习的地方:

  • 每件衣服都配有一个剔除掉被遮住的三角形的裸模,一方面可以提升绘制性能,一方面能避免衣服和皮肤两层三角形的穿插
  • 裙摆/披风/长衫等都是共用同样的8条物理骨骼,算是比较传统的布料模拟做法


image057.jpg

挂件差不多都是StaticMesh,最多带有物理骨骼,直接挂在骨架挂点上,可以跟随体型一起进行变换.

image059.jpg

眼睛这里的Mesh有点扩张了,分了很多层,甚至有3个Mesh用来做眼泪的表现.材质多了,可以更换的样式自然也就多了:

image061.jpg

image062.jpg

头发分了前中后三部分,每一部分可以单独隐藏或者替换,配合大量的模型资源,真正可以配出各种各样的发型,更何况还有MOD的支持.

其它的类似皮肤/皱纹/眼影/腮红/唇彩/纹身/痣/晒痕/指甲等,大多数都是换贴图,没有多少技术上的复杂度,但却是能够大大提升个性的功能:

image064.jpg

image066.jpg

image068.jpg

通过GPA分析发现,这些叠加的图层在运行时并没有独立的贴图:

image070.jpg

所以并没有采用Decal的方式绘制,而是跟皮肤贴图混合到了一起:

image072.jpg

博客地址:https://blog.csdn.net/xoyojank/article/details/77104708

发表于 2018-11-7 18:43:51 | 显示全部楼层
其实今天我本来也想写这个……
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|稿件投递|广告合作|关于本站|GameRes游资网 ( 闽ICP备05005107-1 )

GMT+8, 2018-11-18 18:29

快速回复 返回顶部 返回列表