
今年春季的时候开始在用Blender做VRC模型向Garry’s Mod模型的转模,遇到了一些VRD程序骨不自然的问题,然后一直没修明白
最近重新研究了一下别人做VRD的思路,这里记一记吧
以后有机会的话可能会考虑把我学的整个工作流都做个记录(?),毕竟中文区这方面的文字是真少的可怜了。。。我自己就是对着一篇英文教材走完的全流程
程序化骨骼
虽然我们平时都会用VRD防穿模这种简单的叫法来称呼这个东西,但其实它的学名应该叫程序化骨骼来着,下文为了方便,我就称其为程序骨了
程序化骨骼的定义
在V社官方文档中,程序骨被定义为:
程序化骨骼(在其他地方也被称为骨骼“驱动器”(Blender)或“驱动关键帧”(Maya))通过一个骨骼的旋转来驱动另一个骨骼的旋转和位移。第一个骨骼——称为 驱动 或 控制 骨骼——通常由人类动画师进行操作,而第二个骨骼——称为 程序化 或 辅助 骨骼——根据驱动骨骼的旋转,自动旋转和/或位移。特殊的旋转关键帧,在VRD文件中被称为“触发器”,用于将驱动骨骼的运动范围映射到程序化骨骼的运动范围。
带有沿轴扭转骨骼的人的前臂,是Source中程序化骨骼的典型示例。当手部骨骼顺时针旋转时,前臂中的扭转骨骼也会自动顺时针旋转。当手部骨骼逆时针旋转时,扭转骨骼同样会逆时针旋转。这两种旋转的范围都可以在VRD文件中轻松控制。
简单来说,在Source引擎的定义里,程序骨就是一种“由程序控制的骨骼”。通过一定的驱动配置,程序骨跟随驱动骨的移动而移动,从而在不手动指定程序骨动画的情况下,实现程序骨的移动
而VRD文件,就是记录程序骨驱动内容的文件,所以它也就经常被叫做VRD防穿模
程序化骨骼的实例
那么程序骨在哪里有用呢?对于我们这种做啥比二次元的模型作者来说,最显然的一种用法当然就是裙摆了
在现代游戏和模型中,裙摆经常由不同的方法来驱动防止其与大腿穿模。我们暂且不讨论“把裙摆跟裤子一样当成一个不会飘动的固定的物体”这种很抽象但是最简单的实现,我们来看看能让裙子自己飘动的写法:
比如MMD使用的VRM,以及VRC模型本身,都是设定一个针对骨骼的“碰撞体”,用“碰撞体”控制骨骼之间是否碰撞,来实现“裙子被大腿顶着”的效果
而起源作为一款老引擎,自然没有这么方便的方法来防穿模,所以我们就需要学会去使用程序骨了。
以下是两个例子,左边是没有配置程序骨的裙子,右边是配置了的,相信一眼就可以看出不一样:
感谢被薅出来的智可的演示(x)
除了裙子这种以外,程序骨还有另外的不那么啥比二次元的用法
在转模的制作中,由于我们是将原有的模型骨架迁移到游戏的角色骨架上的,所以不可避免的遇到不适配的情况
比如说,在Garry’s Mod的PM中,玩家右手的根骨骼都是ValveBiped.Bip01_R_Hand
但是在Eku/Milfy的素体中,有一根Wrist_support.R,是用来修正右手臂动作的
如果不使用这跟骨骼修正,有些比较极端的动作就可能让Eku/Milfy的素体出现穿模
所以,我们就需要把这跟Wrist_support.R设置为由ValveBiped.Bip01_R_Hand驱动的程序骨,才能解决问题,这个问题在制作C-Hand手模的时候还挺容易遇见的
VRD文件的构成
V社在在线文档中为我们提供了VRD的写法,如下:
<helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L<basepos> -0.0003 -4.7578 -0.000685692<trigger> 90 -0.140879 -7.0729 0.923253 2.05439e-06 -0.00011566 -0.0109454 0 0 0<trigger> 90 -157.919 -89.6281 158.827 0.101044 -61.3622 -0.505184 0 0 0<trigger> 90 -0.905463 81.1157 0.0128013 -1.79037e-05 49.6029 -0.0109647 0 0 0
<helper> hlp_forearm_R bip_lowerArm_R bip_lowerArm_R bip_hand_R<basepos> -0.0502548 4.76207 -0.0109539<trigger> 90 -0.116485 -7.07782 0.923253 -26.1455 -71.739 -60.6497 0 0 0<trigger> 90 -0.288436 72.9621 0.610626 -72.1773 -44.2586 -20.2743 0 0 0<trigger> 90 -179.149 -81.8242 -179.905 81.3212 -37.0352 -157.273 0 0 0在编写完成之后,VRD通过以下代码,从模型编译文件中调用,进入编译生产:
$proceduralbones <configuration file>我们可以看到,标准的VRD由多个<helper>构成,每一个<helper>块构成了一组VRD的驱动块
一组VRD的驱动块,需要一个<basepos>,作为程序化骨骼在其父骨骼的本地坐标系中的参考平移位置,然后就是若干个<trigger>,<trigger>会作为关键帧,用来实现姿态的参考
不过,在现在,我们完全可以不使用人工编写的方法来编写VRD,下面,我们将介绍利用NekoMDL进行VRD编写的操作
NekoMDL与程序骨自动生成
更好 更快 更强的mdl编译器 - nekomdl
——Starfelll佬如是介绍NekoMDL
NekoMDL是什么?
NekoMDL是Starfelll大佬开发的一款模型编译器,Starfelll大佬是做L4D2工具开发的(顺带一提,大佬最近的作品就是L4N框架和NekoToon渲染器,恐怖如斯),但是由于Source 1的模型编译器的通用性,使得此工具也可兼容到Garry’s Mod模型开发
目前NekoMDL的官方获取方式仅为L4D2创意工坊,如要获取,请:
安装NekoMDL
- 通过Steam创意工坊订阅NekoMDL
- 等待L4D2完成创意工坊缓存工作
- 前往
/Left 4 Dead 2/left4dead2/addons/workshop,寻找3142607978.vpk - 解压,在Crowbar配置NekoMDL为模型编译器
为什么要使用NekoMDL?
NekoMDL在v0.4.0就引入了命令$NekoDriverBone,可以从Blender导出的动画关键帧直接作为参考生成VRD的<trigger>
从我们刚刚的介绍也可以看出,一个<trigger>本质就是一个动画的关键帧,这也是为什么$NekoDriverBone可以实现这个效果
如何利用NekoMDL生成程序骨?
我懒了,这个等以后如果真的要写完整流程记录再说吧。。。
大家可以参考下面这个视频,我们后面来给它的流程纠纠错:
关于我最近研究的想法
手腕和手,其实可以映射到现实世界人类的骨骼关系
记住这点,在做程序骨的时候,尤其是在做人形模型的时候,最好还是把你要做的模型看成你,考虑好骨骼关系
——涅普智可刚刚如是写到
发生了什么
好了,为什么我要在这里重新强调这么一句话呢?
在我之前按照视频的教程完成模型之后,我发现了这么一个问题:

