見出し画像

「アレ」ってShader Graphの「ドレ?」

この記事は「GRIMOIRE アドベントカレンダー2021 ODD」の11個目の記事です

今回の記事はグリモアのRe:プロデューサーチーム所属のNsyが担当します。

自己紹介

はじめまして、グリモアに入社して1年少しのクライアントエンジニアのNsyと申します!

Unityを触りはじめて8年ほどになりますが、Unityナンモワカランとなりながら毎日過ごしています……

今回は、ShaderLabでは「こう書いていた」けど、ShaderGraphでは「ドコでいじれるの?」というような内容を紹介したいと思います!
おじさんなのでおぢさん構文が入るかもしれませんが見逃してください。

今回扱うバージョンについて

現在Techリリース最新のUnity2021.2で使用可能な"Shader Graph 12"系(12.1.2)に基づいた内容となりますが、"ShaderGraph 11"以前では、まだ使用できない機能などに関してはそれぞれ注釈を入れます。

シェーダー書くときよく使うけど現在利用できない機能、設定

いきなり「これができない!」から入るのもどうかと思いますが、逆にこれらの機能を使用したい場合は、ShaderLabで作成しなければということなので、エンジニア的には事前に知れると嬉しかった情報になります。事前に知りたかった……
また、「いや、使用できますよ?」みたいな機能が記載されている場合は、「あーこいつなんもわかっとらんw」と暖かくスルーしてください。

  • 複数のSubShaderの作成

  • 複数のPassの作成

  • Stencilの設定

  • LODの設定

  • MultiRenderTarget対応

  • Fallbackシェーダーの設定

  • VertexShaderおよびFragmentShader以外のShader(GeometryShader、HullShader)

  • Pass内のTag追加(SRP用のLightModeも設定できないため独自のShaderTagIdでのフィルタリングをしたい場合はできないのは不便……)

  • ColorMask(ColorMaskノードはあるが、RenderTargetへの書き込みチャンネルを制限する機能ではない)

などなど、改めて挙げてみると結構できないこと多いですね?
ですが、機能限定されているからこそ、確実性の高い動作が保証されたシェーダーを生成してくれたり、エンジニアやテクニカルアーティスト以外でもシェーダーの作成が行えるメリットは、やはり大きいと思います。

よく使うもの その1 「Culling、DepthTest」

ShaderLabではPassにCullingの設定とDepthTestの設定を普通に記載していました。

Shader "Sample"
{
    Properties
    {
       ~~~~~~~~~~略~~~~~~~~~~
    }
    SubShader
    {
        ~~~~~~~~~~略~~~~~~~~~~
        Pass
        {
        	~~~~~~~~~~略~~~~~~~~~~

        	Cull Front
       		ZWrite On
       		ZTest LEqual 

            HLSLPROGRAM
           	~~~~~~~~~~略~~~~~~~~~~
            ENDHLSL
        }
    }
}

ShaderGraphではGraphInspectorに設定項目があります。
Render FaceがCullingの設定で、Depth Write、Depth Testがそれぞれに当たります。ShaderLabでは"カリングする面"を指定していましたが、Render Faceは"描画する面"の指定になります。
ここで、お気づきの方もおられると思いますが、こちら"ShaderGraph 12"系から追加された新機能になります!
"Shader Graph 11"系以下のバージョンを使用の場合は、設定できず、ShaderLabで記述しなかったときと同様の状態(Default)になります。
ちなみに以降もですが、最近Unity2021.2をさわっていて、Nsyが個人的に「これ追加されたの!?うれしい!!」ってなったものが前面にでてきます。
「Unity2021.2でShaderGraphがアップデートされて個人的にうれしかったこと」がこの記事の本当のタイトルといっても過言ではありません。

よく使うもの その2 「ShaderKeywords」

Shader Valiantなどで使用するShaderKeywordsですが、ShaderLabでは、#pragmaディレクティブで指定します。

Shader "Sample"
{
    Properties
    {
       ~~~~~~~~~~略~~~~~~~~~~
    }
    SubShader
    {
        ~~~~~~~~~~略~~~~~~~~~~
        Pass
        {
            ~~~~~~~~~~略~~~~~~~~~~
            HLSLPROGRAM
            #pragma shader_feature _ _KEYWORD1
            #pragoma shader_feature_local _ _KEYWORD2
            #pragma multi_compile _ _KEYWORD3
            #pragma multi_compile_local _ _KEYWORD4
            ~~~~~~~~~~略~~~~~~~~~~
            ENDHLSL
        }
    }
}

Propertyを作成するときの"+"ボタンで開くプルダウンの一番下にあるKeywordから定義を作成できます。(今回はBooleanを例にします)

作成したKeywaordを選択すると、Graph Inspectorにて設定を行えます。

  • Definitionで"shader_featrue"か"multi compile"かの指定ができます

  • ScopeでLocalかGlobalの指定が可能です。
    ちなみにですが、Unity2021.2からGlobalのShaderKeywordsの上限が4,294,967,294個になりました。(Unity2021.1で384個、それ以前は256個の制限でした。Unity2021.2最高!)

  • Stagesは"12.1.2"から追加された設定で、"Vertex"か"Fragment"かの指定ができるので、ノードの使用をVertexShaderかFragmentShaderで絞れるのか?と思ったのですが、Vertexに設定してもFragmentに接続できる上、生成されるShaderLabコードで該当部分を見つけれら得なかったため不明です、申し訳ありません。
    "ShaderGraph 12.1.2"のDocumentによると、Keywordを適用するステージを選択するとあるのですがどうなんでしょう?

  • DefaultのチェックでデフォルトでKeywordsをOnにするかどうかが指定できます。

