in VRM 勉強会 5

VRM 1.0 に向けた、正規化の問題点の整理と解決案の提示
TokageITLab.
シルク・レニューはじめに発表時間の都合上、かなり内容を削ぎ落としたスライドになっています。
記事の方で詳しく解説を行っているので、スライドの内容について理解を深めたい方はそちらを読むことを推奨します。

https://qiita.com/TokageItLab/items/e5880123a9f508b2769d

自己紹介
シルク・レニュー／トカゲ
・VRM 1.0 のリポジトリでよく文句言ってる
・Godot Engine の 3D ボーンアニメーション周りのコントリビューター
・最近は Blender Add-on を作ったりもしてる

TokageITLabviridflow※最近人気上昇中の Godot Engine
Facebook Reality Labsからの寄付を受け VR 対応が加速している

本題

VRM 1.0 では
ローカル軸の方向（ボーンのレスト回転）を保持するべきなぜ今更？
現在の正規化の仕様ではUnity 上で VRM はなんとなく正常に動くように見えてしまっているがUnity 外の環境になるとそうはいかなくなる
正規化のせいで…

glTF ネイティブな Godot や three.js (three-vrm) 上でVRM をアバターとして動かすのは難しい※表示するぐらいならできるケド

VRM 1.0 はプラットフォームを越えた汎用性を目指す

ローカル軸の方向の定義と正規化の実装の問題に向き合う必要があるそもそも正規化って何してるの？
全てのボーンのローカル軸の方向を破棄する→オイラーで言うと X 軸 Y 軸 Z 軸全てのレスト回転を 0°に強制する
ローカル軸の方向（レスト回転）とはそれぞれのボーンのローカル座標における X Y Z 軸がどの方向を向いているかという情報
例えば、X 軸回転をさせる時にどの方向へ回転するかという情報※レストはポーズを付ける時の基点という意味

本当に捨ててもいい情報なのだろうか？

ローカル軸の方向という情報を捨ててはいけない！
ローカル軸の方向が必要となる場面は非常に多い！

ローカル軸の方向を破棄した際に起きる問題
斜めのボーン（親指や足）を曲げるべき方向が分からなくなる

・斜めのボーンをオイラー角で制御する時、ボーンを曲げる方向がおかしくなる・アニメーションのように同じ値を複数のモデルに適用する時、斜めのボーンで意図しない変形が起こる

ローカル軸の方向を破棄した際に起きる問題
VRMSpringBone・VRMConstraint で回転方向の制御が不可能
例えば DynamicBone であれば回転方向の制限が可能であり、下図のような場合、 FreezeAxes に X を指定すれば誤った回転を防止できる
ヒンジジョイントローカル軸の方向を破棄した際に起きる問題
VRMSpringBone・VRMConstraint で回転方向の制御が不可能
しかし VRM のように正規化でローカル軸の方向を破棄するとX・Y・Z のような軸指定の制御は不可能
VRM 内部の SpringBone・Constaint で回転方向の制御ができないだけではなくDynamicBone・FinalIK のようなローカル軸を使うプラグインが正常に動かなくなるローカル軸の方向が破棄されているのにUnity や VRM Addon はどうやって制御してるの？

Unity や VRM Addon はどうやって制御してるの？
ローカル軸の方向がないモデルをなんとか動かすための２つの技術
Unity（リターゲット）

VRM Addon（方向推定）※実は VRM Addon で Blender に読み込んだモデルはボーンが推定後の向きになっているので VRM の定義を満たしてない

ローカル軸の書き換えや推定でモデルのローカル軸の方向に関係なく制御する→ VRM 正規化の影響を無視して制御しているリターゲットや方向推定があれば問題ないのか？
「Unity Humanoid で親指が歪む問題」に代表するようにリターゲット・方向推定後のローカル軸は元のローカル軸と異なるので正規化前の状態はどうやっても再現できない
故に、「斜めのボーンの回転軸が分からない」「ローカル軸を使うプラグインが壊れる」
これらの問題についてローカル軸を保持する以外に解決方法はなくリターゲットや方向推定ではどうにもならないリターゲットや方向推定があれば問題ないのか？
ローカル軸問題への対策として手動で再設定させる事を考えているらしいが…

・二度手間・データの量が増える
・開発時の前提条件がブレる

再設定は根本的な解決方法ではない

https://github.com/vrm-c/UniVRM/issues/731

現状の正規化による問題点の整理・リターゲットシステムのない環境でポージングやアニメーションの作成が困難
・ボーンを曲げる方向が正確に分からず、デザイナーの意図した変形ができない
・揺れものや IK、コンストレイント等における回転軸の制限が困難
・結局ローカル軸の方向が必要になり方向推定や再設定を行う二度手間が発生

正規化のせいで脱 Unity や機能追加が難しくなっているのではないか？

ローカル軸に関わる問題を解決する為の新たな定義と正規化の実装方法を考えよう回転軸の役割を優先した定義の提案

回転軸の役割を優先した定義の提案
まず、関節に対する回転の操作を「屈伸」「捻り」「開閉」の３つと考える
定義の考え方・SpringBone や Blender に合わせてロール軸方向は親から子へ向かい +Y
・曲げ回転（筋肉が縮まる時の回転）を左半身右半身とも +X で統一
・スケール 1.0 の右手直交系という前提で２軸が決まると Z 軸が自動的に決まる
結果

回転軸の役割を優先した定義の提案

全てのボーンで +X 回転を行うと、胎児のように縮こまるポーズになる（腰や肩は大きく動かすと潰れるのでとりあえず手足のみ操作した画像）

