本日はshader学習枠です。
〇カラーフィルターを作成する
今回は画像のようなカラーフィルターを作成します。
一見半透明のオブジェクトを置いているように見えますが、これは_CameraOpaqueTextureを使用し取得したカメラのレンダリング映像を処理しています。
このようにカメラの映像を使用して処理を加えることでShader側でポストプロセッシングのような表現を学ぶ一環として作成しました。
〇コード
今回は早速コードを乗せます
Shader "Custom/ColorFilterShader" { Properties { } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float4 pos : TEXCOORD0; }; sampler2D _CameraOpaqueTexture; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.pos = ComputeScreenPos(o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col; col = tex2Dproj(_CameraOpaqueTexture, i.pos); return fixed4(col.x,0,0,0); } ENDCG } } }
ここで肝となる部分は二か所あります。
col = tex2Dproj(_CameraOpaqueTexture, i.pos);
tex2Dproj()はtex2D()の処理の成分xyをw除算をしてから使用するという処理を行います。
これはShaderを勉強したての頃に触ったスクリーンスペースを扱う方法でxy成分をw成分で除算するという処理と同様の処理になります。
o.pos = ComputeScreenPos(o.vertex);
次にここで使用される座標は頂点シェーダーで変換しています。
ComputeScreenPosはスクリーンスペースでの座標に変換されます。
これによって_CameraOpaqueTextureでカメラのレンダリング結果がカメラのスクリーン座標に対して張られるようになりました。
最後に赤成分のみを出力します。
return fixed4(col.x,0,0,0);
これでカラーフィルターのShaderが完成しました。
次に次のようにフラグメントシェーダーを変えました。
fixed4 frag (v2f i) : SV_Target { fixed4 col; col = tex2Dproj(_CameraOpaqueTexture, i.pos); col += fixed4(col.x,0,0,0); col/2; return col; }
このようにポストプロセッシング的な表現を行うことができそうです。