Windows のホログラフィックデバイス (HoloLens) には、マルチパスとシングルパスの 2 つのステレオレンダリング方法があります。
マルチパスレンダリングは、2 つの完全なレンダーパス (各目に 1 つずつ) を実行します。これにより、シングルパスでインスタンス化するレンダリング方法と比較して、CPU の負荷がほぼ 2 倍になります。ただし、この方法は最も後方互換性があり、シェーダーを変更する必要がまったくありません。
インスタンス化したレンダリングは、1 つのレンダーパスを実行します。このようなレンダーパスでは、各描画呼び出しがインスタンス化された描画呼び出しで置き換えられます。これにより、CPU 使用率を著しく低下させます。さらに、これは、2 つの画呼び出し間のキャッシュコヒーレンシのために、GPU の使用率をわずかに低下させます。そして、アプリの消費電力ははるかに低くなります。
この機能を有効にするには、Player 設定を開きます (Edit > Project Settings、次に Player カテゴリを選択)。次に、Other Settings パネルに移動し、Virtual Reality Supported プロパティを有効にしてから、Stereo Rendering Method ドロップダウンから Single Pass Instanced (Fastest) を選択します。
Unity では速度の遅い Multi pass (Slow) 設定がデフォルトになっています。スクリプトにこの機能をサポートするのに必要なコードがないカスタムシェーダーがあるかもしれないからです。
ビルトインシェーダーでないものはすべて、インスタンシングで動作するように更新する必要があります。 GPU インスタンシング を参照してそれを行ってください。また、フラグメントシェーダー (Vertex/Hull/Domain/Geometry) の前に使用した最後のシェーダーステージで、さらに 2 つ変更する点があります。最初に、UNITY_VERTEX_OUTPUT_STEREO
を出力構造体に加える必要があります。次に、UNITY_SETUP_INSTANCE_ID()
が呼び出された後に、そのステージの main 関数に UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO()
を加える必要があります。
ポストプロセシングシェーダー
入力テクスチャの宣言の周りに UNITY_DECLARE_SCREENSPACE_TEXTURE(tex)
マクロを加える必要があります。それによって、2D テクスチャ配列が正しく宣言されます。次に、フラグメントシェーダの先頭に UNITY_SETUP_INSTANCE_ID()
への呼び出しを加える必要があります。最後に、これらのテクスチャをサンプリングするときに UNITY_SAMPLE_SCREENSPACE_TEXTURE()
マクロを使用する必要があります。他の類似のマクロの深度テクスチャとスクリーンスペースシャドウマップの詳細については、HLSLSupport.cginc を参照してください。
テンプレートイメージエフェクトに対して前述のすべての変更を適用する簡単な例を示します。
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);
// 単に色を逆にします
col = 1 - col;
return col;
}
Graphics.DrawProceduralIndirect()
と CommandBuffer.DrawProceduralIndirect()
は、すべての引数をコンピュートバッファーから取得します。そのため、簡単にはインスタンス数を増やすことはできません。したがって、手動で、コンピュートバッファに含まれるインスタンス数を 2 倍にしなければなりません。
シェーダーコードに関する詳細は 頂点シェーダーとフラグメントシェーダーの例 のページを参照してください。