サンプルとして単純なSprite用のシェーダーっぽいの
Shader "Custom/Sprite" {
Properties {
// TIPS: モバイル環境でScaleとOffsetは使えないのでNoScaleOffsetで封印する
[NoScaleOffset] _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
[Enum(UnityEngine.Rendering.CullMode)]
_Cull("Cull", Float) = 0 // Off
[Enum(UnityEngine.Rendering.CompareFunction)]
_ZTest("ZTest", Float) = 4 // LEqual
[Enum(Off, 0, On, 1)]
_ZWrite("ZWrite", Float) = 0 // Off
[Enum(UnityEngine.Rendering.BlendMode)]
_SrcFactor("Src Factor", Float) = 5 // SrcAlpha
[Enum(UnityEngine.Rendering.BlendMode)]
_DstFactor("Dst Factor", Float) = 10 // OneMinusSrcAlpha
}
SubShader {
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
}
Cull [_Cull]
ZTest [_ZTest]
ZWrite [_ZWrite]
Blend [_SrcFactor][_DstFactor]
Pass {
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
struct appdata_t {
float4 vertex : POSITION;
half2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
sampler2D _MainTex;
v2f vert(appdata_t v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.color = v.color;
return o;
}
fixed4 frag(v2f i) : SV_Target {
return tex2D(_MainTex, i.uv) * i.color;
}
ENDCG
}
}
}
これでシェーダーファイルを増やさずにInspector上からMaterialでの設定ができる
メリットとしてはShaderVariantが減るのでシェーダーコンパイル時のスパイクが減らせる
あとコピペシェーダー作る必要がないのでコピペ漏れみたいなミスが減る
デメリットはマテリアルの生成難度が上がるので、
エンジニアでない人が「加算にしたいんだけどどうしたら・・・」となってしまいがち
(プリセット設定が選択出来ればいいのだけれど・・・MaterialPropertyDrawerは拡張できるのだろうか・・・)
スクリプトからも変更できる・・・が、MaterialPropertyBlockでは値を変えても変化がなかった
renderer.materialを呼び出すとMaterialが複製される・・・
sharedMaterialを使うとなると参照しているRenderer全てに影響が出る・・・
動的に変更することが有用な場面は非常に限定的かなと
// Materialを直接変更すると変わる
Material mat = new Material(Shader.Find("Custom/Sprite"));
mat.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Off);
mat.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
mat.SetFloat("_ZWrite", 0f);
mat.SetFloat("_SrcFactor", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
mat.SetFloat("_DstFactor", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
// MaterialPropertyBlockでは無効(SpriteRendererはそもそも無理)
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Off);
mpb.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
mpb.SetFloat("_ZWrite", 0f);
mpb.SetFloat("_SrcFactor", (float)UnityEngine.Rendering.BlendMode.One);
mpb.SetFloat("_DstFactor", (float)UnityEngine.Rendering.BlendMode.One);
MeshRenderer render = this.GetComponent<MeshRenderer>();
renderer.SetPropertyBlock(mpb);
【公式リファレンス】
https://docs.unity3d.com/jp/current/Manual/SL-Properties.html
https://docs.unity3d.com/jp/current/ScriptReference/MaterialPropertyDrawer.html