Avatar 参数分布时间同步架构:白皮书

分布时间同步是一个用于大幅减少 Synced Parameter Bit 消耗的主动系统,以容纳超过 256 bit Synced Parameter Bits 的同步参数,由此允许开发者在 Avatar 内容纳更多功能。

封面图标:creatiforest

本书信息


本书在作者根据自身知识撰写并由人工智能优化可读性,内容可能出现错误,对你的 Avatar 进行任何操作前,确保你已经进行了备份。

前言与摘要

前言


LIII Works 一直鼓励开发者手动进行 Avatar 的开发,而不仅仅依赖于自动化工具。

然而,令人遗憾的是,大多数开发者只能完成最基本的物体开关操作,或是利用 Modular Avatar 或 VRCFury 将其他创作者已经打包好的内容安装到自己的 Avatar 上,却缺乏调整这些内容以及在出现错误时排除问题的能力。

实际上,前述开发者中有相当一部分人并没有真正的学习心态。换言之,他们只求现成的成果,而不愿学习获取成果的方法。此外,他们对传授知识的玩家缺乏应有的耐心和态度。

鉴于此,我在此发布本技术概念白皮书,希望能够启发那些真正想要学习本篇技术概念的开发者。

祝各位开发者好运。
 


摘要


本白皮书《Avatar 参数分布时间同步架构:白皮书》旨在介绍一种用于大幅减少 Synced Parameter Bit 消耗的主动系统,从而使 Avatar 能够容纳超过 256 bit 的同步参数。本白皮书将详细阐述该系统的概念,指导玩家如何根据自身需求为其 Avatar 构建所需的参数分布时间同步系统,以便在一个 Avatar 中容纳更多功能或更复杂的功能。除此之外,玩家也可在具有类似功能的自动工具发生错误时能够排解故障

通过了解该系统,玩家可以显著减少 Avatar 的 Synced Parameter Bit 消耗,从而实现更丰富和复杂的功能。然而,设计和实现该系统需要深入理解 VRChat 的 Avatar Parameter 网络同步机制,以及对远端和本地概念的深刻理解。这些概念的掌握和系统的设计具有一定难度,且制作该系统本身也需要投入相当的时间和精力。


分布时间同步的基本概念

阅读该部之前,确保你已经具备所需的前置知识,否则你将难以理解该部内容。

直接同步


现在,假设我们有4个整数需要和远端玩家同步:

如果将他们设置为同步,那么,数值将会通过网络直接抵达远端玩家的客户端。

sync direct.png

直接同步 Parameter 的视觉展示

分布时间同步的基本概念


既然我们已知同步参数的消耗只有在一个参数被标记为Synced (同步) 时才会生效。换句话说,如果一个参数没有被标记为 Sync,那么,这个参数不会消耗同步 bit。

同步参数的数量大,消耗就大,那么,是否有一种办法,可以减少同步的参数的数量,又能将全部信息传递到远端玩家?

分布时间同步就是一种符合这种要求的特殊系统,这种系统将参数同步从同时拆分成多次,在一段时间内分批完成。而分布时间同步的概念与直接同步非常相似,但是传输信息的方式有所改变。


分布时间同步的架构


依然,假设我们有4个整数需要和远端玩家同步,将我方称之为源头,接收方称之为终点:

我们知道,当一个参数被标记为同步,它会通过网络发送到远端。那么,我们可以利用这一点,只需要1个同步参数在中间充当桥梁即可,而每一次同步时,替换同步的源头和终点。

image.png

分布时间同步架构的视觉展示

如果你认为这样来理解还是太抽象的话,就将同步容器想象成一个背包当背着背包去上学的时候,背包里面就放满了课本和文具当背着背包去登山的时候,背包里面就放满了三明治,水,驱蚊水当背着背包去旅行,背包里面就放满了地图,指南针,换洗衣物...

image.png

分布时间同步架构同步 Int_B 时

由此,将同时同步4个整数拆分为分4次同步4个整数。这样,同一时间只需要同步容器是同步的,每一次将不同的参数放入同步容器,一头放入,一头取出,就完成了通过1个同步容器进行4个整数的同步。

