赛马娘Live提取笔记
赛马娘Live提取笔记
复制下岸田夏海MK2大佬写过的:
-本专栏随时可能会因为众所周知的理由而消失。
-是“思路”而非“教学”,因此写的相对比较简明扼要。但如果看懂的话,可以让具有一定改模基础的人也能试着从游戏里拆动作玩。
-整个提取流程依然有大量遗留问题以及需要改善的地方,并且实践过程会相当痛苦。
-不管什么游戏,提取=非正规途径,无论最终进的是MMD、CM3D、恋活还是其他游戏的workshop,本质还是版权物。轻则被夹被封号,重则吃DMCA,如有意外,后果自负。
数据库
在游戏文件存储位置(一般为%USERPROFILE%\Appdata\LocalLow\Cygames\umamusume
)下,meta
文件以及master文件夹内的master.mdb
是两个sqlite格式数据库文件,可以用SQLite Browser打开。
动作数据
赛马娘中的live有music id,不同live名称和music id的对应关系可以在master数据库中id=16, category=16
的位置找到,或者你也可以在umaviewer中查看,live前面的四位数字就是对应的music id。
有了music id,接下来就可以在meta数据库中以music id为关键词搜索live相关文件:
live/musicscores/m{music_id}
可以找到歌词、应援等一些文件。sound/l/{music_id}
音频文件,acb和awb格式,可以使用vgmstream转换提取内容。3d/motion/live/body/son{music_id}
动作文件,可能有很多个,其中体积比较小的是一些插入的动作,体积最大的几个对应一套完整的live舞蹈。cutt/cutt_son{music_id}
一些控制器文件,其中有一个camera文件非常重要,里面包含了live的镜头、动作文件的使用、表情等等,可以说它是live的总指挥。
在数据库中这些record对应的值是一串hex string,猜测应该是对应文件的hash值,在游戏文件的dat
目录下有256个子文件夹对应的就是hex string前两位,这里推荐使用everything或者listary直接搜索文件而不是手动去目录下面找,或者你也可以直接去Cygames的CDN上把文件拖下来,这样只要有两个数据库之后甚至连游戏都不用安装了(喂
动作→FBX
有了动作文件以后我们就可以提取动作了,最方便的方法就是用AssetStudioGUI将动作提取成fbx格式。请注意,由于AssetStudioGUI中AnimationClip的提取必须和Animator绑定,这里的Animator就是人物模型,可以在meta数据库中搜索pfb_bdy
加上马娘id(这个也能在umaviewer里找到),比如我最开始研究的live是Kirari Magic Show,所以我就习惯统统用Copano Rickey来提取动作了。
将模型文件和动作文件同时拖入AssetStudioGUI,选中两者导出,你将会得到一个fbx文件,在blender里导入它(请使用better fbx importer&exporter并将长度单位从cm改成m),就可以看到live动作辣!是不是非常easy!
然后你就会发现,你说得对,但是我的头呢(
由于马娘中马娘有多套服装以及通用服饰,所以实际上身体模型、头部模型、尾巴模型都是分开的,但实际上尾巴咱们用不着,而身体模型是带了头部骨骼的(和头模型的骨骼合并之后就是完整的身体了),所以我们只需要用到身体模型就好。
FBX→VMD
动作导入blender之后,需要稍微调整下帧数结束位置(blender默认250帧),然后理论上就可以直接通过mmd_tools导出成vmd格式的动作了,但是这里有几个问题:
- fbx导入的骨骼名称与MMD标准骨骼不同,因此无法直接套用到MMD模型上
- 赛马娘模型的rest pose是T-Pose,而标准MMD模型一般是A-Pose,即使映射过了骨骼名称,手臂的旋转也是错误的,需要调整
- 赛马娘的骨骼层级与MMD模型不同
要解决以上问题,我们需要做以下操作:
- 通过脚本去批量重命名骨骼,同时最好删除掉无用的骨骼(比如裙摆骨骼之类)
- 调整fbx导入骨骼的rest pose,或者使用mmd_tools的treat current pose as rest pose功能,或者改动mmd模型为A-Pose;mmd_tools的这个功能很好,你可以用脚本去复制一份要套上的MMD模型的骨骼rest pose,这样导出之后的动作就是完美契合MMD的了
- 手动修改MMD模型,最重要的就是修改上半身骨的亲骨为下半身而不是腰;其次一点优化修改就是把下半身和头骨修改成稍微偏离轴线一点(不知道马娘模型中这个设定是为了避免gimbal lock还是怎么回事,但其实他们的动作数据用的quaternion旋转)
Camera数据
你说得对,但是现在角色没有表情啊,表情在哪里?
表情竟然在camera文件里,我大震撼。
你可以用AssetStudioGUI将camera文件导出成json格式,然后其中一些有用的内容结构大致如下:
1 | { |
镜头相关
Position Key、LookAt Key、FOV Key、Roll Key定义了游戏中摄像机的位置角度信息,但很可惜目前我还不知道怎样将它转换为MMD中的镜头,因为文件内存储的位置信息似乎是与角色某些骨骼的相对位置而不是空间绝对位置,因此需要搭配人物运动才能计算出正确的位置。
试想如果镜头是空间的绝对位置,那么身高较高的马娘和比较矮的,相同的镜头拍出来的构图就会不一样,而使用相对位置就避免了这个问题。
并且游戏中live播放时会有一些插入动作(在charaMotSeqList
中定义),如果你使用插件解锁自由镜头会发现有时候人物会闪现,就是插入动作覆盖了完整舞蹈动作,即使能解析出摄像机的正确位置并转换成MMD,也需要搭配这些插入动作才能完美还原live。
因此目前我没有花更多精力来研究镜头数据,欢迎有大佬来弄。
另外chinosk大佬给Trainers-Lengen-G插件加上了镜头信息显示,对于研究镜头会很有帮助,感谢感激神降临🙏。
表情相关
在ripSyncKeys
和mouthKeys
中有嘴型数据,facial1Set
中是C位的表情,other4FacialArray
是其他角色的表情数据,其中的frame
是以60帧为单位的,要注意eyeTrackKeys
也是涉及实时演算的,一个例子就是在幼儿园汇演的live中总大酱有一个绕头动作,对应的眼睛注视位置一直是摄像机,因此这里的DirectPosition
不是方向向量而是空间中的一个点。
另外ripSyncKeys
数据中有一个character
的项很有意思,它标记了该项嘴型对应了哪些马娘,使用的是二进制的mask,例如1对应的是1号位,2对应的是2号,4对应3号,3对应1号和2号,可以使用
(mask >> (id-1)) % 2 == 1
来判断位置id是否在该mask内,但是character
似乎并不是每一项都有的,它没有的时候似乎等同于“可用于所有位置”。
想要将表情数据转换成MMD使用的并不简单,主要的问题在于马娘模型的表情太丰富了,每一个部位可能都有30+的表情,而且眉毛也可以左右单独控制,MMD表情可能总共加起来都没30个……想要部分还原,我的处理方法是将camera中的morph weight转换成一个或多个MMD morph的加权组合,来尽量达到还原,至于眉毛,我只转换左边的部分(假设live中的眉毛表情永远是对称的,不对称我也不管),另外就是眼睛项目中"attribute": 393216
似乎对应了眨眼动作,另外mouthKeys
中似乎有一个可以回退到某个表情的attribute,没研究出来,当空表情处理了。
这里具体对应的morph key关系和权值,只能自己去慢慢试,而且不同模型可能还不一样,这里特别感谢LC_ilmlp最初的表情转换脚本的启发,以及一起发给我的聪明吧唧的模型来研究表情转换。
把处理后的morph keyframe按照一定格式输出成文本格式,然后使用PMX-VMD-Scripting-Tools转换成vmd格式就可以往MMD模型上套了,至此效果已经大差不差了。
音频相关
注意到ripSyncKeys
中character
实际上标记了每一句都是谁来唱,因此我们还可以用脚本来混合之前提取出来的音频文件(这些音频是按照BGM和不同角色干声分开的),并根据演唱人数的不同调整好增益,由于游戏音频文件似乎是以48kHz 16bit采样的波形存储的,相当HiFi,因此处理后的音频再升到24bit就可以投B站的无损音频了(
不过比较奇怪的是Kirari Magic Show这样处理之后会少两小段音频,我不知道是咋回事233。
舞台模型提取
这里就随便写一下因为有点忘了。
live有一个额外的controller文件(对应的id和music id是不一样的,我不知道这个id从哪来),这个controller文件可以提取出一堆mesh文件,把这些mesh提取出的fbx导入blender就可以还原live的舞台,当然有很多物体会不在正确的位置上,因为这些物体在live中是动态的(一般是灯光、阴影的模型),可以直接删掉。
然后模型的贴图,在controller对应的数据库comment中可以看到依赖的mtl材质文件,把这些文件一起用AssetStudioGUI提取,就可以弄出来几个贴图文件,然后在blender里面试一试,把贴图加载上就差不多能还原舞台了,接下来用mmd_tools导出出来扔进MMD。
写在最后
我不知道B站专栏能不能编辑,如果可以,后续如果有新的发现会在文章中直接修改,如果不能的话,也许就评论区指个路。不过大概率我懒得继续折腾了(做MMD死路一条,笑),精力实在有限,第三世界的生活太苦了。
文中所使用的脚本都可以在GitHub: capric98/ddt 中找到,精力有限,没有readme,请自行摸索使用方法。并欢迎大佬commit。
特别感谢其他大佬之前的研究成果,帮我少走了很多弯路,这里贴几个:
引用:https://www.bilibili.com/read/cv25340365?spm_id_from=333.999.list.card_opus.click