Shader Forgeで作成したシェーダーファイルをcgincでまとめてしまう


Shader Forgeで作成したシェーダーファイルからcgインクルードファイルは作れるか?

Unity向けのビジュアルシェーダーエディタであるShader Forgeは、.shaderという拡張子のついているシェーダーファイルを作成しています。

Shader Forgeで作成された.shaderファイルからcgインクルードファイルが作れたら、Shader Forgeだけでは作りにくいような複雑なシェーダーも作れるはずなので、実験してみました。

1:Shader Forgeでサンプルシェーダーを作ってみる

まずはShader Forgeでサンプルシェーダーを作ってみます。
1つめは、HalfLambertのシェーダーです。

こちらはHalfLambertTest.shaderという名前のシェーダーファイルになっています。

2つめとして、Outlineのみのシェーダーを作成します。

こちらはOutlineTest.shaderという名前になっています。

これらの拡張子.shaderのファイルは、Visual StudioやMonodevelopmentのようなIDEで開くことができます。

2:cgインクルードをする.shaderファイルを作成する

つぎにcgincファイルを挿入するひな形となる.shaderファイルをテキストで用意します。
UnityのProjectウィンドウから適当なshaderファイルを新規作成し、以下のコードを中身にコピペしてしまえばいいでしょう。

cgincbase.shader
//このShaderファイルのシェーダー名を指定する
Shader "Shader Forge/IncludeTest"
{
    Properties
    {
    //ここに必要なプロパティを各shaderファイルからコピーする

    }
    SubShader
    {
        Tags
        {
        //全体にかかるタグがあればここに

        }

//以下、ひとつめのPASS
        Pass
        {
            // このパスの名前があれば
            Name " "
            Tags{
                // このパスだけのタグがあれば

            }

            CGPROGRAM
            // 以下、ShaderForgeで作成したshaderファイルのあるパスのCGPROGRAMヘッダー

            // 以下、上のCGPROGRAMヘッダー部分を除いたパスの中身を別ファイル化したcgincをインクルード
            #include " .cginc"
            ENDCG
        }

// 以下、必要な数だけパスを繰り返し
        Pass
        {
            // このパスの名前があれば
            Name " "
            Tags{
                //このパスだけのタグがあれば

            }

            CGPROGRAM
            // 以下、ShaderForgeで作成したshaderファイルのあるパスのCGPROGRAMヘッダー

            // 以下、上のCGPROGRAMヘッダー部分を除いたパスの中身を別ファイル化したcgincをインクルード
            #include " .cginc"
            ENDCG
        }

    }
    // FallBackの指定を入れておく
    FallBack "Legacy Shaders/Diffuse"
}

こちらにShader Forgeで作成した、HalfLambertTest.shaderおよびOutlineTest.shaderから必要な要素だけコピペします。

3:HalfLambertTest.shaderを開いて中身を検討する

ここからはShaderファイルをIDEで開いて、中のコードを検討することになります。
HalfLambertTest.shaderは次の様な構成になっています。
ざっと中身を見てみると、冒頭にプロパティがあり、SubShaderの中には「Forward」と「Forward_Delta」の2つのPassがあります。

これらを上の図のようにブロックに分割して、ひな形の方にコピペしていきます。
また緑と紫のブロックに関しては、各々「HalfLambertTestForward.cginc」「HalfLambertTestForwardDelta.cginc」という名前で、別ファイルとしてセーブしておきます。

4:OutlineTest.shaderを開いて中身を検討する

続いてOutlineTest.shaderは次の様な構成になっています。
こちらにも2つのPassがありますが、最後のPassはあまり意味のある処理をやっていないようですので、ここはバッサリと切ってしまいます。

こちらも青のブロックは、「OutlineTest.cginc」という名前で別ファイルとしてセーブしておきます。

5:cgインクルードファイルとして2つのシェーダーを読み込む

さて、2のひな形より内容をコピペしたshaderファイルを「IncludeTest.shader」と名付け、3および4の各要素を指定の場所にコピペすると、以下の様な状態になります。

こちらのシェーダーファイルからマテリアルを作成すると、1で作成した2つのシェーダーがひとつのシェーダーとしてUnity上で利用することができます。

まとめ

途中.shaderファイルを開いて中身を検討する必要がありますが、必要な部分とそれらをコピペする先には法則性がありますので、いくつか.Shaderファイルを開いてみれば理解できるようになることでしょう。

Shader Forgeを使って直感的に作成した複数のシェーダーをこのようにまとめてしまったり、cgincとして別のシェーダーに再利用することができれば、さらに利用の幅が広がることでしょう。

Enjoy Your Happy Unity Life :-)

※本投稿は、Unity5.3.5f1とShader Forge v.1.27で検証しています。

※※ちなみに今回作ったHalfLambert+Outlineのシェーダーは普通にShader Forgeで組むことができますので、この目的のためにcgincをする必要はありません。念のため(^^;)