制作/修改动画器
其实制作动画器,真正需要手动操作的,只有上一页面提到的Driver层,其他可以通过OSCmooth来一键生成,当然如果想做到新版本Jerry模版那些细致的功能,可能需要我们去修改代码或者手动更改。
1. 创建一个属于自己的BlendTree
选做:从零开始自己建立混合树
只需要在空白处右键选择From New Blend Tree,就可以自动生成一个混合树,双击进入,初始的BlendTree是什么都没有的,参数也是默认的GestureLeftWeight。
修改为Direct类型,然后从加号处添加新的混合树
在新的混合树中添加控制形态键的动画,同时调整参数为对应的FT/v2/xxxxxx
参数没有的话需要自己手动添加,具体使用何种参数,请参考VRCFaceTracking Parameters | VRCFaceTracking (vrcft.io)
参数在这个阶段是"FT/v2/"前缀,这是没有经过平滑的,后期会经由OSCmooth自动转化为"OSCm/Proxy/FT/v2"前缀
反复进行这些操作,可以制作出来一份完整的Driver图层,但是从头开始做不仅麻烦,还可能会漏掉一些动作,徒增一些没必要的参数消耗,所以我们这里可以选择第二套方案,从模版中进行拷贝动画器,然后使用OSCmooth还原动画器。
从模板中还原动画器
一般来说在Package中的文件比较难加以修改,所以我们可以直接把Jerry的模版从Package中移动到Asset中
这个操作也许需要一点时间,而且期间Unity不会有卡顿感,这会让你觉得没有移动成功,几分钟后切换一下窗口,模版就移动过来啦~
移动成功后,把我们需要的动画器(不想动源文件可以Ctrl+D复制一份)放入一个模型当中,本文以夏菲为例
这时候导入我们的OSCmooth-Github,将我们的模型拖入到其中
选择下方的Revert OSCmooth from Layer,这样就可以将Driver层所有参数的"OSCm/Proxy/FT/v2"前缀,转化回原始的"FT/v2/"前缀,这时候,应该只有Driver一个State,没有Binary图层和Smooth图层。
我们也需要删除一些参数,需要保留的仅有"FT/v2/"前缀的参数,并且不是1/2/4的二进制压缩参数
参数名 | 动画器/本地 | 参数表/远程同步 | 描述 |
EyeTrackingActive | Float | Bool | 眼球追踪开启 |
LipTrackingActive | Float | Bool | 面部追踪开启 |
EyeDilationEnable | Float | Bool | 瞳孔追踪开启(瞳孔放大缩小,仅Tobii系可用) |
FacialExpressionsDisabled | Bool | Bool | 关闭手势表情 |
VisemesEnable | Bool | Bool | 口型同步开启 |
FT/v2/xxxxxx | Float | - | 原始输入的浮点值 |
下面是需要删除的参数,特别注意FT/v2/xxxxxx是要保留的,FT/v2/xxxxxx1;FT/v2/xxxxxx2;FT/v2/xxxxxx4是要删除的
FT/v2/xxxxxx1;FT/v2/xxxxxx2;FT/v2/xxxxxx4 | Bool | Bool | 原始输入的布尔值,之后会经由Binary转换为BinaryOut/FT/v2/xxxxxx |
BinaryOut/FT/v2/xxxxxx | Float | - | 经过Binary后的值,之后会经由Smooth转换为OSCm/Proxy/FT/v2/xxxxxx |
OSCm/Proxy/FT/v2/xxxxxx | Float | - | 经过Smooth后的值,之后会在Driver图层直接驱动形态键 |
OSCm/BlendSet | Float | - | 混合树同时进行的关键参数,请保持为1 |
OSCm/Local/FloatSmoothing | Float | - | 本地参数的通用平滑程度 |
OSCm/Local/PupilDilationSmoothing | Float | - | 本地参数的瞳孔平滑程度 |
OSCm/Remote/EyeLidSmoothing | Float | - | 远程参数的眨眼平滑程度 |
OSCm/Remote/FloatSmoothing | Float | - | 远程参数的通用平滑程度 |
OSCm/Remote/PupilDilationSmoothing | Float | - | 远程参数的瞳孔平滑程度 |
其实正常的删除参数的话,能删除就说明该参数已经没有对应的动画器占用了,所以只要删掉能删掉的就行,如果出现这个提示,说明就是这个参数是不能删的。(前提是已经删掉了Binary和Smooth层)
这时候就可以开始编辑我们想要的Driver层了
2. 修改动画器
1.简单调整动作的幅度
参数从0变到1的过程,LipPucker的形态键也从0变到100
如果想要让LipPucker更快的到达100,那么就需要降低阈值。例如将Lip_Pucker.anim的阈值从1降到0.7,这样能够让参数到达0.7的时候,LipPucker就已经到达100了。
参数相当于是在0-0.7的变化过程就走完了原先的0-1的变化过程,所以更加灵敏了也更加快速了。但这样做会导致参数在0.7-1.0的变化过程中,形态键都会一直在100固定。
而如果觉得不动作效果那么夸张,或者想让动作更慢一些,就需要调高阈值。
同理将Lip_Pucker.anim的阈值从1升到2,那么参数即使达到了1,也只有原先0.5的效果,形态键也就只有50。
一般来说参数的取值范围都是[0,1]或[-1,1],所以降低阈值也是降低了最大值。
还有另一种方法来实现降低动作幅度,就是修改动画的形态键值,可以让Lip_Pucker.anim的关键帧降为70,这样即使是参数到达了1,也只能驱动70的形态键。
2.添加限制
一般情况下,单个动作直接伸出是不会穿模的,但组合动作则会很容易穿模,我们假设一个情况,如果LipPucker单独为100,没问题,JawOpen单独为100,没问题,但LipPucker和JawOpen同时为100的时候,会出现一个穿模问题,那我们现在就需要加以限制。
我们一般在比较不重要的动作做出限制,而重要的动作则直接驱动,相比之下,JawOpen是张大嘴巴,而LipPucker是噘嘴,JawOpen重要性大,我们在LipPucker上加一些逻辑限制。
我们的大体思路是,LipPucker=1且JawOpen=0的时候,形态键LipPucker=100,但如果LipPucker=1且JawOpen=1,则形态键LipPucker=0
那我们就需要修改原本在Lip_Pucker位置的动画为混合树,删除原来的Motion,添加新的BlendTree
修改参数为JawOpen,添加两个Motion。
为了实现JawOpen的限制效果,我们这样填入动画文件
然后最后就有这么一个逻辑:
3.添加联动动作
这里提供一个制作简单联动的例子,供大家参考思路。
在最顶级的根混合树添加一个新的混合树,请记得更改参数让这个混合树正常加入计算,如果想要常驻,那就使用FT/DirectBlend,如果要让联动的动作与眼追或嘴追一起开启,那就更改为LipTrackingActive/EyeTrackingActive。
我们现在要制作一个张大眼睛的时候,如果是嘟嘴,就触发星星眼的效果。这需要联系两种参数,EyeLid和LipFunnel。
首先我们需要录制一个模型的Body上的一个星星眼表情,根据需要可以录制多帧或者单帧。同时我们需要录制一个相同形态键的0值的动画。
如果是多帧动画不想循环,请关闭Anim文件的LoopTime(循环时间)以避免动画循环播放,单帧动画也建议关闭
逻辑:EyeLidLeft和EyeLidRight>0.9,且LipFunnel>0.5时,触发Star
逻辑图如上,需要注意正常的眨眼参数是:0.8默认;0.8→1.0瞪眼;0.8→0闭眼,所以我们选择0.9的时候触发
Star0的位置是靠近且小于0.9的一个数值,而不是正常眼睛下的0.8,因为如果使用0.8到0.9触发的话,会让Star表情有一个慢慢出来的动作,可能会导致一些不必要的视觉BUG,所以要尽可能的缩短这一个行程。关于2D混合树的详细解释,请见本章上一页:动画器详解 | VRCD 文档库。
第二层嵌套使用1D混合树,用LipFunnel参数,同样的,使用了靠近且小于0.5的数值,尽可能让这个行程缩短,不要让Star有渐入渐出的效果。
3. 使用OSCmooth完成后续处理
在我们确定好Driver层已经完工,没有需要新增的参数和新增的混合树之后,我们进入OSCmooth的操作页面进行下一步处理。
将我们做好的Driver层所在的动画器放入Avatar的Playable Layers,然后把Avatar放入OSCmooth中。
红框为自动识别动画器内的参数并填入,篮框内的为全局默认设置,我们可以不用在这里调整。我们点击红框的按钮。
在这里我们需要删掉不带有"FT/v2/"前缀的参数,仅保留面捕Driver中所需要的参数。
LocalSmoothness即是本地平滑参数,最大为1
RemoteSmoothness是远程平滑参数,最大为1
在这里我们需要强调,OSCmooth生成的Smooth层,平滑参数越高,平滑程度越高。
Proxy Conversion是自动将Driver层中的FT/v2前缀参数转换为为平滑后的OSCm/Proxy/FT/v2前缀
Flip Input/Output是将平滑层中的输入和驱动的参数互换,一般情况无需使用
Binary Resolution则是我在基本原理 | VRCD 文档库中讲到的二进制压缩的选择,你可以根据自己的需求来调整,1个Bool就能表达2种情况,2个Bool就是4种情况,3个Bool就是8种情况
Combined Parameter是加入一个反向负值,在为互斥的动作进行参数配给的时候,一般可以使用同一个参数的正负两极来节约参数,这时候可以使用这一个选项,例如MouthX1、MouthX2、MouthX4、MouthXNegative,就能实现MouthX从-1到1的变化,也就是嘴巴的左和右
float | -1 | -0.857 | -0.714 | -0.571 | -0.429 | -0.286 | -0.143 | 0 | 0.143 | 0.286 | 0.429 | 0.571 | 0.714 | 0.857 | 1 |
bool | 111N | 110N | 101N | 100N | 011N | 010N | 001N | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
推荐一些比较实用的平滑程度和二进制压缩程度(仅供参考)
按常理来说,眼皮的闭合程度是非常好被侦测到的,而且眼皮的开合程度也事关表情的表达,所以眼皮我们需要更加精细,一般选择直接使用Float驱动,能够提供最大的精细程度。相同的还有眼球移动、嘴巴开合等,这些都不使用二进制压缩,如下表。
不使用二进制压缩的参数 |
EyeLidLeft/EyeLidRight |
EyeLeftX/EyeRightX |
EyeY |
JawOpen |
MouthClosed |
而使用二进制压缩的话,一般来说3个Bool(8个值)配合平滑层即可还原绝大部分Float的精度了,某些参数可以加上一个Negative来进行相反值的表达,这里列举一些值得更高精度和不需要这么高精度的参数,如下表,没提到的参数都建议使用3个Bool即可。
值得用4个Bool的参数 | 只需用2个Bool的参数 |
MouthUpperUp | NoseSneer |
MouthLowerDown | MouthTightenerLeft/MouthTightenerRight |
MouthX |
LipSuckUpper/LipSuckLower |
|
MouthDimple |
|
MouthPress |
而平滑程度的话,有以下几个参数值得注意,如下表
参数 | 本地平滑度 | 远端平滑度 |
EyeLidLeft/EyeLidRight | 0.15 | 0.7 |
EyeLeftX/EyeRightX | 0.15 | 0.7 |
EyeY |
0.15 |
0.7 |
PupilDilation | 0.7 |
0.95 |
其它参数 |
0.7 |
0.7 |
应用OSCmooth
最后我们点击Apply,OSCmooth将自动生成动画和图层,同时修改我们的Driver层。如果需要删除则使用下面的Revert按钮,记得请按照本页面第一点的方法检查一下删没删干净动画器中的参数哦。
安装成功的话会在动画器的参数表内多出这些参数,同时会多出Binary和Smooth层,同时Driver层中使用的参数都修改了前缀
自动生成的动画在OSCmooth文件夹中
至此,动画器方面已经结束,后续还有部分菜单与参数表内容,请移步至下一页
No Comments