読者です 読者をやめる 読者になる 読者になる

【Unityで始める初めてのShader】ポストエフェクトの作り方3

shader3_2

記事に不備があった場合、未来の自分が直すと思います。
では、前回の続き。

前回は、フラグメントシェーダを定義し、そこでreturnしたカラーを画面に反映させることができました。カメラから取ってきた画面を加工するのが目的なので、カメラから映像を取ってきましょう。

まずは、一番最初に消したPropertiesを復活させます。Propertiesはシェーダ内の変数とUnity上の変数を結びつけるのに使用するものでしたね。

Properties {
        _MainTex("MainTex", 2D) = ""{}
}

なんてことはないおまじないです。ただし、サイトによって書き方が若干違ったりします。今回は気にしない。
意味合いとしては、_MainTexが変数名、"MainTex"はUnityエディタ上で表示される名前、2Dは型といったところでしょうか。
ここで宣言をした型を使うにはシェーダ内で同じ変数名を宣言する必要があります。
では、frag関数の中身を以下のように書き換えてみましょう。

Shader "Custom/PostEffect" {
    Properties {
        _MainTex("MainTex", 2D) = ""{}
    }

    SubShader {
        Pass {
            CGPROGRAM

            #include "UnityCG.cginc"

            #pragma vertex vert_img
            #pragma fragment frag

            sampler2D _MainTex;

            fixed4 frag(v2f_img i) : COLOR {
                float4 color = tex2D(_MainTex, i.uv);
                return color;
            }

            ENDCG
        }
    }
}

まず、最初に変わったのは引数が追加されたことです。UnityCG.cgincの中身にv2f_imgという構造体が宣言されているようです。ドキュメントを見ると中で定義されてるものが分かります。
続いてtex2D。これは第一引数にテクスチャ、第二引数に座標を指定するとその座標の色を返してくれるものです。

実行してみると、 shader3_1 カメラから取ってた映像をそのまま出力するシェーダができました!!

では、これを利用してグレースケールエフェクトを作ってみましょう。
プログラムはここを参考にさせて頂いています。

Shader "Custom/PostEffect" {
    Properties {
        _MainTex("MainTex", 2D) = ""{}
    }

    SubShader {
        Pass {
            CGPROGRAM

            #include "UnityCG.cginc"

            #pragma vertex vert_img
            #pragma fragment frag

            sampler2D _MainTex;

            fixed4 frag(v2f_img i) : COLOR {
                float4 color = tex2D(_MainTex, i.uv);

                float gray = (color.r + color.g + color.b) / 3;
                color.rgb = float3(gray, gray, gray);

                return color;
            }

            ENDCG
        }
    }
}

shader3_2

できました!初めてのShaderです!
今後の方針ですが、Unity以外で使われているShaderをUnityで移植しつつ仕様やアルゴリズムを理解していくという形でやっていこうと思います。MMDとかエフェクトが豊富ですしね。