因为我此前就是按照教程完成的程序骨,所以我当时没考虑这么多,这个问题就一直被我丢在这丢了好几个月
解决方法
最近搜了一些资料,发现了一个运行在Blender 4.5+上的BlenderSourceTools魔改分支:PulseSrcOps
这里面带了一个能在Blender内部编写VRD的功能(虽然最后我是觉得还是用NekoMDL好点),而且最关键的,它支持从VRD中导入程序骨约束定义,并且生成在Blender动作编辑器里
我去,还有这种好事?
然后我就用这个工具导入了几位佬的模型,看看人家的VRD是怎么编写的
然后就发现:先前的教程教了错的东西,也不一定说是错的吧,但是一定是容易出问题的方法
先前的教程的关键帧为:腿向前90°、向侧90°、向后90°
这肯定是最符合编写直觉的操作,但是,如果您现在自己站起来,这样子蹬蹬腿,您平时会有意的让侧向和后向蹬腿到90°吗?
所以,几位佬的方案都是:腿先向前90°、然后维持向前,向侧转30°、最后复位腿,再向侧30°
这就是为什么我刚刚莫名其妙的强调骨骼关系这件事,也就是我这次研究搞明白的
然后我就站起来向后蹬了蹬腿,想了想,又加了一条向后30°的约束,大概像下面这样:
弄好,然后导入游戏,搞定!

问题成因
其实我也不是很清楚为什么会发生这种事情,所以我就来猜猜吧:
我的猜想是,程序骨是根据关键帧生成的,但是根据关键帧参考生成的结果的不急会很怪异
简单来说就是,我们肯定是假设程序是根据关键帧的结果,平滑的生成程序骨映射嘛
但可能实际程序上的映射会更激进一点,导致出现裙子被诡异的支撑起来的样子
不过,这样映射之后,裙子肯定还是会有没被映射到的地方
所以我建议,如果显然不是人类能做出的动作,我们就专门做一个不含有飘骨的模型,然后用Overhauled Bone Tool手动接管所有骨骼参数,摆出我们要的动作
总结
这次发现的东西简单来说就是,用下面这个步骤设置关键帧动作:
关键帧的设置
- 先设置腿向前转90°
- 在上一帧的基础上,腿向外侧转30°
- 把腿恢复到原状态,设置腿向侧转30°
- 把腿恢复到原状态,设置腿向后转30°
然后编译的模型的裙子就正常啦,可喜可贺可喜可贺
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 1 天
部分内容可能已过时







