ホログラム安定化 — MRTK2

パフォーマンス

基盤となる Mixed Reality プラットフォームとデバイスが最適な結果を生むためには、一定のフレーム レートを達成することが重要です。 ターゲット フレーム レート (例: 60 FPS または 90 FPS) は、プラットフォームとデバイスによって異なります。 ただし、フレーム レートを満たしている Mixed Reality アプリケーションは、安定したホログラムを持ち、ヘッド トラッキングやハンド トラッキングなどを効率的に行うことができます。

環境追跡

安定したホログラフィック レンダリングは、プラットフォームとデバイスによる頭部姿勢のトラッキングに大きく依存しています。 Unity は、基になるプラットフォームによって推定および提供されるカメラの姿勢から各フレームのシーンをレンダリングします。 この追跡で実際の頭部の動きが正しく追従されない場合、ホログラムの視覚的な表示は不正確になります。 これは、ユーザーが仮想ホログラムを実際の世界に関連付けることができる HoloLens などの AR デバイスでは特に明らかで重要です。 パフォーマンスは、信頼性の高いヘッド トラッキングのために重要ですが、その他にも重要な機能がある場合があります。 ユーザー エクスペリエンスに影響を与える環境要素の種類は、対象となるプラットフォームの特性によって異なります。

Windows Mixed Reality

Windows Mixed Reality プラットフォームには、プラットフォームでのホログラムの安定化に関する参照資料がいくつか用意されています。 ユーザーに対するホログラムの視覚効果を向上させるために開発者が利用できる主要なツールがいくつかあります。

深度バッファーの共有

Unity 開発者は、アプリケーションの深度バッファーをプラットフォームと共有するオプションを使用できます。 これにより、現在のフレームに対してホログラムが存在する場合に、プラットフォームが Late-Stage Reprojection (遅延ステージ再投影) と呼ばれるハードウェア支援型のプロセスを通じて、ホログラムを安定化するために利用できる情報が提供されます。

Late-Stage Reprojection (遅延ステージ再投影)

フレームのレンダリングの最後に、Windows Mixed Reality プラットフォームは、アプリケーションによって生成された色および深度のレンダー ターゲットを取得し、最後の頭部姿勢の予測以降のわずかな頭部の動きを考慮して、最終画面出力を変換します。 アプリケーションのゲーム ループの実行には時間がかかります。 たとえば、60 FPS の場合、アプリケーションがフレームをレンダリングするのに最長で 16.667 ミリ秒かかることを意味します。 これは非常に短い時間のように思えるかもしれませんが、ユーザーの頭部の位置と向きが変わり、その結果、レンダリング時にカメラの新しい投影マトリックスが生成されます。 遅延ステージ再投影は、この新しいパースペクティブに対応するために最終イメージのピクセルを変換します。

ピクセルごとまたは補正平面の LSR

Windows Mixed Reality デバイスで実行されているデバイスのエンドポイントと OS のバージョンによっては、Late-Stage Reprojection アルゴリズムがピクセルごとに、または補正平面を介して実行されます。

ピクセル単位の深度ベース

ピクセル単位の深度ベースの再投影では、深度バッファーを利用してピクセルあたりのイメージ出力が変更されるため、さまざまな距離でホログラムが安定化されます。 たとえば、1 m 離れた場所にある球体が、10 m 離れた柱の前にあるとします。 ユーザーが頭を少し傾けた場合に、球を表すピクセルは、柱を表す遠く離れたピクセルとは異なる変換になります。 ピクセルごとの再投影では、すべてのピクセルでこの距離の差が考慮され、より正確な再投影が行われます。

補正平面

プラットフォームと共有するための正確な深度バッファーを作成できない場合、別の形式の LSR では補正平面が使用されます。 シーン内のすべてのホログラムはいくつかの補正を受けますが、目的の平面にあるホログラムは、ハードウェアの最大の補正を受けます。 平面の頂点と法線は、Unity によって提供される HolographicSettings.SetFocusPointForFrame API を使用してプラットフォームに提供できます。

深度バッファーの形式

開発用に HoloLens を対象とする場合は、24 ビットではなく、16 ビット深度バッファー形式を使用することを強くお勧めします。 これにより、パフォーマンスを大幅に節約できますが、深度値の精度が低くなります。 低い精度を補正し、z ファイティングを回避するには、ファー クリップ プレーンを Unity によって設定された 1000 m の既定値から減らすことをお勧めします。

Note

