【Unity】Shader の定義済みキーワードを動的に有効/無効化する(_EMISSION が効かなかった)

DEVELOP, Unity

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 が反映されました。めでたしめでたし。

Posted by kazupon