Unityシェーダーの基礎知識。Shaderでプロパティにトグルを追加する方法。
関連ページ
参考URL
Unityシェーダーでプロパティにfloatを設定する方法は知っていましたが、boolを設定する方法が分かっていませんでした。
調べた結果boolと近い内容は実装できたのでメモ。

シェーダートグルを追加
結論から言うと、Unityシェーダーでbooleanは使えないです。
そもそも
シェーダープロパティにはintが設定できない
ので、なんとなく事前に予想はしていました。
(コードでintを指定は出来ますが、内部的にはfloatとして処理されます)
その代わり、floatを使って疑似的にトグルをプロパティに表示することはできます。
この際、float値 = 0がトグルOff状態、float値 = 1がトグルのOn状態になります。
サンプルとして、
UseSilhouette
というトグルを作成し、これをOnにした場合画像が灰色のシルエットになるシェーダーを作りました。
OffとOnで画像が以下のように切り替わります。
以下は今回のサンプルシェーダーのコード全文です。
Shader
"Test/TestToggle"
{
Properties
{
//実際はfloatだがトグル表示にすることで外から見るとboolに見える
[Toggle]
_UseSilhouette("UseSilhouette",
float)
=
0
}
SubShader
{
Tags
{
"Queue"
=
"Transparent"
}
Cull
Off
ZWrite
Off
Blend
SrcAlpha
OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma
vertex
vert
#pragma
fragment
frag
struct
appdata
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
struct
v2f
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
sampler2D
_MainTex;
//今回追加したプロパティに対応する変数
float
_UseSilhouette;
v2f
vert
(appdata
v)
{
v2f
o;
o.vertex
=
UnityObjectToClipPos(v.vertex);
o.uv
=
v.uv;
o.color
=
v.color;
return
o;
}
fixed4
frag
(v2f
i)
:
SV_Target
{
fixed4
col
=
tex2D(_MainTex,
i.uv);
col
*=
i.color;
//_UseDoubleのトグルがOnの時はRGBを0.5にして灰色にする
col.rgb
=
((1
-
_UseSilhouette)
*
col.rgb)
+
(_UseSilhouette
*
fixed3(0.5,
0.5,
0.5));
return
col;
}
ENDCG
}
}
}
一応トグルはfloatではなくintを使ってもほぼ同じことは出来ます。
[Toggle] _UseSilhouette("UseSilhouette", int) = 0
//今回追加したプロパティに対応する変数
int
_UseSilhouette;
しかしトグルを多用した
ウェーブシェーダー
でfloatをintに変えて実装した所、2つ以上のトグルをOnにした時に正しく動かなくなりました。
おそらくはトグルのOnOffを計算式に使った場合、バグが発生する可能性が高いです。
公式が推奨するようにトグルはfloatで実装する方が無難な感じがします。

コードを解説
以下の部分がトグル表示に関係するコード。
[Toggle]
のプロパティ属性を指定することでトグル表示を可能にしています。
Properties
{
//実際はfloatだがトグル表示にすることで外から見るとboolに見える
[Toggle]
_UseSilhouette("UseSilhouette",
float)
=
0
}
[Toggle]
の代わりに
[MaterialToggle]
を使っても全く同じ挙動になります。
どうも特定の場合では[Toggle]だけ受け付けて[MaterialToggle]を受け付けない事があるらしいです。
単純に[Toggle]の方が上位互換だと思うのでここでは[Toggle]を指定します。
下のコードでプロパティに対応する変数を宣言。
//今回追加したプロパティに対応する変数
float
_UseSilhouette;
下のコードがトグルのOnOff状態によって描画を描き分ける処理です。
//_UseDoubleのトグルがOnの時はRGBを0.5にして灰色にする
col.rgb
=
((1
-
_UseSilhouette)
*
col.rgb)
+
(_UseSilhouette
*
fixed3(0.5,
0.5,
0.5));
シェーダーではif文が非推奨
なため少しややこしいコードになっています。
_UseSilhouette
はトグルによって0か1の二択が確定しています。つまり
といった感じで、全く描画処理を変えないか、灰色に一色に染めるか二択になります。
0
0