Keywordを作成しておくと、作成したKeywordのノードを作成できるようになります。

Shader Variant Collectionでもそのまま指定が可能です。

使うかも? その1 「CustomGUI」

MaterialのInspectorをカスタムしたい場合、ShaderGUI.csを継承したInspector拡張クラスを用意し、ShaderLabの"CustomEditor"で指定します。

Shader "Sample"
{
    Properties
    {
       ~~~~~~~~~~略~~~~~~~~~~
    }
    SubShader
    {
        ~~~~~~~~~~略~~~~~~~~~~
        Pass
        {
            ~~~~~~~~~~略~~~~~~~~~~
            HLSLPROGRAM
            ~~~~~~~~~~略~~~~~~~~~~
            ENDHLSL
        }
    }
    CustomEditor "CustomMaterialInspecitor"
}

ShaderGraphでも同様に、CustomEditorGUIに指定することで、作成されるMaterialのInspectorを拡張することが可能です。

うれしすぎる新機能「CustomInterpolator」

はい、とうとう新機能に完全フォーカスです。

Unity2021.2から追加された新機能「CustomInterpolator」は頂点ステージからフラグメントステージにデータを渡すことができます!!

  • Unity2021.1までの"ShaderGraph 11"系までは、VertexからFragmentに渡される値は固定で、任意の値を追加することはできませんでした。

  • CustomInterpolatorが追加されたことで、フラグメントステージで行う必要がない計算をバーテックスステージに逃がしたり、バーテックスステージで使用したパラメータをそのままフラグメントステージへ渡すことが可能となります!(ShaderLabで書いているときは当たり前にできていたことが、ShaderGraphでできるようになるのが一番嬉しいかもしれない)

  • ShaderLabではVertexShaderの出力、FragmentShaderへの入力に使用される構造体に渡したい値を追加すれば渡すことが可能でした。

Shader "Sample"
{
    Properties
    {
       ~~~~~~~~~~略~~~~~~~~~~
    }
    SubShader
    {
        ~~~~~~~~~~略~~~~~~~~~~
        Pass
        {
            ~~~~~~~~~~略~~~~~~~~~~
            HLSLPROGRAM
            ~~~~~~~~~~略~~~~~~~~~~
            struct v2f{
                float4 positionCS : SV_POSITION;
                float2 uv         : TEXCOORD0;
                float2 uv2        : TEXCOORD1; // こんな感じで追加できる
            }
            
            v2f Vert(Attributes input)
            {
                ~~~~~~~~~~略~~~~~~~~~~
            } 
            ~~~~~~~~~~略~~~~~~~~~~
            ENDHLSL
        }
    }
}

ShaderGraphでは、Vertexステージを右クリックして出てくるメニューの"Add Block Node"をクリックし、"Custom Interpolator"をクリックすることで追加することができます。

渡したいデータを追加したCustomInterpolatorに接続し、フラグメント側で使用する場合は、CustomInterpolatorノードが使用可能となっているので、そこから取得します。

その他うれしい新機能 「Allow Material Override」

  • "ShaderGraph 11"系では、ShaderGraphで作成したMaterialから設定できる値は、基本的に作成したPropertyのみでした。

  • "ShaderGraph 12"系からは、"Allow Material Override"をOnにすることで、Materialで設定を変更できるようになります。

  • 固定の設定しか持てなかったので、非常に助かります。うれしすぎるのハードルが低いとか言われても気にしないです。

まとめ

ShaderGraphが出た当初から、「お、NodeベースのShaderEditor来た!」「いやでもこれ、ShaderLab書けるなら書いた方が良くない?」「URPのシェーダー生成するの楽だわ〜」「いや〇〇できないからやっぱ書かなきゃじゃん!!」「CustomFunction Node便利〜※コードを書いてそれをノードとして使える機能」「CustomFunction書くならやっぱ普通に書いた方が良くない?」「でもSubGraphとかにすれば、ShaderGraph使える人全員で流用できるしなぁ〜」など、ShaderGraphに対する感情が、掌ぐるんぐるん状態でしが、ここ最近は、総じて「便利!!!!」に落ち着いたため今回はShaderGraphについて書き殴りました。
アレできない、コレできない書いていますが、けっしてアンチでなく、本気で便利だと思ってます。本気です!!!
まだ、手を出されていない方、不便で手放した方もぜひ触ってみると、Unityの進歩を感じれるかもしれません。
※Unity2021.2を最新最高と賛美するように記載しておりますが、「Techリリース」「最新バージョン」でピンとくる方がほとんどかと思いますが、バグとの戦いに悩まされることもあるので、覚悟がある程度必要になります。安定版で問題ない場合はLTSを使用していきましょう。

最後に

ここまでお付き合いいただき、本当にありがとうございます!

ということで、グリモアは一緒に【中二病を救う】側になってくれる仲間を大大大募集中です!

少しでも当社に興味を持って頂けましたら、是非とも下記の採用サイトを御覧ください!


本資料は、ユニティ・テクノロジーズまたはその関連会社がスポンサーとなっているものではなく、ユニティ・テクノロジーズまたはその関連会社と提携しているものではありません。「Unity」は米国およびその他の地域でのユニティ・テクノロジーズまたはその関連会社の商標または登録商標です。


読んでくださりありがとうございま――…… え?さぽーと…?いやいやいや!そんな恐れ多いですよ!でも、サポートいただけると、ゲーム開発が少しだけ楽になるかも…… あ!ごめんなさい、独り言ですっ!えへへへ……