シェーダ内で#define マクロ名(引数) 処理
という文法でマクロを書くことが出来ます。
マクロとはCやC++でよく出てくるインラインで展開されるアレです。
UnityCG.cginc
の中身を眺めているとよく出てきます。
眺めることはあっても書いたことはなかったので、試してみました。
またマクロとコンボ技で使用されるマルチコンパイル
についても検証しています。
◆サンプルコード
各処理内容を説明していきます。
シェーダ側の処理
1.「SHIBUYA24」というキーワード定義
2.そのキーワードの有無によるシェーダを2種類コンパイル
#pragma multi_compile _ SHIBUYA24
↑ここでSHIBUYA24
というキーワードを定義し、SHIBUYA24
キーワードが存在するパターン、存在しないパターンのシェーダをコンパイルするよう指示しています。
◆注意点
#pragma multi_compile SHIBUYA24
コメントにも書きましたが、↑このように書いてしまうとSHIBUYA24キーワードが存在するパターンしか
コンパイルされませんので、シェーダを切り替えるということができなくなります。
#pragma multi_compile _(アンダースコア) キーワード名
という文法で定義する必要があります。
3.SHIBUYA24キーワードの有無によるマクロ挙動の切り替え
#ifdef SHIBUYA24 #define TEST_MACRO(abc) abc.x = 0; #else #define TEST_MACRO(abc) abc.z = 0; #endif
このようにマクロを#define マクロ名(引数) 処理
という文法で定義し、キーワードによる切り替えは#ifdef~#endif
で指定します。
マクロの改行
マクロの処理が複数行になる場合、改行したくなります。 以下のように記述するとコンパイルエラーです。
#define TEST_MACRO(abc) abc.x = 0;
こちらのように\ (バックスラッシュ)
をお尻に付けるとコンパイルが通ります。
#define TEST_MACRO(abc) \ abc.x = 0;
C#側の処理
キーワードを動的に切り替えてシェーダを切り替える
if(m_enableMacro) mat.DisableKeyword("SHIBUYA24"); else mat.EnableKeyword("SHIBUYA24");
このようにEnableKeyword
、DisableKeyword
メソッドを実行することで、MaterialのShaderを切り替えることが出来ます。
余談
#define TEST_MACRO(abc)
このように処理が何も記述されていないマクロを見かけますが、この場合は何も起きません。ご安心を。
まとめ
マルチコンパイル
とマクロ
を使えば、同じようなシェーダをいくつも作る必要がなくなり、ファイル構成をスッキリさせられます。
しかし、あまりこれらに頼るとコードの可読性が下がりそうで、何事もバランスが大事だなと思う次第でございます。