OpenXR アプリのベスト プラクティス

以下のベスト プラクティスの例については、BasicXrApp の OpenXRProgram.cpp ファイルをご覧ください。 最初の Run() 関数は、初期化からイベントやレンダリング ループまでの一般的な OpenXR アプリ コード フローをキャプチャします。

ビジュアルの品質と安定性に関するベスト プラクティス

このセクションのベスト プラクティスでは、OpenXR アプリケーションで最善のビジュアル品質と安定性を実現する方法について説明します。

HoloLens 2 固有のパフォーマンスに関するその他の推奨事項については、以下の「HoloLens 2 のパフォーマンスに関するベスト プラクティス」のセクションをご覧ください。

ガンマ補正レンダリング

レンダリング パイプラインがガンマ補正であることを慎重に確認する必要があります。 スワップチェーンにレンダリングする場合、レンダー ターゲット ビュー形式は、スワップチェーン形式と一致する必要があります。 たとえば、DXGI_FORMAT_B8G8R8A8_UNORM_SRGB はスワップチェーン形式とレンダー ターゲット ビューの両方に対応します。 アプリのレンダリング パイプラインがシェーダー コード内で手動の sRGB 変換を行う場合は、例外があります。 アプリでは、sRGB スワップチェーン形式を要求する必要がありますが、レンダー ターゲット ビューには線形形式を使用します。 たとえば、スワップチェーン形式として DXGI_FORMAT_B8G8R8A8_UNORM_SRGB を要求しますが、コンテンツが二重にガンマ補正されないようにするためにレンダー ターゲット ビューとして DXGI_FORMAT_B8G8R8A8_UNORM を使用します。

プロジェクション レイヤーの深度バッファーを送信する

フレームを xrEndFrame に送信するときは、常に XR_KHR_composition_layer_depth 拡張機能を使用し、深度バッファーをプロジェクション レイヤーと一緒に送信します。 HoloLens 2 でハードウェア深度の再プロジェクションを有効にすると、ホログラムの安定性が向上します。

適切な深度範囲を選ぶ

HoloLens でのホログラムの安定性を向上させるために、より狭い深度範囲を使用して仮想コンテンツのスコープを指定します。 たとえば、OpenXrProgram.cpp サンプルでは、0.1 メートルから 20 メートルを使用しています。 より一貫した深度分解能を実現するには、reversed-Z を使用します。 HoloLens 2 では、優先される DXGI_FORMAT_D16_UNORM 深度形式を使用すると、フレーム レートとパフォーマンスが向上しますが、16 ビット深度バッファーでは、24 ビット深度バッファーよりも深度分解能が低くなります。 これらのベスト プラクティスに従って、深度分解能を最大限に活用することが重要になります。

さまざまな環境のブレンド モードを準備する

世界を完全に遮断するイマーシブ ヘッドセットでもアプリケーションを実行する場合は、xrEnumerateEnvironmentBlendModes API を使用して、サポートされる環境のブレンド モードを列挙し、レンダリング コンテンツを正しく準備してください。 たとえば、HoloLens などの XR_ENVIRONMENT_BLEND_MODE_ADDITIVE を使用するシステムの場合、アプリではクリア カラーとして透明を使用する必要がありますが、XR_ENVIRONMENT_BLEND_MODE_OPAQUE を使用するシステムでは、アプリで不透明な色または仮想ルームを背景にレンダリングする必要があります。

アプリケーションのルート空間として無制限参照空間を選ぶ

通常、アプリケーションでは、ビュー、アクション、ホログラムを相互接続するために、ルート ワールド座標空間を確立します。 ワールドスケールの座標系を確立する拡張機能がサポートされる場合は、XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT を使用します。これにより、ユーザーがアプリの開始位置から遠くに移動した (たとえば、5 m 離れた) ときに望ましくないホログラムのずれを回避できます。 無制限空間拡張機能が存在しない場合は、XR_REFERENCE_SPACE_TYPE_LOCAL をフォールバックとして使用します。

ホログラムを空間アンカーに関連付ける

無制限参照空間を使用する場合、その参照空間に直接配置したホログラムでは、ユーザーが遠くの部屋に移動して戻ったときにずれが生じる可能性があります。 ホログラム ユーザーがワールド内の個別の場所に配置されるようにするには、xrCreateSpatialAnchorSpaceMSFT 拡張関数を使用して空間アンカーを作成し、その原点にホログラムを配置します。 これにより、そのホログラムは時間の経過と共に個別に安定した状態に保たれます。

