皆さんこんにちは。イーソル エンジニアリング本部 Entertainment課のA.Tです。
イーソルではXR機器・ゲーム機器の開発や、それに関わるアプリケーション開発など、エンタテインメント領域のエンジニアリングサービスを幅広く提供しており多数の実績があります。
本記事ではこちらの記事の後編として、XR技術領域におけるオクルージョンの実現で苦労した点および解決方法をご紹介します。オクルージョンの具体的な実装方法は前編で説明していますので、まだご覧になっていない方はぜひ先に前編をご一読ください。
目次 1. 苦労した点・解決方法 1-1. 凹凸スクリーンの生成について 1-2. RGB映像の投影について 1-3. AndroidベースOSのHMDでの開発 2. 最後に |
1. 苦労した点・解決方法
1-1. 凹凸スクリーンの生成について
「現実世界の映像と仮想世界のオブジェクトのオクルージョン」という要求を達成する方法を考えるのは一苦労でした。
まずは「現実世界の映像から立体を生成して、それと同時に仮想世界のオブジェクトを表示しよう」と考えました。ステレオカメラからの深度情報は「点群データ」として取得することもできるという話も聞いていたので、Unreal Engine上で点群データからオブジェクトを生成するプラグインの使用を考えました。
しかし、見つかるプラグインはオブジェクト生成にある程度の時間を要すものであり、今回のように少なくとも数秒に一度程度のスパンでオブジェクト生成が求められるような使い方には向いていないということが分かりました。
そのため、プラグインに頼らずに自力で実装できるような方法を考えました。結果として、「現実世界の映像から立体を生成して仮想世界のオブジェクトと同時に表示する」というアイデアは変えずに、「現実世界の映像から生成するオブジェクトを、直方体の集合である凹凸スクリーンで表現する」という形に落ち着きました。
この方法は、グレースケール映像として得られるステレオカメラからの深度情報を、スクリーンの面上にそのまま表現すれば良いという点で、より直感的に実装が可能だと思われました。また、複雑な形の立体を1つのメッシュとして生成するという難しい実装を回避し、直方体の座標の制御という比較的容易な実装に落とし込むことができた点でメリットがありました。
余談ですが、スクリーンを構成する大量の直方体を管理する必要があるため、処理を少しでも軽くする方法として、直方体を単なるStatic Meshではなく、Instanced Static Meshとして生成しました。Unreal Engineで大量の類似したアクターを制御する必要がある場合にはお試しください。
参考:Instanced Static Mesh | Epic Developer Community
1-2. RGB映像の投影について
スクリーンへのRGB映像の表示について、結果的にはLight Functionを用いてSpot Lightコンポーネントをプロジェクターとして利用するという方法になりましたが、それ以外にもいくつかの方法を検討していました。
例えば、はじめは直接マテリアルとしてスクリーンに貼るのはどうだろうかと考えました。実際にそうした場合、ちょうど柄のついた布でものを覆ったときのように、全ての面に映像が表示され、スクリーンに垂直な方向から見ると元の映像と比べて見えなくなってしまう部分や歪んだ部分が出てきます。
メッシュにマテリアルを投影する機能として用意されている「デカール」という機能についても検討しましたが、マテリアルを直接適用した場合と同様にスクリーンに垂直な面以外にも包むように映像が表示されてしまいました。
参考:Decal Material | Epic Developer Community
図1 デカールを用いた凹凸スクリーンへのRGB映像の表示
結局、「スクリーンへの投影」という実現したい機能をより素直に実現できる方法として現実のプロジェクターに近い機能を持つLight Functionを利用しようということになりました。
また、Light Functionを利用することになった後も、いくつか問題がありました。
まず、図2を見るとわかるように、映像が投影された凹凸スクリーンを近距離で見ると、凹凸の影になっている部分が目立ってしまいます。開発のはじめはこの図の場合のように、プレイヤーが凹凸スクリーンを直接見ることでオクルージョンを実感する計画でした。しかし、あまりに影が目立つことにより現実との乖離が起こり、オクルージョンの体験が損なわれると考えたため、代替の方法を考えました。
図2 仮想空間でのプレイヤー、スクリーン、プロジェクターの位置関係とプレイヤー視点の映像
(凹凸スクリーンの影を軽減する対応前)
そこで、逆にプレイヤーが非常に遠距離にいる場合はどう見えるかを試してみました。たしかにこの場合は、影は近距離の場合に比べて目立たなくなります。しかし、遠距離にいるプレイヤーがスクリーンの内容を判別できるようにするためには、視野角を非常に小さくする必要があり、そうしてしまうとHMDを被った際の頭部の動きに同期したカメラの移動が体感と乖離してしまいます。
ここまでで、遠距離から小さな視野角でスクリーンを見ることができ、しかもプレイヤー視点のカメラはHMDの胴部の動きと違和感なく同期する必要があるという状況になりました。したがって、凹凸スクリーンを映すカメラとプレイヤー視点のカメラを別にするために、非常に遠距離に非常に小さい視野角のScene Capture 2Dを配置し、凹凸スクリーンをキャプチャし、それをユーザーの眼前の別のスクリーンに表示することにしました。最終的に、仮想空間でのプレイヤー、スクリーン、プロジェクター、カメラの関係は以下の図3のようになりました。
図3 仮想空間でのプレイヤー、スクリーン、プロジェクター、カメラの位置関係とプレイヤー視点の映像
(凹凸スクリーンの影を軽減する対応後)
こうすることで、なるべくスクリーンの凹凸の影を目立たせることなく、しかもプレイヤーのカメラ移動をHMDの頭部の動きに同期させることができました。
1-3. AndroidベースOSのHMDでの開発
今回使用したPICO4を含め、多くのHMDはAndroidベースのOSを採用しています。そのため、本プロジェクトではAndroid環境で実行可能なUnrealプロジェクトを作成する必要がありましたが、その点に関して開発の中で何度か躓くことがありました。
その一つとして、RGB映像のスクリーンへの投影のために用いたLight Functionについて、PCのエディターでは想定通りにRGB映像が投影されている様子が確認できたのに対して、HMDでの実行時には映像が表示されなくなってしまうという現象が起こりました。
図4 モバイルフォワードレンダラー設定時のHMDでのLight Functionによるスクリーンへの投影
映像は表示されず、単なるSpot Lightと同様に単色の光が表示される
調べたところ、Web上の記事に「Light FunctionについてはUnreal EngineのAndroid向けにはサポートされていない」との記述が見られました。そこでさらに調査した結果、以下のサイトを見つけました。
このサイトの記述によると、Unreal Engineのモバイル向けのデフォルトのレンダラーは「モバイルフォワード」と呼ばれるフォワード形式のレンダラーで、軽量化のために一部機能が制限されているとのことでした。そして、Unreal Engineにはこの他に「モバイルディファード」というディファード形式のレンダラーが用意されており、こちらはモバイルフォワードで制限されていたLight Functionなどの機能もサポートしているとのことでした。
実際、このサイトの記述のとおりにUnreal プロジェクト設定において使用するレンダラーをモバイルフォワードからモバイルディファードに変更したところ、HMDの実行環境でも、PCのエディターで表示されたのと同様にRGB映像のスクリーンへの投影が実現できました。
自分がゲームエンジンを用いて開発したのは今回が初めてでしたが、Unreal EngineやUnityなどの主要なゲームエンジンで、WindowsなどのPC環境では機能するがAndroidなどの他のプラットフォームでの動作は保証されていない機能が少なからず存在することが分かりました。XR開発ではむしろPC以外の環境で動作させることが多いため、利用したい機能を見つけたときに、その動作が開発環境において保証されているかを確認する視点が今後は必要になると学びました。
3. 最後に
前編・後編にわたり、Unreal Engineを用いたXRにおけるオクルージョンの実装例についてご紹介しましたが、いかがでしたでしょうか。
冒頭でご紹介した通り、イーソルはエンタテインメント分野のエンジニアリングサービスを提供しており、多様な開発実績があります。
イーソルの強みであるOS、デバイスドライバはもちろん、アプリケーション、クラウドサービス開発などの豊富な経験を活かし、お客様に満足いただけるソリューションをご提供します。
「XR・ゲームなどエンタテインメント分野の開発で課題がある」、「開発の委託について詳しく知りたい」、という方はぜひお気軽にイーソルにご相談ください。
Entertainment課 A.T