回転軸の役割を優先した定義の提案
新：提案する定義（推奨値は一例）
ボーン名

グローバルレスト回転（推奨値）
Basis

Spine

LeftUpperArm

LeftThumbProximal

Basis

Basis

(旧：VRM 0.x の定義

屈伸

捻り

開閉

1 0 00 1 00 0 1

X軸

Y軸

Z軸

0 0 -1
1 0 00 -1 0

X軸

Y軸

Z軸

X軸

Y軸

Z軸

( )
( )

0.707 0.5-0.5
0.707 -0.5
0.50-0.707 -0.707)※直感的な規定変換行列での定義を推奨

ボーン名

グローバルレスト回転（強制）

屈伸

捻り開閉

Spine

Quat(0,0,0,1)

X 軸？

Y 軸？

Z 軸？

LeftUpperArm

Quat(0,0,0,1)

Z 軸？

X 軸？

Y 軸？

LeftThumbProximal

Quat(0,0,0,1)

XY 軸？

XZ 軸？

YZ 軸？

レスト回転は推奨値であり強制するものではない
アバターとしてはボーンの回転操作の役割が曖昧な事が問題なので回転軸の役割を優先すべし
VRM 0.x の定義ではレスト回転を統一した結果、斜めのボーンに関して回転軸が決まらない

情報を破棄しない正規化実装の提案

情報を破棄しない正規化実装の提案
一般的な編集ソフト上で再現できる定義であればリギングのガイドラインやサンプルプロジェクトを用意できる（VRM 0.x の定義ではガイドラインがあってもその通りリギングできない）

正規化という技術者しか理解できないような仕様によって意図しない変形をされたり、プラグインが正常に動作しないような「ユーザーの分からない所で何かが起こる」ことよりも「書いてある通りの曲げ方ができるようにしてね」というガイドラインを用意して従ってもらう方がより良いユーザーエクスペリエンスを提供できるのではないか

情報を破棄しない正規化実装の提案とはいえ数値を用いた機械的な補助は必要
ボーン名
LeftUpperArm

グローバルレスト回転（推奨値）
Basis( )0 0 -1
1 0 0
0 -1 0

屈伸

捻り

開閉

X軸

Y軸

Z軸

推奨値を定義しておけば推奨値との差分を計算する事ができるので、差分の大きさによって「推奨範囲外」という警告を出して修正を促す事は可能
既存の回転値を推奨値へ強制するリターゲットも補助として存在するなら有用念を押すが、定義するのはあくまで推奨値であり、デザイナーが意図的に推奨範囲外の値を設定することは十分考えられるので警告は出しても強制すべきではないローカル軸の定義と正規化実装を改善した際のメリット
デザイナー
・多くの編集ソフト上で定義をそのまま利用できる・リギングの指標が分かりやすくなる
・意図した変形をアバター利用者へ伝える事ができる
・アニメーションの作成や共有がリターゲットがなくても容易になる

プログラマー
・リターゲットや方向推定が必須ではなくなる
・ローカル軸を参照した移動や回転方向の制御が可能
・ボーン削減による負荷軽減 ※VRMSpringBone 末端の方向推定用ボーンが不要になる・ボーンを制御するパラメータの実装が容易になる

定義をきちんと行いローカル軸を保持した時のメリットは大きいまとめ
ボーンの方向を揃える必要性 → 分かる
元の情報を破棄してボーンの方向を揃える → やりすぎ編集のための情報は確かに必要ないが…

現在の VRM はアバターをアバターとしてアニメーションさせる為に必要な情報まで破棄してしまっている
ボーンの方向を揃えるにしてもいくつかやり方がある「必要な情報まで失わない」正規化実装を行うべし

VRM 1.0 は VRM 0.x との互換性を考えなくてもよい滅多にない機会
ここでローカル軸の方向の定義と正規化処理の実装を見直す事でプラットフォームを超えた汎用アバターフォーマットとしてあらゆる glTF をサポートするプラットフォームへ進出するというスタートラインに立てるのではないでしょうか宣伝
Godot Engine

実は MToon や VRMSpringBone を含めVRM を Godot で利用できるようにするアドオンを有志のメンバーで開発中
Godot の公式メンバーで glTF パイプラインのコアコントリビューターである
Ernest Lee 氏もアドオンの開発に関わっておりGodot 公式ブログにも VRM の事が載っている（Godot が VRM を公式サポートする訳ではないので注意）

ただし、今回説明した正規化の問題のせいで雲行きが良くない
https://godotengine.org/article/introducing-the-godot-gltf-2-0-scene-exporter

宣伝
V-Sekai※指〜〜〜…

海外発の開発中 Godot 製オープンソース VR メタバース（VRM 対応予定）
https://v-sekai.org/

謝辞
情報提供や調査協力、ファクトチェックを行って頂きました
以下の方々に感謝致します
・Ernest Lee (Godot Member, Core Contributor 3D pipeline of Godot)
・Saracen (V-Sekai)
・Lyuma (V-Sekai)
・lox9973 (ShaderMotion)・Silent (Starlit Wanderings, Silent's Cel Shading Shader)・fuka mizno (sirokiri)

VRM で Unity プラグインが正常に動かなくなった
Unity 外の環境で VRM が使いづらくて困っている
VRM が使える場面をもっと増やしたい
脱 Unity を目指している

これらに該当するあなた！
記事の方を共有してくださると助かります！
https://qiita.com/TokageItLab/items/e5880123a9f508b2769d

ご静聴ありがとうございました！