デコシノニッキ

デコシノニッキ

ホロレンジャーの戦いの記録

Reprojectionについて整理する

さらっと更新がかかっていたドキュメント。 描画の安定化周りで、HoloLens 2から微妙に変わっていたので整理します。

docs.microsoft.com

シーンで起こるアニメーションやユーザーが頭を動かす時の動きと視点の変化を考慮し、HoloLens は Reprojection(再投影) と呼ばれる描画を安定化させるテクニックを使っています。

Reprojectionには 4つの方法があります

手法の種類

HoloLens 2 から、 Depth Reprojection という新しいキーワードが登場します。 基本的に、Depth Reprojection を今後使うことが推奨です。

手法 詳細
Depth Reprojection (深度再投影) 最小労力で、最も効果的。レンダリングされるシーンの全ての部分が、ユーザーからの距離に基づいて独立して、 安定化される。深度に急激な変化がある場合、一部のレンダリングアーティファクトが表示される場合がある。このオプションは、HoloLens 2および没入型ヘッドセットでのみ使用できる。
Planar Reprojection (平面再投影) アプリケーション側で安定化を正確に制御できる。平面はアプリケーションによって設定され、その平面上のすべてがシーンの最も安定した部分になります。 ホログラムが平面から離れるほど、安定性が低下する。 このオプションは、すべてのWindows MRプラットフォームで使用できます。
Automatic Planar Reprojection (自動平面再投影) 深度バッファの情報を使用して安定化平面を設定する。このオプションは、HoloLens generation 1およびHoloLens 2で使用できる。
None (何もしない) アプリケーションが何もしない場合、安定化平面をユーザーの視線方向に2メートルに固定して平面再投影が使用される。これは通常、標準以下の結果。

手法の大別

手法を分けると、深度ベースの描画安定化と平面ベースの安定化で分けることができます。

  • 深度ベース: Depth Reprojection
  • 平面ベース: Planar Reprojection、Automatic Planar Reprojection

Automatic Planar Reprojection は一見深度を使っているので深度っぽいがそうではないです。

簡単に言うと、平面上にある部分の描画だけが安定して描画される仕組み。 何もしなければ、基本的に自動的にカメラの常に2m先にこの平面がありますが、見たいオブジェクトや場所がカメラの常に2m先にあるなんて言う話はあり得ないので、アプリケーションからはAPIや設定を通してこの平面の位置を決めてあげる必要があります。

f:id:haikage1755:20191206100845p:plain

Planar Reprojection では奥行をカメラから飛ばしたレイとコライダーの衝突によって得ています。Stabilization Plane Modifier というスクリプトの中身を見ると良く分かります。一方、Automatic Planar Reprojection ではこれを代わりにカメラのDepth 情報から今見ている場所との距離を算出し、それっぽいところに置いてくれているようです。

f:id:haikage1755:20191206101050g:plain

www.tattichan.work

www.tattichan.work

手法の有効化

細かい設定がどうのこうの書いてありますが、今のUnity環境であれば、XR supported にチェックを入れれば自動的に、HoloLens 2 はDepth Reprojection、 HoloLens 1 は Automatic Planar Reprojection になります。

手法 詳細
Depth Reprojection アプリケーションは、レンダリングされたフレームごとに深度バッファーをシステムに送信する。 Unityでは、[Player Settings] の [Enable Depth Buffer Sharing] オプションを有効にすることで使える。SetFocusPointAPIを呼び出してはいけない。
Planar Reprojection (平面再投影) すべてのフレームで、アプリケーションがシステムに安定させる平面の位置を伝える。 Unity では SetFocusPointForFrameを呼び出し、「Enable Depth Buffer Sharing」を無効にする必要がある。
Automatic Planar Reprojection (自動平面再投影) これを有効にするには、アプリケーションはDepth Reprojectionの場合と同様に深度バッファをシステムに送信する必要がある。 HoloLens 2では、アプリケーションはフレームごとに0,0のポイントでSetFocusPointを設定する必要がある。 HoloLens gen 1の場合、アプリケーションはSetFocusPointを呼び出してはいけない。

MRTK 2.2 からは Camera Profile からこの設定を変更することができます。

f:id:haikage1755:20191206101315p:plain

手法の選択

Unity バージョンをあげて、2018.4.13f1にしておくのがいいと思います。

Stabilization Type ImmersiveHeadsets HoloLens gen 1 HoloLens 2
Depth Reprojection 推奨 N/A 推奨 ※Unity 2018.4.12以降またはUnity 2019.3以降を使用する必要あり。それ以外の場合は、Automatic Planar Reprojectionを使用。
Planar Reprojection N/A デフォルト推奨 Depth Reprojection が良くない場合に推奨。 ※Unity 2018.4.12以降またはUnity 2019.3以降を推奨。以前バージョンは、わずかに劣化した再投影結果になる。
Automatic Planar Reprojection 非推奨 Automatic Planar が良くない場合に推奨。 どちらのDepthオプションでも目的の結果が得られない場合。

深度が正しく設定されていることを確認する

Views -> Hologram Stability から確認できます。 f:id:haikage1755:20191206100621p:plain

Show depth or plane in headset. を使用すると、Depthや平面が可視化されます。 ※ この設定はMRCでは反映されない

Depth Reprojection が有効な場合 青い部分が深度が適切に設定された部分。赤い部分は、深度が設定されていない部分。 赤い部分が大きいほど修正が必要となる。 f:id:haikage1755:20191206100639p:plain

Planar Reprojection と Automatic Planar Reprojection が有効な場合 青い格子平面が、FocusPlane f:id:haikage1755:20191206100651p:plain

深度で問題が起きているとき

深度がレンダリングされたホログラムと一致しない場合、レンダリングで目に見えるグリッチが発生します。
(ドキュメントではグリッチという言葉が使われていますが、もう少し分かりやすく言うと描画に歪みのようなものが発生します。)

  • ユーザーインターフェイスオーバーレイのレンダリングに使用される2番目のカメラがある場合、実際のビューからすべての深度情報を上書きする可能性がある。
  • 透明なオブジェクトは多くの場合、深度を設定しない。
  • 一部のテキストレンダリングは、デフォルトでは深さを設定しない。

Unityから深度バッファを確認する

MRTK 2.2 には深度バッファを確認する機能がついています。文字シェーダーなどは深度書き込みを行っていないのでこのように切り替えると真っ白になります。

f:id:haikage1755:20191205233409p:plain

f:id:haikage1755:20191205233221g:plain

Reprojection設定を上書きする

Device Portal からは上記設定を上書きすることが可能になります(が、使うのかこれ…)。

f:id:haikage1755:20191206100709p:plain

[デコシノニッキ]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」