MR 開発時の Unity の推奨設定 を理解する [Mixed Reality ドキュメント]

今回はこのドキュメントを読む.

docs.microsoft.com

Low Quality Settings (描画品質設定)

高フレームレートを維持するために,Unity Quality settings を Very Low に設定すること.
デフォルトだと Very High になっていると思うけど,
実際に実機で比べてみると描画の質にあんまり差は感じにくかった気がする.

Edit > Project Settings > Quality > Very Low にする.

qiita.com

Lighting settings (ライティング設定)

Realtime Global Illumination を無効にする.
有効の場合,Unity はライティングをリアルタイムで計算してしまうので重くなる.

Window > Rendering > Lighting Settings > Realtime Global Illumination

Unity 2019 では非推奨になっている.

docs.unity3d.com

Baked Global Illumination を無効にする.
有効の場合,Unity はライティングを事前に計算し,ランタイム時にシーンに設定する.
VRHMD 等のような没入型の場合は効果があるけれど,HoloLens 開発には適用されない.

docs.unity3d.com

Single pass instancing rendering path (シングルパスインスタンス レンダリングパス)

レンダリング設定を Multi-pass になっていると,
ユーザーの各目に対して 1 回ずつレンダリングされる.
つまりシーンは 2 回レンダリングされていることになる
従来の 3D 開発と比較すると,計算する必要がある作業量が事実上 2 倍になるので,
CPU/GPU 節約のために Unity で最も効率的なレンダリングパスを選択することが重要.

Single pass instaced rendering は MR アプリの Unity レンダリングパイプラインを最適化するため
すべてのプロジェクトでこの設定をデフォルトで有効にすることが推奨されている.

MRTK Standard Shader は Single pass に対応している.
カスタムシェーダーが Single pass に対応してない場合,適切に描画されない可能性がある.

カスタムシェーダーに対応するためのサンプルコードは下記参照.

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    UNITY_INSTANCE_ID
};
struct v2f
{
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;
    UNITY_INSTANCE_ID
    UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata v)
{
    v2f o;
    UNITY_SETUP_INSTANCE_ID(v);
    UNITY_TRANSFER_INSTANCE_ID(v, o);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
}

UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);

fixed4 frag (v2f i) : SV_Target
{
    UNITY_SETUP_INSTANCE_ID(i);
    fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv);
    // just invert the colors
    col = 1 - col;
    return col;
}

(抜粋: https://docs.unity3d.com/Manual/SinglePassStereoRenderingHoloLens.html)

Multi-pass の場合のイメージ

f:id:xrdnk:20200409121653p:plain

Single-pass の場合のイメージ

f:id:xrdnk:20200409121704p:plain

Multi-pass,Single-pass,Single-pass Instancing の CPU/GPU パフォーマンス定量的な比較

f:id:xrdnk:20200409121713p:plain

  • 引用・参考資料

blogs.unity3d.com

docs.unity3d.com

Enable depth buffer sharing (深度バッファシェアリングの有効化)

ホログラム安定化のために,Depth Buffer Sharing プロパティを有効にする.

hololabinc.github.io

Player XR Settings (Edit > Project Settings > Player > XR Settings)
Enable Depth Buffer Sharing を有効化 > Windows Mixed Reality expansion

また,Hololens 開発の場合,Depth Buffer を 16 ビットの精度に設定することで,
24 ビットの精度に比べて,データの移動や処理が少なくなるため,必要な帯域幅が大幅削減し,
パフォーマンスがよくなる.

16 ビットの精度に設定したことで,Z-fighting が生じることがある.
24 ビットの精度に戻せば解決するが,HoloLens 開発においては 16 ビットを維持した方がよい.
対処法としては,MRTK の Camera 設定で,Near / Far Clip の値を変更して,範囲を小さくする.

  • Z-fighting とは

壁や床の絵がチラチラするアレ

tsubakit1.hateblo.jp

ホロモンさんの記事によれば,

bluebirdofoz.hatenablog.com

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

とのことなので,Far clip を 50 に設定すればよさそう.

また,16 ビットの精度の場合,Unity は Stencil Buffer を作成しない模様.
逆に 24 ビットの精度の場合,8 ビットの Stencil Buffer が作成されるとのこと.

docs.unity3d.com

  • Stencil Buffer について

qiita.com

難しい.Shader の知識ちゃんと身につけないとまずいなこれは….

Building for IL2CPP (IL2CPP ビルド)

Unity 2019 から .NET ビルドができなくなっており,IL2CPP 一択となっている.
ただまあ,IL2CPP ビルドは.NET ビルドに比べて遅い….

IL2CPP ビルド時間を減らす Tips は以下の通り.

docs.unity3d.com

  • インクリメンタルビルドの活用
  • マルウェア対策ソフトウェアのスキャンからプロジェクトとターゲットのビルドフォルダを除外する
  • SSD でビルド

特に,大きなアセットがある場合や,シーンやアセットを常に変更する Unity プロジェクトは,
Cache Server を利用するとよい.

docs.unity3d.com