[Unityシェーダー基礎] マテリアルのInspectorからシェーダー変数にアクセス。
マテリアルプロパティとSRP Batcherについて。
関連ページ
参考URL
シェーダーの変数にはマテリアルのInspectorからもアクセスできます。
この機能を知らないと、動的に動かす必要のないシェーダー変数も一々コードから変更する必要があるので、開発効率が数十倍落ちます。
シェーダーをUI Imageに適用する方法は
こちら
。
またマテリアルが仲介することでC#からシェーダーにアクセスすることもできます。それに関しては
こちら
の記事をどうぞ。
※コードが古くなっていたのでURP用に記事を改修しました(2026/03/15)

プロパティが実装されたシェーダー
Unity Shaderでは、
Properties
内に変数を記入すると、その値をInspectorから操作できます。
下の例は、
BlendRate
の値に応じて、画像を灰色に塗りつぶすシルエットシェーダーです。
コードは次の通りです。

Shader
"UI/TestSilhoutte"
{
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
}
SubShader
{
Tags
{
"RenderPipeline"
=
"UniversalPipeline"
"Queue"
=
"Transparent"
}
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;
half4
color
:
COLOR;
float4
positionOS
:
POSITION;
};
struct
Varyings
{
half2
uv
:
TEXCOORD0;
half4
color
:
COLOR;
float4
positionCS
:
SV_POSITION;
};
//uGUI Image > Source Imageにアタッチされた画像を参照する
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//SRP Batcherを適用
CBUFFER_START(UnityPerMaterial)
//プロパティと紐づくShader内で使う変数の宣言
half
_BlendRate;
CBUFFER_END
Varyings
vert
(Attributes
input)
{
Varyings
output;
output.uv
=
input.uv;
output.color
=
input.color;
output.positionCS
=
TransformObjectToHClip(input.positionOS.xyz);
return
output;
}
half4
frag
(Varyings
input)
:
SV_Target
{
half4
col
=
SAMPLE_TEXTURE2D(_MainTex,
sampler_MainTex,
input.uv);
col
*=
input.color;
//元のImageのカラーと灰色を_BlendRateに応じてブレンド
half3
grayColor
=
half3(0.5,
0.5
,
0.5);
col.rgb
=
lerp(col.rgb,
grayColor,
_BlendRate);
return
col;
}
ENDHLSL
}
}
}


プロパティ実装の解説
Inspectorに変数を表示させるためには、まず
Properties
ブロックの記述が必要になります。
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
}
ここでは
_BlendRate
が実際にShader内で使う変数名です。
第一引数の
"BlendRate"
がInspectorに表示される文字列。Shader内で使う変数名と一致している必要はありません。
何なら日本語でも問題なく動きます。
第二引数は型指定、ここでは
Range
指定しています。Rangeは最小値と最大値を限定させたfloat型のことです。
最後に=0で_BlendRateの初期値を代入。
Propertiesブロック以外にも、
HLSLPROGRAM
内にも同じ変数名を宣言する必要があります。
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//SRP Batcherを適用
CBUFFER_START(UnityPerMaterial)
//プロパティと紐づくShader内で使う変数の宣言
half
_BlendRate;
CBUFFER_END
half _BlendRate;の前後に
CBUFFER_START(UnityPerMaterial)
と
CBUFFER_END
というコードも確認できます。
これはURPから追加された
SRP Batcher
という機能です。
簡単に言うとこのコードを入れるだけでPropertiesで宣言した変数の取得速度が大きく向上します。
このマテリアルを適用したオブジェクトの数が増えるほど、その効果が顕著になります。
ただし何でもかんでもSRP Batcherが使える訳ではなく、Propertyの中でも簡単な数値データのみ適用可能です。

プロパティの補足
今回は_BlendRateが0未満だったり1より上になるとバグになるのであえてRangeで制限しています。
実際は制限のない単純なfloatもプロパティに追加できます。下がそのコードサンプルです。
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
_FloatTest
("FloatTest",
float)
=
0
}
//プロパティと紐づくShader内で使う変数の宣言
half
_BlendRate;
float
_FloatTest;
以前の記事
で書いた通り、内部で使える浮動小数点数はfloat以外にhalfもあります。
プロパティ自体には実質floatしか記述できませんが、対応するHLSLPROGRAM内の変数はhalfに落とし込むことができます。
//プロパティと紐づくShader内で使う変数の宣言
half
_BlendRate;
half
_FloatTest;
残念ながらシェーダープロパティに単純なintは使えません。
バグやエラーなどは発生しませんが、内部的には完全にfloatとして処理されてしまいます。
_BlendRate ("BlendRate", Range(0.0, 1.0)) = 0
_FloatTest ("FloatTest", float) = 0
_IntTest ("IntTest", int) = 0
見ての通り、intを指定してるのに0.5が入力できてしまっています。
一方でHLSLPROGRAM内の対応する変数にはintを指定できます。
//プロパティと紐づくShader内で使う変数の宣言
half
_BlendRate;
half
_FloatTest;
int
_IntTest;
上の例では、インスペクターからはIntTestに対して小数点以下を指定できるものの、
_IntTest
は小数点以下の数値を無視して処理します。
0
0