基本原理
简易流程图
下面是一个从现实动作到模型动作的简单流程图,仅供参考,实际情况可能会有所变化。
简单来说,头显发送原始数据到VRCFT,然后通过VRCFT转化UE参数到模型当中,模型通过动画器控制动画驱动模型形态键实现动作。
参数的平滑和参数二进制压缩
根据VRChat的文档和我们自己游玩的经验,我们可以知道VRC的参数同步是有延迟的,一般会隔0.2s左右会向远端(也就是其他玩家)同步一次同步参数。例如我的GestureRightWeight这个float的参数,我在一秒内将他从0变到1,在本地会看到这个过程很平滑,而远端其他玩家就会出现段落感,如图,下面的滑条为这个参数本地变化,上面为远端看到的这个参数的变化情况
即时是本地,也有可能出现数据跳跃,为了避免这个情况,所以我们现在需要将这个参数更好的流畅的同步到远端,并且本地也做一定的平滑处理,常用的平滑处理就是使用内插运算,简单举个例子,就是一个参数从0,在变成0.2的时候,取中值0.1,然后变化到0.3的时候,取得中值0.2,无时无刻进行这个运算,就会平滑的处理参数变化。这整个流程一般称作Smooth。
这时候就需要OSCmooth的作用,我们留在后文讲。
同时,因为面捕涉及的形态键众多,如果每一个形态键都由一个对应的float值来操控的话,如果是ARKit,那就需要52*8=416个参数,UE只会更多,众所周知VRC SDK的话只允许有256个同步参数,这时候我们就需要对参数进行一些压缩,针对一些不需要那么精细的动作,进行二进制压缩。这个流程一般称作Binary。
二进制压缩的基本原理可以理解为,如果我们之前使用一个int参数来表达0、1、2、3、4、5、6、7,总共8个值,占用了8个参数空间,而我们现在使用3个bool参数来实现相同的表达,以下用1和0来表达一个bool的状态,可以得出这个对照表:
int | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
bool | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
这样我们就可以只用3个bool,也就是3个参数空间做到了原本需要8个参数空间的表达,相同的,0-1的float占用8参数空间,我们也可以用3个bool表达一个float,对应的,需要把0-1分成7份,如下表:
float | 0 | 0.143 | 0.286 | 0.429 | 0.571 | 0.714 | 0.857 | 1 |
bool | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
如果增加Bool的数量,能够表达的int值就会更多,float值就会更加细致,但过度增加Bool不仅会徒增参数消耗,同时还收益不高
了解了这些,我们就可以准备接下来的内容了
No Comments