Slide 1

Slide 1 text

UniVRM 利用アプリケーションの VRM 1.0 への移行について @Santarh

Slide 2

Slide 2 text

この LT を聞いて嬉しくなれるひと - UniVRM アプリのシステムを VRM 1.0 にアップデートするのに 必要なことを知りたい人 - VRM モデルを読み込む Unity アプリを既に作っている人 - VRM 1.0 モデルを読み込む Unity アプリを作ってみたい人

Slide 3

Slide 3 text

この LT で話すこと - UniVRM アプリのシステムを VRM 1.0 にアップデートするために必要な 機能の差分 - UniVRM の VRM 1.0 に関する各 API の概要 この LT で話さないこと - UniVRM 1.0 の各 API の詳細な使い方

Slide 4

Slide 4 text

自己紹介 名前   Santarh(さんたー) 所属   株式会社バーチャルキャスト 何してる リアルタイム 3DCG 周りのエンジニアリング全般      VRM 1.0 Spec / UniVRM / MToon Contributor 最近   機械学習による画像生成の試行      RTX 4090 買ってしまった…… Twitter @santarh

Slide 5

Slide 5 text

VRM 1.0 についての概要 - VR 向け 3D アバターファイルフォーマット VRM の正式な規格 - そもそもいままでの VRM 0.x はベータバージョンだった - 従来の VRM 0.x をベースに、ユーザ要望の大きかった機能を取り入れつつ glTF 拡張として整合性のある規格を策定 - トランスフォーム正規化の部分撤廃、表情機能の充実、コンストレイント、etc - 2022 年 9 月(先月)に規格が正式リリース済み - UniVRM は v0.104.0 以降、VRM 1.0 を正式にサポート - まだまだ最低限の機能しかない

Slide 6

Slide 6 text

UniVRM アプリのシステムを VRM 1.0 へ アップデートする上での機能の差分 1. インストール 2. ロード 3. ライセンス 4. 表情操作 5. ボーン操作 6. マテリアル・シェーダ 7. VRM 1.0 で追加されるが、モデル読み込み側で気にしなくて良い機能

Slide 7

Slide 7 text

UniVRM 0.x UniVRM 1.0 UniVRM アプリのシステムを VRM 1.0 へ アップデートする上での機能の差分 このスライド上での表記説明 従来の VRM 0.x 用の実装のこと 新しい VRM 1.0 用の実装のこと

Slide 8

Slide 8 text

VRM 1.0 の動作確認 - サンプルモデル - https://github.com/vrm-c/vrm-specification/tree/master/samples - UniVRM 内のランタイムロードサンプル - UniVRM/Assets/VRM10_Samples/VRM10Viewer - VRM 1.0 対応アプリ・サービス - バーチャルキャスト (VR アバターとして使用可能) - VRoid Hub (Web 上でのモデルのプレビューが可能)

Slide 9

Slide 9 text

1. インストール - UniVRM-0.xxx.y_zzzz - UniVRM_Samples-0.xxx.y_zzzz - VRM-0.xxx.y_zzzz - VRM_Samples-0.xxx.y_zzzz インストールすべき UnityPackage の変更(両立もできます) UniVRM 0.x UniVRM 1.0

Slide 10

Slide 10 text

1. インストール - com.vrmc.gltf - com.vrmc.vrmshaders - com.vrmc.univrm UniVRM 0.x - com.vrmc.gltf - com.vrmc.vrmshaders - com.vrmc.vrm UniVRM 1.0 インストールすべき UPM Package の変更(両立もできます)

Slide 11

Slide 11 text

2. ロード UniVRM 0.x UniVRM 1.0 UniVRM 1.0 に切り替えても、従来の VRM 0.x ファイルを読み込めます VRM 0.x ファイル VRM 1.0 ファイル 自動変換 される! ファイル システム

Slide 12

Slide 12 text

2. ロード public async Task LoadAsync(byte[] data, string name) { var gltfData = new GlbBinaryParser(data, name).Parse(); var vrmData = new VRMData(gltfData); var context = new VRMImporterContext(vrmData); var instance = await context.LoadAsync(new ImmediateCaller()); return instance.gameObject; } UniVRM 0.x public async Task LoadAsync(byte[] data) { var instance = await Vrm10.LoadBytesAsync(data); return instance.gameObject; } UniVRM 1.0 ロード用の関数が簡潔になります

