vol.1を読んだ勢いでvol.2を読み始めた。 booth.pm
第7章まで読んでShader Variantが登場したので、まとめ記事を上げる前にここだけ別途メモを残しておく。
まず、Variantというのはググると「変異体」とか「変形」みたいな言葉が意味としてまず出てくるけど、理解する上では「多様体」みたいなニュアンスのほうがわかりやすい。1つのシェーダからキーワード(文字通り)を駆使して様々な結果を生み出すようにする仕組み。重要構文としてmulti_compile
やshader_feature
が出てくる。
公式ドキュメントより
多くの場合、固定されたシェーダーコードの断片の大部分を保持するだけでなく、わずかに異なるシェーダー「バリアント」を作成できるようにしておくと便利です。一般に「メガシェーダー」や「ウーバーシェーダー」と呼ばれ、ケースごとに異なるプリプロセッサーディレクティブでシェーダーコードを複数回コンパイルすることで達成されます。 Unity では、これは シェーダースニペットに #pragma multi_compile または #pragma shader_feature を追加することによって達成することができます。これも サーフェースシェーダー で動作します。 実行時には、適切なシェーダーバリアントは、マテリアルのキーワード (Material.EnableKeyword と DisableKeyword) またはグローバルシェーダーキーワード (Shader.EnableKeyword と DisableKeyword ) からピックアップされます。
multi_compileを使う
Shader "Sample/TestShader" { SubShader { Pass { CGPROGRAM ... #pragma multi_compile _ RED ... fixed4 frag(v2f i) : SV_Target { #ifdef RED return fixed4(1, 0, 0, 1); #endif return fixed4(0, 0, 0, 1); } ...
こういうシェーダを用意しておく。 ここでREDというのがまさにキーワードというやつ。それから_ってのはどのキーワードも有効じゃないときのためのもの。switch文のdefault的なもんだと思う。 このキーワードのON,OFFをスクリプトから操作するのは簡単で、
Shader.EnableKeyword("RED"); Shader.DisableKeyword("RED");
あるいは
Material.EnableKeyword("RED"); Material.DisableKeyword("RED");
でできる。(それぞれマテリアルに対してなのか、シェーダに対してなのかが違う。)#ifdef ~ #endif の間に #elif を使えば分岐はもっと増やせる。(#ifndefもある。)
当然、コンパイルの時点で処理されるので、裸の if 構文を使うより効率が良い。
Propertiesからキーワードを操作する
これはいろいろ手段はあるっぽい。Toggleの例を示す。
Shader "Sample/TestShader" { Properties { [Toggle(_R)] _R("Red", Float) = 0 [Toggle(_B)] _B("Blue", Float) = 0 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ _R #pragma multi_compile _ _B ... fixed4 frag(v2f i) : SV_Target { fixed4 color = fixed4(0, 0, 0, 1); #ifdef _R color.r += 1; #endif #ifdef _B color.b += 1; #endif return color; } ...
とかって書くと、
みたいにできる。
shader_featureを使う
キーワードが増えるとシェーダがどんどん大きくなってしまう。それを避ける方法にshader_feature
がある。
これはmulti_compile
とほとんど同じだけど、
- _ を省略できる - 未使用のキーワードで有効になる部分はコンパイル時にシェーダプログラムに含まない
という違いがある。#pragma multi_compile _ _R
を #pragma shader_feature _R
に変えるだけ。
さいごに
とまあ、こんな感じです。Unity Shader Programming Vol.2の第7章のまとめでした。
こちらの2つの記事も似通った内容で、参考になりました。