VRM Animation(动画)

VRM Animation

https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm_animation-1.0

什么是“VRM Animation”?

VRM Animation 是一种格式,用于描述在 VRM 中定义的人型模型的动画。

文件的内容

VRM Animation 的用途

通过 VRM Animation,您可以在跨应用程序和模型使用人型模型的动画。

以下是一些 VRM Animation 可能的应用示例:

支持 VRM Animation 的应用程序

showcase

警告
得益于社区的支持,许多应用程序在支持 VRM Animation 的 draft 规范方面进行了合作。VRM Animation 规范刚刚正式发布。如果您使用支持 draft 版本的应用程序,行为可能与正式版不同,或可能无法按预期工作。

备注
若希望在此列表中增加新的应用程序,
请通过 GitHub 提交 issuesPull Request
请务必提供应用程序的名称与网址。

使用 VRM Animation 开发应用程序

VRM-1.0 已支持 VRM-Animation。

import

请参考 import(开发相关)retarget(开发相关)

export

此外,如果 Unity 中存在 humanoid 动画,可以逐帧导出为 VRM-Animation。

EDITOR 专用

请参考 export(开发相关)

VRM-Animation 导入

详情请参考VRM10Viewer(开发相关,无翻译)

VRM-Animation 导出

请参考实装的 BVH Converter 

Assets/VRM10/Editor/VrmAnimationMenu.cs

说明

输入

为了导出 VrmAnimation,需要以下条件:

为了简单地达到以上条件,我们使用了bvh 格式文件。

警告:
如果 BVH 的初始姿势不是 T-Pose,将无法正常工作。

UNITY HUMANOID 不是必须的
使用 Animator.GetBoneTransform 会更简单。

初始化

VRM Animation exporter 使用说明
Transform humanoid_hierarchy;

var data = new ExportingGltfData();
using var exporter = new VrmAnimationExporter(
            data, new GltfExportSettings());
exporter.Prepare(humanoid_hierarchy.gameObject);

VRM Animation exporter 使用说明
exporter.Export((VrmAnimationExporter vrma) =>
{
    // get human bones
    var map = new Dictionary<HumanBodyBones, Transform>();
    var animator = bvh.Root.GetComponent<Animator>();
    foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones)))
    {
        if (bone == HumanBodyBones.LastBone)
        {
            continue;
        }
        var t = animator.GetBoneTransform(bone);
        if (t == null)
        {
            continue;
        }
        map.Add(bone, t);
    }

    vrma.SetPositionBoneAndParent(map[HumanBodyBones.Hips], bvh.Root.transform);

    foreach (var kv in map)
    {
        var vrmBone = Vrm10HumanoidBoneSpecification.ConvertFromUnityBone(kv.Key);
        var parent = GetParentBone(map, vrmBone) ?? bvh.Root.transform;
        vrma.AddRotationBoneAndParent(kv.Key, kv.Value, parent);
    }

推进时间并注册帧

// get animation
    var animation = bvh.Root.gameObject.GetComponent<Animation>();
    var clip = animation.clip;
    var state = animation[clip.name];

    var time = default(TimeSpan);
    for (int i = 0; i < bvh.Bvh.FrameCount; ++i, time += bvh.Bvh.FrameTime)
    {
        state.time = (float)time.TotalSeconds;
        animation.Sample();
        vrma.AddFrame(time);
    }

输出

});
var glb =  data.ToGlbBytes();

提示
这是在通常的 glb 基础上添加了 VRMC_vrm_animation 的版本

解决初始姿态差异的问题

使用与VRM-0.X兼容的数据时,在某些情况下,问题可能不会显现出来,如果...
     •模型骨架
     •动画骨架
都符合VRM兼容的标准化T-Pose,那么无需转换即可运行。

使用 UniVRM 实装的解决方案

在 UniVRM 的 vrm-1.0 中,包含了 ControlRig 这一组件,它能够支持初始姿态的转换。在运行时加载的过程中,ControlRig会自动进行设置和初始化。

使用 ControlRig  操作未标准化的模型(开发相关,无翻译)

也可以让 UNITY 的 MECANIM HUMANOID 代替
如果为运动的源和目标都设置了 humanoid avatar

解决方案

在 UniVRM 之外,也可以实现动画转换。

https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm_animation-1.0/how_to_transform_human_pose.ja.md

模型和动画的骨架需要满足 HumanoidBone 规范并处于 T-Pose,这是必要条件。