2023-05-07 ボンディング・インタラクション
This page is available in English: English
このページは AI(Claude)によって翻訳されています。翻訳に誤りが含まれる可能性があります。
ResilienceVR は、既存のプラットフォームの枠にとらわれずに実験と試行錯誤を重ねるために、私が開発しているソーシャル VR アプリです。
この記事では、最初の実験がどのように動作するかを説明します。レイテンシがあっても、アバターの IK がオブジェクトや他のプレイヤーに反応できるようにする仕組みです。
既存のアプリケーションにおけるネットワーク IK
ソーシャル VR では、ユーザー同士が 1 つの仮想空間でつながっており、たいてい、自分自身を表す 1 つの仮想的な姿(アバター)を操り人形のように操作します。
現在、ソーシャル VR アプリケーションがプレイヤーの仮想的な姿を他のプレイヤーに送る主な方法は 2 つあります。
- アバターの腰の位置とボーンの回転を送る、または
- アバターの重要なボーン(頭や手など)、あるいはハードウェアトラッカーの位置と回転を送る。
これらの方法にはそれぞれ欠点があります。後者の方法では、エンドユーザー側が他のプレイヤーのポーズを推定するために、追加の計算をする必要があります。
いずれにせよ、どちらの方法でも、ネットワークを通じて送るデータ量が大きくなります。そのため、アプリケーションのニーズに応じて規模を拡大するには、さらなる簡略化と最適化が必要です。
一般に、全員のアバターが仮想空間内で互いに近い位置にいる最悪のケースでは、こうしたアプリケーションのネットワーク使用量はプレイヤー数の 2 乗で見積もれます。新しく参加したプレイヤーのデータを、インスタンス内にすでにいる他のすべてのプレイヤーに送る必要があるからです。
最適化をしない場合:
- プレイヤー数が 2 倍になると
10 人のインスタンスは、5 人のインスタンスよりもネットワークへの負荷が 4 倍になります。 - プレイヤー数が 10 倍になると
80 人のインスタンスは、8 人のインスタンスよりもネットワークへの負荷が 100 倍になります。
このスケーリングの問題は、多くの最適化手法の主な動機になっています。静的でないデータをネットワークで送ることには、深刻な金銭的コストがかかりうるからです。
レイテンシの問題
ユーザー同士は依然としてレイテンシによって隔てられており、場合によってはプレイヤー間の遅延が 200 ミリ秒から、まる 1 秒にも及ぶことがあります。
こうした遅延は、プレイヤーが他のプレイヤーの行動に反応して自分のアバターを動かすことを妨げます。手をつなぐ、一緒に踊る、あるいは別のプレイヤーも操作している仮想空間内のオブジェクトを操作しようとすると、レイテンシのために見た目にずれが生じます。
ボンディング・インタラクション
この問題の部分的な解決策として、ResilienceVR では、すべてではないものの、プレイヤー同士の一定程度の反応的なインタラクションを可能にするアプローチを実験しています。ソーシャル VR にはさまざまな文脈がありますが、私が特に関心を持っているのは**ユーザー同士の絆(ボンディング)**です。お互いの体に手を置くことで、手をつないだり、一緒に踊ったりできる手段を提供します。
ここでの目的のために、VR の外では「ビクティム・コントロール」として知られているものに注目します。これは、演技の分野で舞台上の格闘(ステージコンバット)に使われる用語です。格闘シーンを演じるとき、加害者役の俳優は、実際には被害者役を制御していません。被害者役は自由に動く権利を完全に保っています。つまり、ある俳優が被害者役の俳優の頭をつかむ演技をしても、被害者役の頭は、加害者の意志ではなく、被害者自身の意志で自由に動き回れるということです。
私たちのケースでは、誰かの手足を制御しているのは、インタラクションを始めた人ではありません。
文脈は重要なので、この実験では、プレイヤー同士が対立する他のソーシャル VR のインタラクション、たとえば素手で戦う格闘ゲームやガンゲームは対象にしていません。
戦闘に特化したネットワーク処理には、さらなる課題があるかもしれません。たとえば、この文脈では戦闘中のプレイヤー同士が対立しているため、あるプレイヤーが他のプレイヤーの手足の制御を奪えることが必要になるかもしれません。他の誰かがあなたの肘を引き離したら、あなたの手はどうなるでしょうか?「ネットワーク版 Boneworks」は、まったく異なる問題を解くことになるでしょう。これは、ResilienceVR での今後の実験のテーマになるかもしれません。
プレイヤー以外とのインタラクション
このシステムは主にプレイヤー同士のボンディングのために設計されましたが、たまたま、仮想空間内のアイテムやオブジェクト、さらには他のプレイヤーが持っているアイテムとのインタラクションも、簡単に拡張して実現できることがわかりました。
Boneworks や Half-Life: Alyx のようなシングルプレイヤーのゲームに大きく影響を受け、プレイヤーの手がオブジェクトに引き寄せられるように機能を拡張し、その引き寄せを他のプレイヤーにもレイテンシなしで見えるようにしました。
これらのシングルプレイヤーゲームとは違い、リジッドボディのシミュレーションやコリジョンは関与しないため、初歩的な形のインタラクションであることには注意が必要です。
仕組み
簡単に言うと、ローカルプレイヤーの手が、何かに引き寄せられているかどうかを他のプレイヤーに伝えます。つかんだ瞬間には、それをどこでつかんだかを他のプレイヤーに伝えます。データを継続的に送り続けるわけではありません。
その後、各プレイヤーが、それぞれのプレイヤーの手がそれぞれのオブジェクトにどれだけ強く引き寄せられているかを計算し、部分的な IK ソルバーを実行して、ネットワーク IK による手の配置とオブジェクトによる手の配置の中間のどこかに手を置きます。引き寄せが強いほど、オブジェクトに近くなります。
詳細:
ステップ 1:ローカルユーザーが、ネットワーク IK 用にプレイヤーのポーズを保存する
通常の IK ソルバーが実行され、解かれたポーズが、ネットワーク IK の一部として送信できるように保存されます。ネットワーク IK のポーズは、以下のステップで説明するシステム全体が存在しないかのような構成で、常にローカルのデータとともに送信されます。
すべてのユーザーのアバターは、ネットワーク IK に基づいてポーズが取られます。
ステップ 2:ローカルユーザーが、最も魅力的なオブジェクトを見つける
ローカルでは、プレイヤーの手が(すでにオブジェクトをつかんでいない場合)、自分の周りにある、引き寄せられる可能性のあるオブジェクトを探します。
ここでの目的では、プレイヤーの手足は引き寄せられる対象のオブジェクトです。
利用可能なオブジェクトが見つかると、現在の手の配置を前提に、そのオブジェクトに完全に引き寄せられた場合に、手がオブジェクト上のどこに置かれるかを計算します。
手の配置の候補が計算できたら、それぞれの候補について磁化量を計算します。これは、現在の手の配置が、手の配置の候補にどれだけ近いかを示すスカラーの推定値です。また、オブジェクトによっては、他のものより魅力的なものがあります。
磁化量が最大のオブジェクトが勝者となります。
- ユーザーが何かに引き寄せられている場合、ユーザーはどのオブジェクトに引き寄せられているかを他のユーザーに送ります。オブジェクトは、引き寄せられる対象を識別するための数値で表されます。
- ユーザーがそのオブジェクトをつかむと決めた場合、ユーザーはそのオブジェクトに対する手の相対的な位置と回転を送ります。これは、最初につかんだ後は更新されません (例外が 1 つあり、後で説明します)。
- ユーザーが何にも引き寄せられていない場合、ユーザーは、何にも引き寄せられていないという情報を送ります。
この方法の利点は、低コストなことです。イベント駆動です。引き寄せの状態は常に変わるわけではなく、送信されるデータも最小限です。フェーズが変わるとき以外は、ネットワークデータの補間はほとんど必要ありません。
この計算はローカルで行われるため、他のプレイヤーについて、引き寄せられるオブジェクトの探索を実行する必要はありません。そのため、引き寄せ状態への遷移が遅れることがあります。
磁化量は、ユーザー入力を駆動するために再利用できます。磁化量が一定のしきい値を超えたら、ユーザーがそのオブジェクトとインタラクションできるようにするのです。たとえばクライミングに便利です。
磁化量は他のプレイヤーには送信されないことに注意してください。遅延をよりよく考慮に入れるため、磁化量は各プレイヤーのもとで再計算されます。
ステップ 3:すべてのユーザーが、引き寄せられているユーザーについて部分的な IK を実行する
ユーザーは、自分自身も含め、該当するすべてのユーザーについて、IK をローカルで解きます。
IK ソルバーは、次の場合、そのプレイヤーについてローカルでは実行されません。
- そのプレイヤーが見えていないとき、または
- そのプレイヤーが何にも引き寄せられていないとき、または
- そのプレイヤーが、無効になっているオブジェクトに引き寄せられているとき、または
- そのプレイヤーが、非表示になっている誰かのアバター上にあるオブジェクトに引き寄せられているとき(たとえば、カリングされているために Animator が更新されていない場合)
こうすることで、必要のないユーザーを繰り返し処理せずに済みます。
ResilienceVR は独自に書いた IK ソルバーを使っているので、IK のどの部分を、どのように実行するかをより細かく制御できます。そのため、現在ポーズを取っているアバターに基づいて、腕だけを解くことができます。
ユーザーは、その特定のオブジェクトに対する手の配置を計算し、続いて磁化量を計算します。
この磁化量を使って、ネットワーク経由の手の配置と最終的な手の配置の間を補間します。これにより、手は、リモートではなくローカルでオブジェクトに近づくにつれて、そのオブジェクトに引き寄せられていきます。
反復の方法は 2 つあります。
- ソルバーの反復をすべて、ユーザーごとに別々に、すべてのプレイヤーで同じ順序で実行する、または
- 各ユーザーでソルバーの反復を 1 回ずつ実行し、全ユーザーにポーズを適用してから、再び反復する。
どちらにも欠点があります。各ユーザーがお互いの手をつかもうとするシナリオや、お互いの肘をつかもうとするシナリオでは、安定性の問題につながる可能性があり、これはまだ実験が必要です。
相対的な動き(ステップ 2 内)
つかんでいる手を動かしながらも、ネットワーク IK の恩恵を受けられるようにしたいと思っています。
プレイヤーがこの動作を始めると決めたとき、次の内容を含む別のネットワークイベントを送ります。
- この動作を始めた瞬間の手の位置と回転、および
- この動作を始めた瞬間の、持っているオブジェクトの位置と回転。
これはその後更新されないため、補間はありません。ソルバーのフェーズでは、プレイヤーの手をオブジェクトに対する相対的な差分として扱います。これにより、このステップで自前の補間を行わなくても、あらゆるネットワーク IK の滑らかさの恩恵を受けられます。
プレイヤーがこの動作をやめると決めたときは、新しくベイクした位置と回転を含む新しいグラブ動作を送ります。
VRChat での実装
「ResilienceVR IK Demo」という VRChat の Udon ワールドは、上記のシステムを、VRChat プラットフォームの許される制限の範囲内に収めて移植したものです。
現在の Udon は実行速度の遅さが制約になりますが、この成果を披露するには十分です。ResilienceVR からのコードの変更を最小限に抑えたかったため、これは Udon 固有の最適化をほとんど行っていない素朴な移植であることに注意してください。
それでも、簡略化のために IK ソルバーの一部を無効にする必要がありました。もしこれがネイティブな Udon プロジェクトであれば、ソルバーをもっと効率的に書いたでしょう。
VRChat はアバターのメッシュへのアクセスも、ボーンへの書き込みアクセスも提供していません。そこで、ワールド自体にアバターのモデルを SkinnedMeshRenderer として含め、そのアーマチュアを動かすことで、ユーザーがアバターを着ているように見せています。
ワールド内のアバターペデスタルが、ボーンの回転と長さが正しいこと、そして表示されているときに Animator が動作していることを保証します。表示されるメッシュがないために Animator が動作していない場合、Udon の VRCPlayerApi は更新されたボーンの回転を返しません。
この VRChat ワールドは、次のように動作します。
ステップ 1:ローカルユーザーが、ネットワーク IK 用にプレイヤーのポーズを保存する
すべてのプレイヤーのボーンの位置と回転(VRCPlayerApi を使用)を収集し、メモリにコピーします。これらの位置と回転は、IK を解く過程で何度も読み書きされます。
ResilienceVR とは異なり、ネットワーク IK を担当するのは VRChat なので、ワールドから、送信されるボーンに今後影響を与える手立てがない以上、これについて心配する必要はありません。
ステップ 2:ローカルユーザーが、最も魅力的なオブジェクトを見つける
この部分は ResilienceVR とほぼ同じですが、CyanPlayerObjectPool の助けを借りて、Udon の手動同期でイベントを送信します。元のイベント駆動の性質のおかげで、Udon への移植はとても簡単です。
ステップ 3:すべてのユーザーが、引き寄せられているユーザーについて部分的な IK を実行する
Udon はプレイヤーのデータへのアクセスが不十分なため、ほとんどの最適化を実現できません。
この場合、次のものに限定しました。
ユーザーは、自分自身も含め、該当するすべてのユーザーについて、IK をローカルで解きます。
IK ソルバーは、次の場合、そのプレイヤーについてローカルでは実行されません。
- そのプレイヤーが正しいアバターを着ていないとき
- そのプレイヤーが何にも引き寄せられていないとき
プレイヤーが正しいアバターを着ているかどうかは、ヒップ、スパイン、チェスト、ネックそれぞれの間の距離を測ることで検出できます。プレイヤーが同じモデルのオリジナルアバターを着ている場合は、誤検出が起こりえます。
プレイヤーは個別に処理され、ポーズはただちに適用されます。実行順序が結果に影響するため、多少のずれが生じることがあります。
解かれたポーズは、ワールド内にある SkinnedMeshRenderer のアーマチュアのボーンに適用されます。
結果
この実験の結果、自分で体験できる VRChat のワールドが生まれました。私の作品が、既存のソーシャル VR ユーザーに、お気に入りのソーシャル VR プラットフォームにもっと多くを望み、求める気持ちを抱かせるきっかけになればと思っています。
ResilienceVR は、共有したい新しいアイデアを試行錯誤するために使える、ソーシャル VR アプリであり続けます。
プレイヤー同士のインタラクションは、ユーザー体験の面で興味深い課題をたくさん生み出すため、研究すべきことはまだたくさんあります。特に、つかむインタラクションと磁化の強さについては、多くのフィードバックをいただいており、今後取り組んでいくつもりです。
https://twitter.com/vr_hai/status/1653570784999120899
Patreon
Patreon、Pixiv Fanbox で支援してくださっているすべての皆さん、そして Booth で私の無料ツールにチップを贈ってくださった皆さん、ありがとうございます!
私の作品や研究を気に入っていただけたら、Patreon での支援をご検討ください!
Haï~ | creating Virtual reality gimmicks and productivity tools | Patreon
Become a patron of Haï~ today: Get access to exclusive content and experiences on the world’s largest membership platform for artists and creators.