Slide 13

Slide 13 text

2. ロード UniVRM 0.x UniVRM 1.0 Root VRMMeta VRMBlendShapeProxy Animator VRMLookAtHead VRMFirstPerson Root Vrm10Instance Animator Runtime Vrm Meta Expression LookAt FirstPerson Expression LookAt FirstPerson GameObject Component C# class/method ロードしたモデルに付与される MonoBehaviour の型がすべて変わります

Slide 14

Slide 14 text

FirstPerson Runtime Vrm 2. ロード UniVRM 0.x UniVRM 1.0 Root VRMMeta VRMBlendShapeProxy Animator VRMLookAtHead VRMFirstPerson Animator Meta Expression LookAt FirstPerson Expression LookAt ひとつの MonoBehaviour に統合 Root Vrm10Instance GameObject Component C# class/method ロードしたモデルに付与される MonoBehaviour の型がすべて変わります

Slide 15

Slide 15 text

FirstPerson 2. ロード UniVRM 0.x UniVRM 1.0 イミュータブルな情報とミュータブルな情報で格納場所が分かれます Root VRMMeta VRMBlendShapeProxy Animator VRMLookAtHead VRMFirstPerson Animator Meta Expression LookAt FirstPerson Expression LookAt Runtime Vrm モデル固有で不変な 情報を格納 ランタイムに操作する コントローラを格納 Root Vrm10Instance モデル名 とか 表情操作 API とか GameObject Component C# class/method

Slide 16

Slide 16 text

FirstPerson Animator Root Vrm10Instance Runtime Vrm 2. ロード UniVRM 0.x UniVRM 1.0 モデル名やライセンスなどのメタ情報コンポーネント Root VRMBlendShapeProxy Animator VRMLookAtHead VRMFirstPerson Expression LookAt FirstPerson Expression LookAt VRMMeta Meta モデル情報 GameObject Component C# class/method

Slide 17

Slide 17 text

Animator Root Vrm10Instance Runtime Vrm Root Animator VRMLookAtHead FirstPerson LookAt VRMMeta Meta 2. ロード UniVRM 0.x UniVRM 1.0 表情操作コンポーネント VRMFirstPerson LookAt FirstPerson Expression Expression 表情一覧 表情操作 VRMBlendShapeProxy GameObject Component C# class/method

Slide 18

Slide 18 text

FirstPerson Animator Root Vrm10Instance Runtime Vrm Root VRMBlendShapeProxy Animator Expression FirstPerson Expression VRMMeta Meta 2. ロード UniVRM 0.x UniVRM 1.0 視線操作コンポーネント VRMFirstPerson VRMLookAtHead LookAt LookAt 設定値 操作 API GameObject Component C# class/method

Slide 19

Slide 19 text

Animator Root Vrm10Instance Runtime Vrm Root VRMBlendShapeProxy Animator VRMLookAtHead Expression FirstPerson Expression LookAt VRMMeta Meta 2. ロード UniVRM 0.x UniVRM 1.0 VR 用の一人称視点生成コンポーネント LookAt VRMFirstPerson 設定値 FirstPerson 生成 API (?) GameObject Component C# class/method

Slide 20

Slide 20 text

3. ライセンス UniVRM 0.x UniVRM 1.0 それぞれのファイルに応じたライセンスを使用ユーザに提示する必要があります VRM 0.x ファイル VRM 1.0 ファイル VRM 0.x モデル ライセンス情報 VRM 0.x モデル ライセンス情報 VRM Public License 1.0 ライセンス情報は 変換できない! ファイル システム

Slide 21

Slide 21 text