"16 ビットの深度フォーマット" を使用する場合、この設定では Unity はステンシル バッファーを作成しないため、ステンシル バッファーを必要とする効果は機能しません。 "24 ビットの深度の形式" を選択した場合、エンドポイントのグラフィックス プラットフォームが対応する場合は、通常、8 ビットのステンシル バッファーが作成されます。

Unity での深度バッファーの共有

深度ベースの LSR を利用するには、開発者が行う必要がある重要な手順が 2 つあります。

  1. [編集]>[プロジェクト設定]>[プレーヤー]>[XR 設定]>[Virtual Reality SDK]>[深度バッファー共有] を有効にします。
    1. HoloLens をターゲットにする場合は、16 ビット深度の形式も選択することをお勧めします。
  2. 画面に色をレンダリングすると、深度もレンダリングされます

Unity のOpaque GameObjects は、通常、自動的に深度に書き込みます。 ただし、通常、透明なオブジェクトおよびテキスト オブジェクトは、既定では深度に書き込みません。 MRTK 標準シェーダーまたは Text Mesh Pro を利用している場合は、これを簡単に解決できます。

Note

シーン内のどのオブジェクトが深度バッファーに視覚的に書き込まれないかをすばやく調べるには、MRTK 構成プロファイルの [エディターの設定] の下にある [レンダー深度バッファー] ユーティリティを使用できます。

透明の MRTK 標準シェーダー

MRTK 標準シェーダーを使用した透明な素材の場合は、素材を選択して [インスペクター] ウィンドウで表示します。 次に、[今すぐ修正] ボタンをクリックして、素材を深度に書き込むために変換します (例: Z 書込みオン)。

変更前

Depth Buffer Before Fix MRTK Standard Shader

クリック後

Depth Buffer Fixed MRTK Standard Shader

Text Mesh Pro

Text Mesh Pro オブジェクトの場合は、TMP GameObject を選択してインスペクターで表示します。 素材コンポーネントで、割り当てられた素材のシェーダーを MRTK TextMeshPro シェーダーを使用するように切り替えます。

Text Mesh Pro Depth Buffer Fix

カスタム シェーダー

カスタム シェーダーを作成する場合は、ZWrite フラグPass ブロック定義の先頭に追加して、深度バッファーに書き込むようにシェーダーを構成します。

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
不透明による支援

上記のメソッドが特定のシナリオ (つまり、Unity UI を使用) で機能しない場合は、別のオブジェクトを用意して深度バッファーに書き込むことができます。 一般的な例としては、シーンのフローティング パネルで Unity UI テキストを使用することが挙げられます。 パネルを不透明にするか、少なくとも深度に書き込むことによって、テキストとパネルの両方の z 値が互いに近接しているため、プラットフォームによって安定します。

WorldAnchors (HoloLens)

視覚的な安定性を確保するために正しい構成が満たされていることを確認すると共に、ホログラムを正しい物理的な場所で安定した状態に保つことが重要です。 開発者は、物理領域内の重要な場所をプラットフォームに通知するために、1 つの場所に留まる必要がある GameObjects の WorldAnchors を活用できます。 WorldAnchor は、そのオブジェクトの変換を完全に制御する、GameObject に追加するコンポーネントです。

HoloLens などのデバイスは、常にスキャンを行い、環境について学習しています。 したがって、HoloLens が空間内の移動や位置を追跡するときに、その推定値が更新されて Unity の座標系が調整されます。 たとえば、GameObject が開始時にカメラから 1 m の場所に置かれていて、HoloLens によって環境が追跡されるときに、GameObject が配置されている物理的な地点が実際には 1.1 m 離れていることが検知される場合があります。 これにより、ホログラムのずれが生成されます。 WorldAnchor を GameObject に適用すると、アンカーはオブジェクトの変換を制御できるようになります。これにより、オブジェクトは正しい物理的な場所に保持されます (つまり、実行時に 1 m ではなく 1.1 m の距離に更新されます)。 アプリ セッション間で WorldAnchors を維持するために、開発者は WorldAnchorStore を使用して WorldAnchors を保存し、読み込むことができます。

Note

WorldAnchor コンポーネントを GameObject に追加した後は、その GameObject の変換 (つまり、transform.position = x) を変更することはできません。 開発者は、変換を編集するために WorldAnchor を削除する必要があります。

WorldAnchor m_anchor;

public void AddAnchor()
{
    this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}

public void RemoveAnchor()
{
    DestroyImmediate(m_anchor);
}

アンカーを手動で操作する方法については、Microsoft ワールドロック ツールを確認してください。

関連項目