Mixed Reality キャプチャをサポートする

HoloLens 2 のプライマリ ディスプレイは、加算の環境ブレンドを使用しますが、ユーザーが Mixed Reality キャプチャを開始すると、アプリのレンダリング コンテンツは環境のビデオ ストリームとアルファブレンドされます。 Mixed Reality キャプチャ ビデオ内で最善のビジュアル品質を実現するには、プロジェクション レイヤーの layerFlagsXR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT を設定することをお勧めします。

HoloLens 2 のパフォーマンスに関するベスト プラクティス

ハードウェアの再プロジェクションをサポートするモバイル デバイスとして、HoloLens 2 には、最適なパフォーマンスを得るための厳しい要件があります。 コンポジション データの送信には多数の方法があるため、パフォーマンスを大幅に低下させる後処理が発生します。

スワップチェーン形式を選ぶ

xrEnumerateSwapchainFormats を使用してサポートされるピクセル形式を常に列挙し、アプリがサポートするランタイムから最初の色と深度のピクセル形式を選びます。これは、最適なパフォーマンスを実現するためにランタイムが優先するものであるためです。 注意: HoloLens 2 では、DXGI_FORMAT_B8G8R8A8_UNORM_SRGBDXGI_FORMAT_D16_UNORM は通常、レンダリングのパフォーマンスを向上させるための最初の選択肢です。 24 ビットの深度バッファーの方がパフォーマンスへの影響が少ないデスクトップ PC で実行されている VR ヘッドセットでは、この優先順位が異なる可能性があります。

パフォーマンスに関する警告: プライマリ スワップチェーンの色形式以外の形式を使用すると、実行時の後処理が発生し、パフォーマンスが大幅に低下します。

常に推奨されるビュー構成の幅と高さ (XrViewConfigurationView からの recommendedImageRectWidthrecommendedImageRectHeight) を使用してレンダリングし、レンダリングの前に、常に xrLocateViews API を使用して推奨されるビュー ポーズ、視界、その他のレンダリング パラメーターに対してクエリを実行します。 姿勢とビューに対してクエリを実行するときは、常に最新の xrWaitFrame 呼び出しからの XrFrameEndInfo.predictedDisplayTime を使用します。 これにより、HoloLens でレンダリングを調整し、HoloLens を装着しているユーザーのビジュアル品質を最適化することができます。

単一プロジェクション レイヤーを使用する

HoloLens 2 には、コンテンツのレンダリング用の限られた GPU 電源と、単一プロジェクション レイヤー用に最適化されたハードウェア コンポジターがあります。 常に単一プロジェクション レイヤーを使用すると、アプリケーションのフレームレート、ホログラムの安定性、ビジュアル品質を向上させることができます。

パフォーマンスに関する警告: 単一保護レイヤー以外を送信すると、実行時の後処理が発生し、パフォーマンスが大幅に低下します。

テクスチャ配列と VPRT を使用したレンダリング

カラー スワップチェーンに arraySize=2 を使用して、xrSwapchain を左目と右目の両方に対して 1 つ、さらに深度用に 1 つ作成します。 スライス 0 に左目を、スライス 1 に右目をレンダリングします。 VPRT を使用したシェーダーとインスタンス化された描画呼び出しをステレオスコピック レンダリングに使用して、GPU の負荷を最小限に抑えます。 これにより、ランタイムの最適化によって HoloLens 2 上で最大のパフォーマンスを実現することもできます。 テクスチャ配列の代替となる 2 倍幅のレンダリングや片目ごとの個別のスワップチェーンなどにより、実行時の後処理が発生し、パフォーマンスが大幅に低下します。

クアッド レイヤーを避ける

XrCompositionLayerQuad を使用してクワッド レイヤーをコンポジション レイヤーとして送信するのではなく、クアッド コンテンツをプロジェクション スワップチェーンに直接レンダリングします。

パフォーマンスに関する警告: クアッド レイヤーなど、単一のプロジェクション レイヤー以外の追加のレイヤーを指定すると、実行時の後処理が発生し、パフォーマンスが大幅に低下します。