MRが楽しい

MRやVRについて学習したことを書き残す

MRTK v2のドキュメントを少しずつ読み解くパフォーマンス その1

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200129094128j:plain

パフォーマンス

入門

パフォーマンスを確認する最も簡単な方法は、フレームレート、またはアプリケーションが1秒間に画像をレンダリングできる回数です。
ターゲットのプラットフォーム(Windows Mixed Reality、Oculusなど)のターゲットフレームレートを満たすことが重要です。
例えば HoloLens では、ターゲットフレームレートは 60 FPS です。

低フレームレートのアプリケーションは、ホログラムの安定性の低下、位置トラッキング、ハンドトラッキングなど、ユーザー体験の悪化を招く可能性があります。
開発者が高品質のフレームレートを追跡して達成できるように、Mixed Reality Toolkit はさまざまなツールとスクリプトを提供しています。

Visual Profiler

開発の際にパフォーマンスを継続的に追跡するには、アプリケーションの実行とデバッグ中にフレームレートを常に表示することをお勧めします。
Mixed Reality Toolkit は現在のFPSとメモリ使用量に関するリアルタイム情報を提供する Visual Profiler を提供します。

Visual Profiler は MRTK Profiles Inspector の Diagnostics System Settings で設定できます。
f:id:bluebirdofoz:20200129093835j:plain

Unityエディターまたはエミュレーターでの実行ではなく、デバイスで実行するときに Visual Profiler を使用してフレームレートを追跡することが重要です。
リリース構成ビルドでデバイス上で実行すると、最も正確なパフォーマンス結果が表示されます。
f:id:bluebirdofoz:20200129093847j:plain

Optimize Window

MRTK Optimize Window は複合現実開発者が最良の実行結果を得るための環境を設定するものです。
そのシーン&アセットの潜在的ボトルネックを特定するのに役立つ情報や自動化ツールを提供しています。
Unity の特定の主要な構成は、複合現実プロジェクトの大幅な最適化に役立ちます。

これらの設定には複合現実に対して最適なレンダリング構成が含まれます。
複合現実プロジェクトはシーン全体をレンダリングするための2つの画面(つまり2つの目)があるという点で、従来の3Dグラフィックス開発と比較してユニークです。

以下で参照される推奨設定は、MRTK Optimize Window を活用することにより、Unity プロジェクトで自動構成できます。
f:id:bluebirdofoz:20200129093855j:plain

Unityの推奨設定

Single-Pass Instanced rendering

UnityのXRのデフォルトのレンダリング設定は Multi-pass です。
この設定により、Unityはレンダーパイプライン全体を2回(各目につき1回)実行することとなります。

これは代わりに Single Pass Instanced rendering を選択することで最適化できます。
この構成ではレンダーターゲット配列を活用して、各眼の適切なレンダーターゲットに単一の描画呼び出しを実行できます。
このモードではレンダーパイプラインの1回の実行で全てのレンダリングを実行できます。
従って、複合現実プロジェクトのレンダリングパスとして Single Pass Instanced rendering を選択すると、CPUとGPUの両方で時間を節約できます。
これが推奨されるレンダリング構成です。

ただし、各メッシュに対して1つの描画呼び出しを発行するには全てのシェーダーでGPUインスタンス化がサポートされている必要があります。
インスタンス化により、GPUは描画呼び出しを両目で多重化できます。
UnityビルトインシェーダーおよびMRTK Standardシェーダーには、デフォルトで必要なインスタンス化命令がシェーダーコードに含まれています。
カスタムシェーダーを作成する場合、これらのシェーダーと同じように Single Pass Instanced rendering をサポートする必要があります。

カスタムシェーダーのサンプルコード
struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID // Single Pass Instanced rendering 対応
};

struct v2f
{
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;

    UNITY_VERTEX_OUTPUT_STEREO // Single Pass Instanced rendering 対応
};

v2f vert (appdata v)
{
    v2f o;

    UNITY_SETUP_INSTANCE_ID(v); // Single Pass Instanced rendering 対応
    UNITY_INITIALIZE_OUTPUT(v2f, o); // Single Pass Instanced rendering 対応
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // Single Pass Instanced rendering 対応

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = v.uv;

    return o;
}

品質設定

Unityは、各プラットフォームのレンダリングの品質を制御するプリセットを提供します。
これらのプリセットは影、アンチエイリアス、グローバルイルミネーションなど、どのグラフィック機能を有効にできるかを制御します。
これらの設定を下げて、レンダリング中に実行される計算量を最適化することをお勧めします。

1.メニューから Edit -> Project Settings を選択し、Project Settings ウィンドウで Quality タブを開く。
UWP プラットフォームの品質選択で Low Quality を選択する。
f:id:bluebirdofoz:20200129093906j:plain

2.全てのシーンファイルで Window -> Rendering -> Lighting Settings を選択し、Lighting ウィンドウを開く。
Uncheck Real-time Global Illumination を無効化する。
f:id:bluebirdofoz:20200129093924j:plain

Depth Buffer Sharing(HoloLens)

特にHoloLens用に開発している場合、XR設定で Depth Buffer Sharing を有効にするとホログラムの安定化に役立ちます。
ただし Depth Buffer の処理は24ビットのフォーマットを使用する場合、パフォーマンスコストが発生する可能性があります。
このため、Depth Buffer を16ビット精度に設定することを強くお勧めします。
f:id:bluebirdofoz:20200129093946j:plain

16ビットのフォーマットが原因で z-fighting が発生する場合はカメラの clip plane の far が可能な限りの最小値に設定されていることを確認してください。
f:id:bluebirdofoz:20200129093955j:plain
・z-fighting
en.wikipedia.org
・far clip plane
docs.unity3d.com

Unityはデフォルトで1000mの clip plane の far を設定します。
HoloLensでは通常、ほとんどのアプリケーションシナリオで50mの clip plane の far で十分です。

注意

16ビットの深度フォーマットを使用する場合、Unity はこの設定で stencil buffer を作成しないため、ステンシルバッファーに必要な効果は機能しません。
逆に24ビットの深度フォーマットを選択すると、一般に8ビット stencil buffer が作成されます。

stencil buffer を必要とするマスクコンポーネントを使用する場合は代わりに RectMask2D の使用を検討してください。
RectMask2D は stencil buffer を必要としないため、16ビットの深度フォーマットと組み合わせて使用できます。

MRTK構成プロファイルの Editor 設定から Render Depth Buffer を使用できます。
これにより、シーン内のどのオブジェクトが Depth Buffer に書き込むかを視覚的にすばやく判断できます。
本ツールを利用するには Tools パッケージのインポートが必要です。
f:id:bluebirdofoz:20200129094027j:plain

bluebirdofoz.hatenablog.com