【Unity】【シェーダ】シェーダでcgincファイルをインクルードして使う

シェーダでcgincファイルをインクルードして使う方法です。

Unity2018.2

cgincファイルを作る

まずcgincファイルを作ります。
Unity上から作れないので適当に拡張子が.cgincのファイルを作って取り込みます。

f:id:halya_11:20181106204302p:plain

取り込んだらまず次のように記述します。
二重インクルード防止のための作法です。

#ifndef EXAMPLE_INCLUDED
#define EXAMPLE_INCLUDED

// ここに処理を書いていく

#endif

処理としては適当にマクロを一つ定義しておきます。

#ifndef EXAMPLE_INCLUDED
#define EXAMPLE_INCLUDED

#define POW2(value) value * value;

#endif

インクルードして使う

これをシェーダファイルにインクルードすれば、
cgincファイルに定義された処理が使えるようになります。

Shader "Example"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM

           #pragma vertex vert
           #pragma fragment frag
           #include "UnityCG.cginc"
           #include "Example.cginc"
            
            float4 vert (float4 vertex : POSITION) : SV_POSITION
            {
                return UnityObjectToClipPos(vertex);
            }
            
            fixed4 frag () : SV_Target
            {
                return POW2(0.5);
            }

            ENDCG
        }
    }
}

cgincには色々書ける

includeしたところに展開されるだけなので、関数や変数などもcgincに書けます。
というか#pragma以外ならだいたいなんでも書けます。

たとえばcgincに頂点シェーダとフラグメントシェーダを定義してみます。

#ifndef EXAMPLE_INCLUDED
#define EXAMPLE_INCLUDED

#include "UnityCG.cginc"
            
float4 vert (float4 vertex : POSITION) : SV_POSITION
{
    return UnityObjectToClipPos(vertex);
}
            
fixed4 frag () : SV_Target
{
    return 0.5;
}

#endif

シェーダファイルでそれを読めば正常に動作します。

Shader "Example"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            
           #pragma vertex vert
           #pragma fragment frag
           #include "Example.cginc"

            ENDCG
        }
    }
}

上手く使えば複数のシェーダで処理を共通化しやすくなります。