同步步骤,Bit 数与延迟


从分布时间同步的架构可以看出,这种将同步从同时同步分散到在一段时间中逐步完成的方法实际上是在用时间换空间

时间换空间的策略是通过增加计算时间来减少内存使用。这种方法通常用于在内存资源有限的情况下,通过重复计算或延迟计算来节省内存。

在当前的情境下,就是通过将参数同步分布到一段时间内逐步完成来减少同时间同步的参数的数量,以此减少 bit 的消耗,这么做也将不可避免地使得参数的同步延后。

同步步骤与延迟的关系

分布时间同步架构本质上是将同步拆分成多次来完成,因此,同步步骤是决定节省 bit 的数量以及同步延迟的重要因素。步骤越多,同步的延迟越大,但同时间要同步的参数也可以减少,同步容器的数量变少,同步的成本也会降低。

反之,同步的步骤越少,同步的延迟就会越小,但就要用越多的同步容器同时对多个参数进行同步,容器的成本就会提高。

这个部分在下个章节中会继续深入。

分布时间同步的技术细节

开始本部前,确保你已具备所需的前置知识,并且了解分布时间同步的基本概念

在VRChat 每隔 0.2秒会对 Avatar 的同步参数发起同步 (Sync Interval(同步间隔) = 0.2s),而同步的信息抵达远端玩家的时间大约在 0.1 - 1.0秒 (Latency = 0.1 ~ 1.0)


同步步骤,Bit 数与延迟 (续)


上一章节提到,同步步骤决定了可节省的 bit 数,以及带来的延迟。

同步步骤可节省的 bit 数可以由以下公式计算:

image.png

计算同步参数 bit 节省的公式

不同类型需(Bool, Int && Float) 需独立计算。 Int 及 Float 可以互相转换而不损失过多精度,固计算和同步时可以视作同一类型

同步步骤带来的延迟可以由以下公式计算:

image.png

计算同步步骤延迟的公式

在某个同步步骤数量下所需的同步容器的数量可以由以下公式计算:

image.png

计算所需同步容器数量的公式

举例,如果有10个integer,在4步同步的情况下:

分布时间同步架构的细节


一个分布时间同步系统的架构包含远端区分发送器接收器同步容器(Bool, Int, Float*),时序标记(Bool)

Int 及 Float 可以互相转换而不损失过多精度,固计算和同步时可以视作同一类型,同步时发射器将 Float 转换为 Int,接收器反之

分布时间同步架构的运行

具体来说,分布时间同步架构的运作逻辑是这样的:

  1. 发射器将要传递的参数数值输入到对应的同步容器内,同时设定好时序标记
  2. 同步容器并且在0.2秒的同步间隔结束后向远端的接收器发送。
  3. 接收器接收到时序标记的变化,将同步容器里的内容保存到它对应的参数中。

重复以上步骤,直到所有步骤完成,即完成一次完整同步,最后从步骤1开始循环。

实现分布时间同步的方法并不唯一,只要符合其原理即可

同步容器 && 时序标记

同步容器和时序标记分别用于承载要同步的参数数值以及指示接收器开始接收内容。同步容器视乎情况,可能需要使用多个以传递所有类型的参数和降低传输延迟。而时序标记则取决于你决定使用多少同步步骤。

将多个时序标记视为一组以二进制表示的数值,容纳步骤数量所需的二进制位数即为时序标记所需的数量:

远端区分

远端区分是一个极为简单的模块,它的唯一作用是在 Avatar 初始化时区分其所属 Avatar 当前为由玩家正在穿着的本地 Avatar,或者是由远端玩家观察的 Avatar,并由此决定该 Avatar 是传输源头还是传输终点。

一般来说,使用 IsLocal做出区分即可。

image.png

远端区分模块的例子

发射器

分布时间同步系统中的发射器负责将本地 Avatar 中的值输入到同步容器中,并且也要负责设定同步时序,以免发送的信息被输入到错误的参数中。

同步参数以每0.2秒的间隔发送,故每个步骤间需间隔0.2秒

