ホログラムの安定化

パフォーマンス

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

環境の追跡

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

Windows Mixed Reality

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

深度バッファーの共有

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

遅延段階の再プロジェクション

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

ピクセルあたりの対安定化平面 LSR

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

ピクセルごとの深度ベース

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

安定化平面

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

深度バッファーの形式

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

注意

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

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

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

  1. [ Edit > Project 設定 > Player > XR 設定 > Virtual Reality sdk >深度バッファーの共有 を有効にします。
    1. HoloLens をターゲットにする場合は、 16 ビット深度形式 も選択することをお勧めします。
  2. 画面に色を表示する場合、深度も表示する

Unity の不透明なオブジェクトは、通常、深さに自動的に書き込まれます。 ただし、通常、透明な & テキストオブジェクトは、既定では深度に書き込まれません。 mrtk 標準シェーダーまたはテキストメッシュ Pro を利用している場合は、これを簡単に解決できます。

注意

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

Transparent MRTK Standard shader

Mrtk Standard shaderを使用した透明な素材の場合は、[インスペクター ] ウィンドウで素材を選択して表示します。 [ 今すぐ修正 ] ボタンをクリックして、素材を [深度に書き込む] に変換します ( Z/書き込み)。

以前

MRTK Standard Shader を修正する前の深度バッファー

クリック後

深度バッファー固定 MRTK Standard Shader

テキストメッシュ Pro

テキストメッシュ Pro オブジェクトの場合は、[TMP] オブジェクトを選択してインスペクターに表示します。 マテリアルコンポーネントで、割り当てられたマテリアルのシェーダーを切り替えて、MRTK TextMeshPro シェーダーを使用します。

テキストメッシュ Pro 深度バッファーの修正

カスタムシェーダー

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

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
不透明なバック

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

WorldAnchors (HoloLens)

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

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

注意

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

WorldAnchor m_anchor;

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

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

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

関連項目