[Unityシェーダー基礎] Shaderでプロパティにトグルを追加する方法。
lerp関数について。
関連ページ
参考URL
Unityシェーダーでプロパティにfloatを設定する方法は知っていましたが、boolを設定する方法が分かっていませんでした。
調べた結果boolと近い内容は実装できたのでメモ。ついでにlerp関数についても少し解説しています。
※コードが古くなっていたのでURP用に記事を改修しました(2026/03/15)

シェーダートグルを追加
結論から言うと、Unityシェーダーでbooleanは使えないです。
そもそも
シェーダープロパティにはintが設定できない
ので、なんとなく事前に予想はしていました。
(コードでintを指定は出来ますが、内部的にはfloatとして処理されます)
その代わり、floatを使って疑似的にトグルをプロパティに表示することはできます。
この際、float値 = 0がトグルOff状態、float値 = 1がトグルのOn状態になります。
サンプルとして、
UseSilhouette
というトグルを作成し、これをOnにした場合画像が灰色のシルエットになるシェーダーを作りました。
OffとOnで画像が以下のように切り替わります。
以下は今回のサンプルシェーダーのコード全文です。

Shader
"UI/TestToggle"
{
Properties
{
//実際はfloatだがトグル表示にすることで外から見るとboolに見える
[MaterialToggle]
_UseSilhouette("UseSilhouette",
float)
=
0
}
SubShader
{
Tags
{
"RenderPipeline"
=
"UniversalPipeline"
"Queue"
=
"Transparent"
}
Cull
Off
ZWrite
Off
Blend
SrcAlpha
OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma
vertex
vert
#pragma
fragment
frag
#include
"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct
Attributes
{
half2
uv
:
TEXCOORD0;
float4
positionOS
:
POSITION;
half4
color
:
COLOR;
};
struct
Varyings
{
half2
uv
:
TEXCOORD0;
float4
positionCS
:
SV_POSITION;
half4
color
:
COLOR;
};
//uGUI Image > Source Imageにアタッチされた画像を参照する
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//SRP Batcherを適用
CBUFFER_START(UnityPerMaterial)
//今回追加したプロパティに対応する変数
float
_UseSilhouette;
CBUFFER_END
Varyings
vert
(Attributes
input)
{
Varyings
output;
output.positionCS
=
TransformObjectToHClip(input.positionOS.xyz);
output.uv
=
input.uv;
output.color
=
input.color;
return
output;
}
half4
frag
(Varyings
input)
:
SV_Target
{
half4
col
=
SAMPLE_TEXTURE2D(_MainTex,
sampler_MainTex,
input.uv);
col
*=
input.color;
//lerp関数を使って色を合成する
//第1引数:開始の色(_UseSilhouetteが 0 のときの色)
//第2引数:終了の色(_UseSilhouetteが 1 のときの色)
//第3引数:割合(0 か 1 かのスイッチ)
col.rgb
=
lerp(col.rgb,
half3(0.5,
0.5,
0.5),
_UseSilhouette);
return
col;
}
ENDHLSL
}
}
}

一応トグルはfloatではなくintを使ってもほぼ同じことは出来ます。
[MaterialToggle] _UseSilhouette("UseSilhouette", int) = 0
//今回追加したプロパティに対応する変数
int
_UseSilhouette;
しかしトグルを多用した
ウェーブシェーダー
でfloatをintに変えて実装した所、2つ以上のトグルをOnにした時に正しく動かなくなりました。
おそらくはトグルのOnOffを計算式に使った場合、バグが発生する可能性が高いです。
公式が推奨するようにトグルはfloatで実装する方が無難な感じがします。

コードを解説
以下の部分がトグル表示に関係するコード。
[MaterialToggle]
という
マテリアルプロパティドロワー
を指定することでトグル表示を可能にしています。
Properties
{
//実際はfloatだがトグル表示にすることで外から見るとboolに見える
[MaterialToggle]
_UseSilhouette("UseSilhouette",
float)
=
0
}
ちなみに
[MaterialToggle]
の代わりに
[Toggle]
を使っても全く同じ挙動になります。
[Toggle]
は
Shader Variant
という、シェーダー内で静的分岐処理をさせたい時に便利な機能ですが、処理速度は[MaterialToggle]の方が軽量です。
p.61 : シェーダー基礎、UnityでShaderVariantを使ってコード分岐
p.62 : シェーダー基礎、[Toggle]でShaderVariant
今回は静的分岐ではなく単純に「0 or 1」の係数として使っているだけなので、[MaterialToggle]を採用しています。
下のコードでプロパティに対応する変数を宣言しています。
//今回追加したプロパティに対応する変数
float
_UseSilhouette;
下のコードがトグルのOnOff状態によって描画を描き分ける処理です。
//lerp関数を使って色を合成する
//第1引数:開始の色(_UseSilhouetteが 0 のときの色)
//第2引数:終了の色(_UseSilhouetteが 1 のときの色)
//第3引数:割合(0 か 1 かのスイッチ)
col.rgb
=
lerp(col.rgb,
half3(0.5,
0.5,
0.5),
_UseSilhouette);
lerp
は線形補完を実行する大変便利な関数です。
第一引数を最小値、第二引数を最大値として、第三引数に0~1の値を代入することでその間の値を返します。
たとえば第三引数に0.5を代入するコードに変更すると、もともとのピクセル色と灰色がちょうど半分ずつ合成された画像が表示されます。
//col.rgb = lerp(col.rgb, half3(0.5, 0.5, 0.5), _UseSilhouette);
col.rgb
=
lerp(col.rgb,
half3(0.5,
0.5,
0.5),
0.5);
元のコードでは第三引数に_UseSilhouetteをしています。_UseSilhouetteは[MaterialToggle]によって0か1の値しか代入されません。
このため全く元の画像に変更を加えないか、灰色一色に染めるかの二択になります。
0
0