[Omniverse] CloudXRのARを試す その2

  • by

OmniverseのCloudXRについて、もう少し理解が進んだ部分がありますので補足します。

Omniverse Create 2021.3.7と、CloudXR ARCore Client ver.1.0(ar-sample.apk)を使用しています。
ar-sample.apkは、「Omniverseのインストールフォルダ\pkg\create-2021.3.7\kit\xrclients\googlear」内にあるものを使用しました。

CloudXRのストリーミングの仕組み

CloudXRについて、もう少し分かりやすく書くようにします。
CloudXRのドキュメントは「 https://docs.nvidia.com/cloudxr-sdk/index.html 」にあります。
CloudXRは、「RGBA画像」をスマートフォンやタブレットにストリーミング配信しAR/VRを実現しています。
画像を作成して配信を行う元をサーバ、それを受け取るスマートフォンやタブレットをクライアントと呼ぶことにします。


Omniverseはサーバを担当することになります。
レンダリングした2D画像から背景を除去し(XR Compositing)、RGBA画像を作成します。
背景の透過部はAlpha成分が0になります。
Wi-Fiを通してクライアントのスマートフォンまたはタブレットに画像をストリーミングします。
※ 2021/11/27現在は、対応端末はAndroidのみのようです。

クライアント側から端末の位置や姿勢(向き)がサーバ側に随時送られ、サーバ側ではリアルタイムでカメラ位置/向きを更新しレンダリングを行ってクライアントに配信、という流れになります。

スマホでは処理しきれない大規模なシーンや複雑なレンダリング(パストレーシングも可能。これは後述します)をOmniverse側で行うことにより、
スマホのスペック以上のAR表現が可能になります。

CloudXRのクライアント(ar-sample.apk)のプロジェクト/ソースファイルはどこ ?

「Omniverseのインストールフォルダ\pkg\create-2021.3.7\kit\xrclients\googlear」内にreadme.txtがあり、ここにGitHubのURLが記載されていました。

https://github.com/NVIDIA/CloudXR/blob/master/arcore-android-sdk/samples/hello_cloudxr_c

のようです。
オープンソースなのですね。

パストレーシングを使用

Omniverseでは「RTX Real-time」と「RTX Path-traced」をリアルタイム用途で使用できます。

※ Irayはリアルタイム向けではないため説明から省きます。

「RTX Real-time」は主に直接照明のみのリアルタイムレイトレーシングのため、結構なfpsが確保できます。
対して、「RTX Path-traced」はパストレーシングのレンダリングになり、大域照明も含まれます。
ただし、「RTX Real-time」よりも速度は遅いです。
「RTX Path-traced」は数秒でじわっとレンダリングされるため、AR/VRのようなある程度高いfpsを求める用途の場合は不向きではあります。

ですが、「RTX Path-traced」使用時でも劇的にレンダリングを速度を上げる手段があります。
「Render Settings」の「Path Tracing」で「Total Samples per Pixel」をデフォルトの64から5に変更しました。

これで、1.05秒かかっていたレンダリングが0.05秒に短縮できました。

値が小さすぎると間接照明の計算が行き届かないことになるため眠くなってしまいます。
後、シーンによっては1や2を指定した場合に、Omniverse側でサンプリングミス?か何かでエラーになり、クライアント側でうまく反映されないことがありました。
3-5あたりがリアルタイム用途としては適値かなと思います。

パストレーシング時の1フレームのレンダリング時間がViewportに表示されない場合は、HUD-StatsのPathTracingをオンにします。

CloudXRに渡す画像解像度を低くして、速度を最適化

Tablet ARウィンドウで「Relative Size of XR Buffer」はデフォルトは1.0です。
これは、AR/VRする場合の解像度を調整するオプションになります。
ここを0.8などのように小さくすることで粗くはなりますが若干速度アップします。

CloudXRに渡す画像をリサイズで調整するだけではなく、Omniverseのレンダリング画像サイズ自身もここで変化するようです。
特にレイトレーシングの場合はレンダリングピクセル数をいかに少なくするかが速度に貢献するため、このパラメータは有効になります。

ただし、値をさらに小さくするとスマホ側でうまく反映されなくなりました。
こちらの環境では0.7はNGでした。0.8は問題なしです。

クライアント側でちらつく ?

サーバ側の処理が重い(かどうかは断言できないですが、、、)と
スマホ(Pixel 4a)のカメラからの映像にオーバーラップされるRGBA画像がちらつき、
不安定になる場合がありました。
ある程度fpsを確保する条件があるのかもしれません。

半透明や屈折/ミラー表現は苦手

CloudXRはRGBA画像のストリーミングになるため、半透明や屈折表現は整合性をとるのが難しいように思いました。
半透明についてはOmniverseのレンダリングはできているのですが、
CloudXRに渡されるときのXR CompositingでDepthがある部分が採用され、それ以外はクリップされるようで、
半透明が消えてしまいます。

また、Depthのある透過をOmniSurfaceでなんとかすることはできますが、その場合はレンダリング時の背景(Dome Lightの指定)が透過先として反映されることになります。
屈折表現も同じです。
そのため、いざARした場合にクライアントのカメラの背景を採用するわけではないため、
正確な透過や屈折が表現できません。
また、ミラーのようなラフネスが0に近い場合の反射もDome Lightの映り込みは問題になります。

この場合、下の画像がARとしてオーバーラップされることになります。
透過(屈折)や反射が、実際のクライアントのカメラからの映像とは異なることになるというのが分かりますでしょうか。

このあたりはストリーミングでARする場合の避けられない点になりそうですので、表現として意図的に使わないほうがよいのかもしれません。
なお、半透明でニセ影を与えるときのようなフェイクについては、後処理で対処できそうではあります(しょせん2D画像なわけなので)。

最近調べていたCloudXRについて、現状分かっていることを記載しました。
背景のDome Lightを指定時のライティングの整合性はある程度詰めることができるため、次回そのあたりを記載予定です。