【Unity】Shader の定義済みキーワードを動的に有効/無効化する(_EMISSION が効かなかった)
Unity に最初から存在する 3Dオブジェクトである Cube や Sphere に割り当てられている Standard.shader は実に様々なパラメータを設定できます。
試しに メタリックな質感でも表現してみようと _Metallic にパラメータを流し込んでみます。
using UnityEngine;
public class MetallicTest : MonoBehaviour
{
[SerializeField, Header("メッシュレンダラー")]
private MeshRenderer m_meshRenderer;
public MeshRenderer meshRenderer
{
get { return m_meshRenderer; }
}
private MaterialPropertyBlock m_mpb;
public MaterialPropertyBlock mpb
{
get { return m_mpb ?? (m_mpb = new MaterialPropertyBlock()); }
}
void Start()
{
if (meshRenderer != null)
{
mpb.SetFloat(Shader.PropertyToID("_Metallic"), 1.0f);
mpb.SetFloat(Shader.PropertyToID("_Glossiness"), 0.5f);
meshRenderer.SetPropertyBlock(m_mpb);
}
}
}
左が変更前、右が変更後の見た目です。メタリック感が出ています。
自己発光してみよう
メタリックな感じになりましたし、今度は自己発光してみます。自己発光である_Emission キーワードにパラメータを流し込んでみます。
using UnityEngine;
public class EmissionTest : MonoBehaviour
{
[SerializeField, Header("メッシュレンダラー")]
private MeshRenderer m_meshRenderer;
public MeshRenderer meshRenderer
{
get { return m_meshRenderer; }
}
private MaterialPropertyBlock m_mpb;
public MaterialPropertyBlock mpb
{
get { return m_mpb ?? (m_mpb = new MaterialPropertyBlock()); }
}
/// <summary>
/// 開始
/// </summary>
void Start()
{
if (meshRenderer != null)
{
mpb.SetColor(Shader.PropertyToID("_EmissionColor"), Color.yellow);
meshRenderer.SetPropertyBlock(m_mpb);
}
}
}
実行結果を確認してみます。右側が_Emission へパラメータを流し込んだ結果です。
あれ?変化がない。おかしい、指定した色に光らない。…シェーダーファイルの中身を確認します。
https://unity3d.com/jp/get-unity/download/archive
Standard.shader の中身を確認すると
#pragma shader_feature_local _NORMALMAP
#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
#pragma shader_feature _EMISSION
#pragma shader_feature_local _METALLICGLOSSMAP
pragma shader_feature _EMISSION お前か。というわけでキーワードを有効にします。
void Start()
{
if (meshRenderer != null)
{
mpb.SetColor(Shader.PropertyToID("_EmissionColor"), Color.yellow);
meshRenderer.material.EnableKeyword("_EMISSION"); // 追加
meshRenderer.SetPropertyBlock(m_mpb);
}
}
結果を見てみます。
_EMISSION が反映されました。めでたしめでたし。