シングルパスインスタンスレンダリングとカスタムシェーダー
Update custom shaders to support single-pass stereo instanced rendering.
読み終わるまでの所要時間 12 分最終更新 1ヶ月前
URP、HDRP、ShaderGraph、サーフェスシェーダー、およびビルトインシェーダーは、シングルパスステレオインスタンスレンダリングを、すでにサポートしています。ただし、アセットストアのシェーダー、サードパーティ製のシェーダー、または独自に作成したシェーダーの更新が必要となる場合があります。
インスタンス化されたレンダリングのシェーダーでのサポートについて、詳細は GPU インスタンシングを参照してください。このセクションの内容は、特にステレオレンダリングについて説明しており、インスタンス化されたレンダリング全般をサポートするために実施する必要のある変更を、すべてカバーしていない可能性があります。
頂点入力属性構造体の更新
UNITY_VERTEX_INPUT_INSTANCE_IDappdata例
struct appdata{ float4 vertex : POSITION; float2 uv : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID //Insert};
頂点出力属性構造体の更新
UNITY_VERTEX_OUTPUT_STEREOv2f例
struct v2f{ float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; UNITY_VERTEX_OUTPUT_STEREO //Insert};
主要頂点シェーダー機能の更新
主要な メソッドの先頭に、以下のマクロを順番に追加します。
vertUNITY_SETUP_INSTANCE_ID()UNITY_INITIALIZE_OUTPUT(v2f, o)UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO()
UNITY_SETUP_INSTANCE_ID()unity_StereoEyeIndexunity_InstanceIDUNITY_INITIALIZE_VERTEX_OUTPUT_STEREOunity_StereoEyeIndexunity_StereoEyeIndexfragUNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEXUNITY_INITALIZE_OUTPUT(v2f,o)v2f例
v2f vert (appdata v){ v2f o; UNITY_SETUP_INSTANCE_ID(v); //Insert UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o;}
ポストプロセスシェーダー
ポストプロセスシェーダーでシングルパスステレオインスタンシングをサポートする場合は、カスタムシェーダーの手順に加えて、以下の手順を行ってください。
注意: Unity の基本シェーダースクリプトは、すべて Unity のウェブサイトからダウンロードできます。
シングルパスインスタンシングに対応させる各ポストプロセスシェーダーに、以下の手順を実行します。
-
シェーダースクリプトの frag メソッドの外に UNITY_DECLARE_SCREENSPACE_TEXTURE(tex) マクロを追加 (配置については下の例を参照) して、特定のステレオレンダリングメソッドを使用する場合に GPU が適切なテクスチャサンプラーを使用するようにします。例えば、マルチパスレンダリングを使用する場合、GPU は テクスチャ 2D サンプラーを使用します。シングルパスインスタンシングまたはマルチビューレンダリングの場合、テクスチャサンプラーはテクスチャの配列です。
-
フラグメントシェーダーの frag メソッドの先頭にを追加します (配置については、下の例を参照してください)。このマクロは、
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i)ビルトインシェーダー変数を使用して、GPU がどの眼に描画するかを調べる場合にのみ、追加する必要があります。これは、ポストプロセスエフェクトをテストするときに便利です。unity_StereoEyeIndex -
2D テクスチャのサンプリングには、マクロを使用します(下の例を参照してください)。スタンダードシェーダーは、2D テクスチャベースのバックバッファを使用してテクスチャをサンプリングします。シングルパスステレオインスタンシングは、このタイプのバックバッファを使用しないため、シェーダーが正しく描画するように、2D テクスチャのサンプリングには別のメソッドを指定します。レンダリングの問題を防ぐために、
UNITY_SAMPLE_SCREENSPACE_TEXTURE()マクロは、どのステレオレンダリングパスが使用されているかを検出し、適切な方法で自動的にテクスチャをサンプリングします。深度テクスチャとスクリーンスペースシャドウマップに使用される類似のマクロの詳細については、HLSLSupport.cginc で Unity のドキュメントを参照してください。UNITY_SAMPLE_SCREENSPACE_TEXTURE()
例
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insertfixed4 frag (v2f i) : SV_Target{ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); //Insert fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Insert // just invert the colors col = 1 - col; return col;}
完全なサンプルシェーダーコード
以下は、テンプレートイメージエフェクトシェーダーの簡単な例です。シングルパスステレオインスタンシングをサポートするための、前述したすべての変更が適用されています。シェーダーコードに追加された行は、コメント でマークされます。
//Insertstruct appdata{ float4 vertex : POSITION; float2 uv : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID //Insert};//v2f output structstruct v2f{ float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; UNITY_VERTEX_OUTPUT_STEREO //Insert};v2f vert (appdata v){ v2f o; UNITY_SETUP_INSTANCE_ID(v); //Insert UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o;}UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insertfixed4 frag (v2f i) : SV_Target{ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); //Insert fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Insert // invert the colors col = 1 - col; return col;}
プロシージャルジオメトリ
Graphics.DrawProceduralIndirect() メソッドと CommandBuffer.DrawProceduralIndirect() メソッドを使用して GPU に完全にプロシージャルなジオメトリを描画する場合、両方のメソッドがコンピュートバッファから引数を受け取ることに注意してください。つまり、インスタンス数をランタイム時に増やすのは難かしいということです。インスタンス数を増やすには、コンピュートバッファに含まれるインスタンス数を、手動で 2 倍にする必要があります。
シェーダーのデバッグ
以下のシェーダーコードは、ゲームオブジェクトを、ユーザーの左眼用には緑色に、右眼用には赤色にレンダリングします。このシェーダーは、すべてのステレオグラフィックスをチェックし、正しく機能していることを確認できるため、ステレオレンダリングのデバッグに便利です。
Shader "XR/StereoEyeIndexColor"{ Properties { _LeftEyeColor("Left Eye Color", COLOR) = (0,1,0,1) _RightEyeColor("Right Eye Color", COLOR) = (1,0,0,1) } SubShader { Tags { "RenderType" = "Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag float4 _LeftEyeColor; float4 _RightEyeColor; #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); return lerp(_LeftEyeColor, _RightEyeColor, unity_StereoEyeIndex); } ENDCG } }}
ShaderGraph デバッグシェーダー
ShaderGraph は、シングルパスステレオレンダリングをサポートするために必要なマクロを、自動的に追加します。ShaderGraph にデバッグシェーダーを実装するには、視点インデックスに基づいて通常色を設定するカスタム関数ノードを使用します。

unity_StereoEyeIndexOut = lerp(LeftColor, RightColor, unity_StereoEyeIndex);