[Unityシェーダー基礎] C#からShader変数にアクセスする方法。
関連ページ
参考URL
シェーダーの変数の値は
マテリアルから操作が可能
となっています。
またUnity C#からマテリアルにアクセス可能なので、実質C#からシェーダー変数にもアクセスできます。
この知識がないとゲーム中に動的にシェーダー変数を動かすことができないので、シェーダーを使った演出を作ることができないです。
※コードが古くなっていたのでURP用に記事を改修しました(2026/03/15)

今回使うシェーダー全文
今回は
_BlendRate
というShader変数に応じて、画像をシルエット化するシェーダーを作ります。
コードの内容としては
こちら
のコードからPropertiesの数行を削っただけになります。
(今回はInspectorから値を変更しないのでPropertiesは要りません)

Shader
"UI/TestSilhoutte2"
{
SubShader
{
Tags
{
"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
}
}
}

_BlendRate
のようなShader内で宣言された変数に対して、C#からアクセスが可能です。

C#からShader変数にアクセス
厳密に言うとまずMaterialのC#コードにアクセスし、そのMaterialがShaderコードにアクセスします。
下の動画は、ボタンを押すと星がシルエット化してから右端まで移動し、右端に到達すると1秒かけてシルエットが解除される処理です。
C#のシェーダーに関係するコード部分だけ紹介。まず最初の星移動前にシルエット化するコードです。
[SerializeField] private Image star;
star.material.SetFloat("_BlendRate", 1);
SerializeField
でアタッチしたImageコンポーネントから、
star.material.SetFloat("_BlendRate", 1)
でプロパティにアクセスしています。
ここでは
_BlendRate
というShader変数を1にするようにC#から指定。
SetFloat以外にもSetIntやSetColorなど様々な関数があります。
今回の
_BlendRate
は型宣言はhalfになっていますが、
C#から見るとShaderのhalfとfloatはともにfloatという扱いになります。
次に星が1秒かけてシルエット状態から_BlendRate=0に戻る処理。
DOTween.To(() => star.material.GetFloat("_BlendRate"), (val) =>
{
star.material.SetFloat("_BlendRate", val);
}, 0, 1f);
面倒なので
Tween
で処理。
SetFloat
と対になる形で
GetFloat
関数があり、これで現在のプロパティの値を取得できます。
以上のように、Shaderを操作しアニメーションを実装が可能です。
0
0