ご存じの方も多いかもしれませんが、Beat Saber は 1.29.4 から Unity のバージョンが変更になり、内部的には仕様が変更され、一部の mod やアセットには大きな影響を与えるものになっています。
とは言っても、ユーザーから見ると、特にゲームの見た目が変わったわけではないですし、機能が増えたわけでもないので、なにが変わったのか?よくわからないと思います。今回はこちらについて書いてみます。
今回のアップデートで、大きな影響がある部分は、VR API の変更と、VR レンダリング方式の変更があり、下記のようになっています。
Beat Saber 1.29.1
- Unity 2019.4.28
- VR API: OpenVR または Oculus (LibOVR)
- VR レンダリング: シングルパスステレオレンダリング
Beat Saber 1.29.4
- Unity 2021.3.16
- VR API: OpenXR
- VR レンダリング: シングルパスインスタンシングレンダリング
今回はこの VR API の変更について解説していきます。
まず VR API と言われてもなんだかわからないと思いますが、ソフトウェア (ゲーム) から VR ハードウェアにアクセスするための取り決め、と言えばわかりやす…くないですね。例を挙げてみましょう。
たとえば、VR コントローラーの位置を取得するプログラムを作りたい、としましょう。この場合、OpenVR という VR API を使用すれば、プログラムのコード中で GetDeviceToAbsoluteTrackingPose という命令を実行することで、トラッキングされているデバイスの位置情報を取得することができます。
VR デバイスは Quest、Index、PICO4 など多数存在しますが、OpenVR 上で動いてる限り、どのデバイスであっても、同じ GetDeviceToAbsoluteTrackingPose という命令でトラッキング情報を取得することができます。これが API の便利なところです。
それでは、なぜ今回、別の OpenXR という API に移行してしまったのでしょう?これは、OpenVR が Steam に依存する API で、Steam が介在しないところでは使用できない、という問題があるからです。
たとえば Beat Saber は Oculus Store でも PC 版が販売されていますが、この Oculus Store の PC 版 Beat Saber は Steam が入っていない環境でも動く必要があります。また、PC の介在しない、Quest 単体で動く Beat Saber もありますね。これらの場合、OpenVR は使用できないので、コントローラーの位置情報を取得するのに、さきほどの GetDeviceToAbsoluteTrackingPose は使用できません。
それではどうしていたのかというと、Oculus には Oculus の VR API があり、こちらには ovr_GetTrackingState という命令で、トラッキング情報を取得できるようになっています。
つまりゲーム側は、今ゲームが OpenVR (SteamVR) で動いているのか、Oculus VR で動いているのかを判別して、どちらの API を使用すべきなのか切り替えていたわけです。もちろん、使用する API は位置情報のひとつだけで済むものではないので、かなり面倒なことになります。
(実際のところ、Beat Saber は Unity を通してトラッキング情報を取得しているので、直接に GetDeviceToAbsoluteTrackingPose を呼んでいるわけではないですが、Unity にどちらの API を使わせるかの指定は必要ですし、細かい部分で、処理の切り分けが必要になっています)
そこで出てきたのが OpenXR です。名前が似ていて混同しそうですが、OpenVR と OpenXR は別です。今までは下図の左のように、Steam であったり Oculus であったりが別々の API を提供していて、すべての VR デバイスをサポートしようとすると、アプリ (ゲーム) 側は複数の API を内包する必要がありましたが、それでは冗長な上に大変なので、統一した新しい API を皆で作りました、というのが図の右の OpenXR になります。
これにより、アプリ (ゲーム) は、今動いているのが SteamVR 上なのか、Oculus のプラットフォーム上なのか、違いを気にすることなく、プログラムを書くことができるようになるわけです。最高ですね。
となれば良かったのですが、良いことばかりではありません。まず、新しい API に移行すると、今までの API は使用できなくなります。Unity にそのあたりを全面的に任せていた場合は、Unity が OpenXR にも対応しているので、変更部分は小さくて済む場合もあります。
逆に、がっつり OpenVR 依存のプログラムを書いていた場合は、その部分がまるごと動かなくなります。NalulunaAvatars や NalulunaSpaceCalibrator のように…。なぜこれらの mod が、トラッキング情報の取得を Unity に任せていないのかというと、Beat Saber が使用していた Unity 2019.4.xx には一定数以上のトラッキングデバイスは見えなくなる、という致命的な不具合があり、トラッカーをたくさん接続したときに認識できない問題を回避するためには、自前で OpenVR の API を呼ぶしかなかったのです…。
API が統一されたのは良いですが、プログラムから呼ばれた API を解釈して、実際に VR のハードウェアとやりとりする部分を作るのは、Steam (Valve) であったり Oculus (Meta) であったりの仕事になります。そして、場合によっては OS 上に複数の OpenXR 実装が存在する、というややこしい状況になってしまいます。
再び先ほどの図を出しますが、赤丸で囲った部分を見てください。一番下の VR デバイスまで行く道は Steam の道を通るか、Oculus の道を通るか…、どの道を通るかはユーザーが選択できる形になっています。
そして…、現実はこの理想図のようにあらゆる VR デバイスへ道がつながっているわけではなく、たとえば Valve Index を使用する場合、Oculus や Windows MR の道を選んでしまったら動きません。
Meta Quest など、Meta の VR デバイスを使用している場合は、Steam か Oculus の道を選んでいれば動きます。しかし、どちらでも動いてしまうだけに、困った事態に陥っている可能性もあります。というのも、Steam の道を選んでしまった場合、フレームレートが安定しないなど、いちおう動きながらも不具合が発生している場合が多いからです。
今まではユーザーが何も考える必要はなく、SteamVR で起動すれば OpenVR で、Oculus ストアから (あるいは -vrmode oculus で) 起動すれば、Oculus VR で動いていたものが、ゲームが OpenXR に移行してからは、ユーザー側で正しい選択をする必要があり、現状、トラブルを誘発する状況になっていると思います。
もし Quest を使用していて、Beat Saber をアップデートしてから、やけにカクカクする、トレイルが変に乱れる、などの症状が発生している場合は、OpenXR ランタイムに Steam が選択されているかもしれません。下記の「OpenXR ランタイムの選び方 (Meta デバイス)」を確認してみてください。
上は OpenXR ランタイムの選択が間違っている状態の Beat Saber (Quest Link) のフレームタイミンググラフです。CPU、GPU の負荷は問題ないにも関わらず、コンポジターの処理時間が異常で、常に処理落ちが発生し、フレームレートが半分になってしまっています。
Meta Quest、Oculus Rift など Meta のデバイスの場合、
Oculus アプリを起動し、設定の中にある「OpenXRランタイム」のところで「Oculusをアクティブに設定」をクリックします。
下のようになっていれば OK です。
Valve Index、VIVE、PICO 4 などの Steam VR デバイスの場合です。他の会社の VR HMD を同時使用していなければ通常問題ないと思いますが、Oculus アプリが入っている場合などは、そちらが選択されている可能性もあります。
SteamVR の設定を開いて、左下の詳細設定を「表示」にし、「開発者」を開いて、「STEAMVRをOPENXRランタイムとして設定」をクリックします。
下のようになっていれば OK です。
アップデートで何が変わったのか?OpenXR とは何なのか?ユーザーの視点からではよくわからない部分だと思うので、なるべくわかりやすく書いてみましたが、うまく伝わったでしょうか。
OpenXR ランタイムの選択については、あまり意識されていない方が多いと思いますが、トラブルになりやすい部分だと思います。この記事がみなさんのお役にたてば幸いです。
Neko-Hangten
2023-06-28 11:59:34 +0000 UTCなるるるるな / NALULUNA
2023-06-28 10:24:00 +0000 UTCNeko-Hangten
2023-06-28 10:17:57 +0000 UTC