3. ライセンス public async Task LoadModel(byte[] data) => await Vrm10.LoadBytesAsync(data, vrmMetaInformationCallback: Callback); private void Callback(Texture2D thumb, Meta vrm10Meta, Vrm0Meta vrm0Meta) { if (vrm10Meta != null) { // VRM Public License 1.0 from the VRM 1.0 model. var modelName = vrm10Meta.Name; var authors = vrm10Meta.Authors; } else if (vrm0Meta != null) { // VRM 0.x License from the VRM 0.x model. var modelName = vrm0Meta.title; var author = vrm0Meta.author; } } UniVRM 1.0 それぞれのファイルに応じたライセンスを使用ユーザに提示する必要があります

Slide 22

Slide 22 text

4. 表情操作 概念の名前が適切な名前に変わります UniVRM 0.x UniVRM 1.0 VRMBlendShape Expression

Slide 23

Slide 23 text

4. 表情操作 - 喜 joy - 怒 angry - 哀 sorrow - 楽 fun - 喜 happy - 怒 angry - 哀 sad - 楽 relaxed - 驚 surprised デフォルト定義の表情の種類が増えます・命名が適切なものに変わります UniVRM 0.x UniVRM 1.0 - A - I - U - E - O - Aa - Ih - Ou - Ee - Oh

Slide 24

Slide 24 text

4. 表情操作 型やメソッドが変わりますが、API の使用感自体は変わりません public void SetFacial(GameObject root) { var controller = root.GetComponent(); var facial = new Dictionary { {BlendShapeKey.CreateFromPreset(BlendShapePreset.Fun), 1.0f}, {BlendShapeKey.CreateFromPreset(BlendShapePreset.A), 1.0f}, }; controller.SetValues(facial); } UniVRM 0.x UniVRM 1.0 public void SetFacial(GameObject root) { var controller = root.GetComponent().Runtime.Expression; var facial = new Dictionary { {ExpressionKey.Happy, 1.0f}, {ExpressionKey.Aa, 1.0f}, }; controller.SetWeights(facial); }

Slide 25

Slide 25 text

5. ボーン操作 UniVRM 0.x と同じように、正規化された状態でのボーン操作ができます public void SetTPose(GameObject root) { var animator = root.GetComponent(); foreach (var bone in AllBones) { var tf = animator.GetBoneTransform(bone); if (tf == null) continue; // Enforce T-Pose tf.localRotation = Quaternion.identity; } } UniVRM 0.x UniVRM 1.0 変更なし

Slide 26

Slide 26 text

5. ボーン操作 ボーン操作の API が従来と同じであるために、内部構造は変わっています UniVRM 0.x UniVRM 1.0 Root Animator Model Bone Root SkinnedMesh Renderer GetBoneTransform() ModelMesh Model Bone (正規化されてる) GameObject Component C# class/method Root Animator Model Bone Root SkinnedMesh Renderer GetBoneTransform() ModelMesh Model Bone (正規化されてない) ControlRig Root ControlRig Bone (正規化されてる) 参照 参照 メッシュ変形 メッシュ変形 コントロール

Slide 27

Slide 27 text

6. マテリアル・シェーダ - Standard - UniGLTF/UniUnlit - VRM/MToon Shader Variant Collection - Assets/VRMShaders/VRM/VRMShaders - Standard - UniGLTF/UniUnlit - VRM10/MToon10 Shader Variant Collection - Assets/VRMShaders/VRM10/VRM10Shaders ビルドに含める必要のあるシェーダの変更 UniVRM 0.x UniVRM 1.0 間違ってる…

Slide 28

Slide 28 text

表情の競合を解決する機能「オーバーライド」が追加(モデル制作者側が設定) UniVRM 0.x UniVRM 1.0 JOY WEIGHT:1.0 HAPPY WEIGHT:1.0 BLINK WEIGHT:1.0 BLINK WEIGHT:1.0 7. VRM 1.0 で追加されるが モデル読み込み側で基本的には気にしなくて良い機能

Slide 29

Slide 29 text

7. VRM 1.0 で追加されるが モデル読み込み側で基本的には気にしなくて良い機能 コンストレイント機能の追加(モデル制作者側が設定) 左腕ボーンに追従して動く 普通のボーン コンストレイント UniVRM 1.0 Animator で取得できる 左腕ボーン Vrm10Runtime 内で Expression 等と同じタイミングで処理されます

Slide 30

Slide 30 text

まとめ - 概念はほぼ対応するが、具体的な型やメソッドは変わる - ロード関数は簡潔になる - ライセンス提示は 0.x モデルを考慮すると2種類の実装が必要 - 表情操作 API はほぼ変わらない - ボーン操作は変える必要が無い - ビルドに含めるべきシェーダは変わる GetComponent() してたところの 保守が一番大変そう

Slide 31

Slide 31 text

参考リンク - VRM 1.0 の仕様 - https://github.com/vrm-c/vrm-specification - UniVRM - https://github.com/vrm-c/UniVRM