MRが楽しい

MRやVRについて学習したことを書き残す

Unityでスクリプトからシェーダのキーワード定義を変更して処理を切り替える その4(シェーダのキーワードを確認する)

本日はUnityの小ネタ枠です。
Unityでスクリプトからシェーダのキーワード定義を変更して処理を切り替える方法です。
今回はシェーダに設定しているキーワードを確認する方法を試します。

前回記事

以下の記事で作成したサンプルシェーダを基にサンプルを作成します。
bluebirdofoz.hatenablog.com

シェーダのキーワードを確認する

スクリプトからシェーダのキーワードの有効状態を確認するにはShader.IsKeywordEnabledを利用します。
docs.unity3d.com

if (Shader.IsKeywordEnabled(_shaderKeywordRed))
{
    // ...
}

マテリアルごとに設定されたキーワードの有効状態を確認するにはMaterial.IsKeywordEnabledを利用します。
docs.unity3d.com

// 対象のマテリアルの参照を取得する
Material targetMaterial = _renderer.material;
if (targetMaterial.IsKeywordEnabled(_shaderKeywordRed))
{
    // ...
}

サンプルスクリプト

前回作成したスクリプトにキーワードの有効状態を確認する関数を追加しました。
・ShaderKeywordController.cs

using UnityEngine;

public class ShaderKeywordController : MonoBehaviour
{
    private readonly string _shaderKeywordRed = "FORCE_RED_COLOR";
    private readonly string _shaderKeywordGreen = "FORCE_GREEN_COLOR";
    private readonly string _shaderKeywordBlue = "FORCE_BLUE_COLOR";
    
    [SerializeField] Renderer _renderer;

    /// <summary>
    /// 全てのキーワードを無効化する
    /// </summary>
    [ContextMenu("ResetShaderKeyword")]
    public void ResetShaderKeyword()
    {
        // シェーダのキーワードの定義を削除する
        Shader.DisableKeyword(_shaderKeywordRed);
        Shader.DisableKeyword(_shaderKeywordGreen);
        Shader.DisableKeyword(_shaderKeywordBlue);
    }
    
    /// <summary>
    /// シェーダー全体に赤色にするキーワードを有効化する
    /// </summary>
    [ContextMenu("SetShaderKeywordRed")]
    public void SetShaderKeywordRed()
    {
        // シェーダのキーワードの定義を追加する
        Shader.EnableKeyword(_shaderKeywordRed);
        
        // シェーダのキーワードの定義を削除する
        Shader.DisableKeyword(_shaderKeywordGreen);
        Shader.DisableKeyword(_shaderKeywordBlue);
    }
    
    
    /// <summary>
    /// 指定のレンダラーが保持するマテリアルのシェーダにのみ赤色にするキーワードを有効化する
    /// </summary>
    [ContextMenu("SetMaterialShaderKeywordRed")]
    public void SetMaterialShaderKeywordRed()
    {
        // マテリアルのシェーダのキーワードの定義を追加する
        _renderer.material.EnableKeyword(_shaderKeywordRed);
        
        // シェーダのキーワードの定義を削除する
        _renderer.material.DisableKeyword(_shaderKeywordGreen);
        _renderer.material.DisableKeyword(_shaderKeywordBlue);
    }

    /// <summary>
    /// シェーダの赤色のキーワードの定義が有効化されているか確認する
    /// </summary>
    [ContextMenu("CheckShaderKeywordRed")]
    public void CheckShaderKeywordRed()
    {
        // シェーダの赤色のキーワードの定義が有効化されているか確認する
        if (Shader.IsKeywordEnabled(_shaderKeywordRed))
        {
            Debug.Log("Shader.IsKeywordEnabled:赤色のキーワードが有効化されています");
        }
        else
        {
            Debug.Log("Shader.IsKeywordEnabled:赤色のキーワードが有効化されていません");
        }
    }

    /// <summary>
    /// 指定のレンダラーが保持するマテリアルのシェーダの赤色のキーワードの定義が有効化されているか確認する
    /// </summary>
    [ContextMenu("CheckMaterialShaderKeywordRed")]
    public void CheckMaterialShaderKeywordRed()
    {
        // 指定のレンダラーが保持するマテリアルのシェーダの赤色のキーワードの定義が有効化されているか確認する
        if (_renderer.material.IsKeywordEnabled(_shaderKeywordRed))
        {
            Debug.Log("Material.IsKeywordEnabled:赤色のキーワードが有効化されています");
        }
        else
        {
            Debug.Log("Material.IsKeywordEnabled:赤色のキーワードが有効化されていません");
        }
    }
    
#if UNITY_EDITOR
    private void OnApplicationQuit()
    {
        ResetShaderKeyword();
    }
#endif
}

スクリプトをシーンに設定して変更対象のマテリアルの参照を追加します。

動作確認

シーンを再生して動作を確認します。

Shader.IsKeywordEnabledの動作

Shader.IsKeywordEnabledはShader.EnableKeywordまたはShader.DisableKeywordで設定したキーワードの有効状態のみチェックします。
以下の通り、Shader.EnableKeywordで有効化した場合はShader.IsKeywordEnabledで検出できますが、Material.IsKeywordEnabledでは有効と判定されません。


Material.IsKeywordEnabledの動作

Material.IsKeywordEnabledは指定のマテリアルに対してMaterial.EnableKeywordまたはMaterial.DisableKeywordで設定したキーワードの有効状態のみチェックします。
以下の通り、Material.EnableKeywordで有効化した場合はMaterial.IsKeywordEnabledで検出できますが、Shader.IsKeywordEnabledでは有効と判定されません。