image.png

发射器通过 Parameter Driver 将参数储存到同步容器中,以及设定同步时序

接收器

分布时间同步系统中的接收器负责视乎时序,将同步容器中的值输入到对应的参数中。

Wait For Interval 是一个为了防止状态转变过快而使 Parameter Driver 被跳过的安全措施,离开该状态的 Transition 需要勾选 Exit Time,具体 Exit Time 不重要

image.png

接收器通过 Parameter Driver 将同步容器中的信息储存到参数中

选读:VRChat Avatar Parameter 网络同步机制简述

该选读部分由 AI 于受监督的环境下协助完成

如欲了解更多,可参考 Animator Parameters | VRChat Creation

参数同步


参数同步是指将 Avatar 的特定参数传递给其他远端玩家,使得远端玩家一侧的 Avatar 能够接收到这些参数更新,从而执行相应的逻辑和动画。这一机制是确保功能正常运行的基础。

参数同步的实现

要实现参数同步,首先需要将参数添加到 Avatar 的 Playable Layer 动画控制器中。接着,在 Expression Parameters List 中添加一个同名的参数,选择正确的类型并勾选 Sync。如果某个参数仅存在于 Playable Layer 的动画控制器中,那么该参数不会通过网络同步到远端,但其变化可能通过流程间接地同步。

参数同步的限制

每个 Avatar 最多只能使用 256 bit 的参数。具体来说,每个同步的 bool(布尔值 True/False)需占用 1 bit,而一个 int(整数)或 float(浮点数/小数)将占用 7 bit。

同步的类型


在 VRChat 中,参数同步分为三种类型:Speech、Playable 和 IK。每种类型的用途、同步方式、延迟等信息如下:

选读:Parameter Driver 概述

该选读部分由 AI 于受监督的环境下协助完成

如欲了解更多,可参考 Animator Parameters | VRChat Creation

 

Parameter Driver 概述


Parameter Driver 是一种用于修改 Avatar 动画控制器中参数的行为。该行为可以在进入状态时对参数进行多种操作,并且这些操作按从上到下的顺序依次完成。需要注意的是,只有在 VRCExpressionParameter 对象中定义的参数才会在网络中同步。

 
参数操作类型

Avatar Parameter Driver 支持多种参数操作类型,包括 Set、Add、Random 和 Copy。以下是每种操作类型的详细说明:


Set

功能:将指定的值设置为目标参数。
用法:选择操作类型为 Set,指定目标参数和要设置的值。


Add

功能:将指定的值添加到目标参数。
用法:选择操作类型为 Add,指定目标参数和要添加的值。
注意:使用 Add 操作时,建议仅在本地运行,将参数设置为同步,以确保远端的结果一致。


Random

功能:将目标参数设置为介于最小值和最大值之间的随机数。
用法:选择操作类型为 Random,指定目标参数、最小值和最大值。
注意:使用 Random 操作时,建议仅在本地运行,并将参数设置为同步,以确保远端的结果一致。


Copy

功能:将源参数的值复制到目标参数。
用法:选择操作类型为 Copy,指定源参数和目标参数。

尽管你不能直接 Copy VRChat的内置参数,但你依然可以使用例如 BlendTree 或准备一个 Parameter 映射层等办法驱动另一个参数,由此来间接得到 VRChat 的内置参数

尽管官方文档称必须存在于同步参数表中,但即便目标参数不存在于参数同步表中,你依然可以使用 Parameter Driver 来驱动它,只是该变化仅会在本地生效

 
参数范围限制

对于同步的参数,值会被限制在特定范围内:整数参数的范围为 [0, 255],浮点数参数的范围为 [-1, 1]。这些限制确保了参数在网络同步时的稳定性和一致性。

 
Local Only

启用 "Local Only" 选项将使驱动程序仅在本地操作,而不进行网络同步。这是一个快捷的方法,避免了使用 IsLocal 的繁琐步骤。

 
Debug String

每个 Avatar Parameter Driver 操作都可以包含一个调试字符串,当该行为运行时,该字符串将被打印到输出日志中,便于调试和问题排查。