地味に使ったことなかったのでメモ。
CGINCLUDE?
CGINCLUDEブロックは、複数パス間における共通設定を記述するブロックらしいです。
「設定」ってどこまでだろう。
検証用シェーダを作成
適当に2パスのシェーダを書いてみます。
Shader "Test_CgInclude" { Properties { _Color ("Color", Color) = (0,0,0,0) } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; }; half4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex + v.normal * 0.1); return o; } fixed4 frag (v2f i) : SV_Target { return _Color; } ENDCG } Pass { Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; half4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { return 1.0 - _Color; } ENDCG } } }
処理に特に意味はないです。 一応Cubeにアタッチするとこんな感じ。
変数をCGINCLUDEに
_ColorをCGINCLUDEに移してみます。
Shader "Test_CgInclude" { Properties { _Color ("Color", Color) = (0,0,0,0) } SubShader { Tags { "RenderType"="Opaque" } CGINCLUDE half4 _Color; ENDCG Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex + v.normal * 0.1); return o; } fixed4 frag (v2f i) : SV_Target { return _Color; } ENDCG } Pass { Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { return 1.0 - _Color; } ENDCG } } }
問題なく先ほどと同様のレンダリング結果が得られました。
異なるパス間で同じ変数を定義しなくて済むようになったので、CGINCLUDEの効果が得られました。
構造体の定義やキーワードの記述も書ける
変数の宣言以外にも、構造体の定義とか#pragma キーワードとかも移してみました。
問題なさそうです。
Shader "Test_CgInclude" { Properties { _Color ("Color", Color) = (0,0,0,0) } SubShader { Tags { "RenderType"="Opaque" } CGINCLUDE #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; }; half4 _Color; ENDCG Pass { CGPROGRAM v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex + v.normal * 0.1); return o; } fixed4 frag (v2f i) : SV_Target { return _Color; } ENDCG } Pass { Blend One One CGPROGRAM v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { return 1.0 - _Color; } ENDCG } } }
SubShader間でも共有できる
まあこうなってくるとSubShader間でも共通で使えるんでしょうが、一応試してみます。
Shader "Test_CgInclude" { Properties { _Color ("Color", Color) = (0,0,0,0) } CGINCLUDE #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; }; half4 _Color; ENDCG SubShader { Tags { "RenderType"="Opaque" } Pass { Blend One One CGPROGRAM v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { return 1.0 - _Color; } ENDCG } } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex + v.normal * 0.1); return o; } fixed4 frag (v2f i) : SV_Target { return _Color; } ENDCG } } }
エラーにならず、SubShader間でも問題なく共有できました。
ソースコードも結構スッキリしました。
複数パス使うときには積極的に使っていきたいです。