Unityシェーダーの基礎知識。マテリアルのInspectorからシェーダー変数にアクセス。
関連ページ
参考URL
シェーダーの変数にはマテリアルのInspectorからもアクセスできる。
この機能を知らないと、動的に動かす必要のないシェーダー変数も一々コードから変更する必要があるので、開発効率が数十倍落ちる。
またマテリアルが仲介することでC#からシェーダーにアクセスすることもできる。それに関しては
こちら
の記事をどうぞ。
プロパティが実装されたシェーダー
Unity Shaderでは、Properties内に変数を記入すると、その値をInspectorから操作できる。
下はBlendRateの値に応じて、画像を灰色に塗りつぶすシルエットシェーダー。
コードは次の通り
Shader
"Test/TestSilhoutte"
{
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
}
SubShader
{
Tags
{
"RenderType"="Transparent"
"Queue"
=
"Transparent"
}
Cull
Off
ZWrite
Off
Blend
SrcAlpha
OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma
vertex
vert
#pragma
fragment
frag
#include
"UnityCG.cginc"
struct
appdata
{
fixed2
uv
:
TEXCOORD0;
fixed4
color
:
COLOR;
fixed4
vertex
:
POSITION;
};
struct
v2f
{
fixed2
uv
:
TEXCOORD0;
fixed4
color
:
COLOR;
fixed4
vertex
:
SV_POSITION;
};
sampler2D
_MainTex;
//プロパティと紐づくShader内で使う変数の宣言
fixed
_BlendRate;
v2f
vert
(appdata
v)
{
v2f
o;
o.uv
=
v.uv;
o.color
=
v.color;
o.vertex
=
UnityObjectToClipPos(v.vertex);
return
o;
}
fixed4
frag
(v2f
i)
:
SV_Target
{
fixed4
col
=
tex2D(_MainTex,
i.uv);
col
*=
i.color;
//元のImageのカラーと灰色を_BlendRateに応じてブレンド
fixed4
SilhouetteColor
=
fixed4(0.5,
0.5
,
0.5,
1);
col.r
=
(col.r
*
(1
-
_BlendRate))
+
(SilhouetteColor.r
*
_BlendRate);
col.g
=
(col.g
*
(1
-
_BlendRate))
+
(SilhouetteColor.g
*
_BlendRate);
col.b
=
(col.b
*
(1
-
_BlendRate))
+
(SilhouetteColor.b
*
_BlendRate);
return
col;
}
ENDCG
}
}
}
プロパティ実装の解説
Inspectorに変数を表示させるためには、まずPropertiesブロックの記述が必要。
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
}
ここでは
_BlendRate
が実際にShader内で使う変数名。
第一引数の
"BlendRate"
がInspectorに表示される文字列。Shader内で使う変数名と一致している必要はない。何なら日本語でも良い。
第二引数は型指定、ここでは
Range
指定している。Rangeは最小値と最大値を限定させたfloat型のこと。
最後に=0で_BlendRateの初期値を代入。
Propertiesブロック以外にも、CGPROGRAM内にも同じ変数名を宣言する必要がある。
sampler2D
_MainTex;
//プロパティと紐づくShader内で使う変数の宣言
fixed
_BlendRate;
プロパティの補足
今回は_BlendRateが0未満だったり1より上になるとバグになるのであえてRangeで制限している。
実際は制限のない単純なfloatもプロパティに追加できる。下はそのコードサンプル。
//Inspectorに表示するプロパティの宣言
Properties
{
_BlendRate
("BlendRate",
Range(0.0,
1.0))
=
0
_FloatTest
("FloatTest",
float)
=
0
}
//プロパティと紐づくShader内で使う変数の宣言
fixed
_BlendRate;
float
_FloatTest;
以前の記事
で書いた通り、CGPROGRAM内で使える浮動小数点数はfloat以外にhalfとfixedもある。
プロパティ自体にはfloatしか記述できないが、対応するCGPROGRAM内の変数はhalfやfixedに落とし込める。
//プロパティと紐づくShader内で使う変数の宣言
fixed
_BlendRate;
fixed
_FloatTest;
残念ながらシェーダープロパティに単純なintは使えない。
バグやエラーなどは発生しないが、内部的には完全にfloatとして処理されてしまう。
_BlendRate ("BlendRate", Range(0.0, 1.0)) = 0
_FloatTest ("FloatTest", float) = 0
_IntTest ("IntTest", int) = 0
見ての通り、intを指定してるのに0.5が入力できてしまっている。
一方でCGPROGRAM内の対応する変数にはintを指定できる。
//プロパティと紐づくShader内で使う変数の宣言
fixed
_BlendRate;
fixed
_FloatTest;
int
_IntTest;
上の例では、インスペクターからはIntTestに対して小数点以下を指定できるものの、_IntTestは小数点以下の数値を無視して処理する。
0
0