Version: 2020.1
言語: 日本語
Replaced Shaders でのレンダリング
Depth Texture の使用

カスタムシェーダー GUI

時として、標準搭載されている Unity のマテリアルエディターではうまく表現できない、変わったデータタイプを伴うシェーダーが必要になります。Unity はデフォルトで用意されているシェーダープロパティを上書きする方法を提供しているので、あなた自身で定義することができます。データ範囲の確認と、カスタムコントロールを定義するために、この機能を使う事ができます。

シェーダーの GUI 用にカスタムエディターを書く場合、まず最初に Custom Editor を要求するシェーダーを定義します。カスタムエディターに使う名前は、マテリアルエディター向けに Unity から参照されるクラスになります。

カスタムエディターを定義するために、 ShaderGUI のクラスを拡張し、アセットの階層内にある Editor フォルダーの下に、スクリプトを置きます。

using UnityEditor;

public class CustomShaderGUI : ShaderGUI 
{
    public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        base.OnGUI (materialEditor, properties);
    }
}

カスタムエディターを定義した (CustomEditor “CustomShaderGUI”) どんなシェーダーにおいても、リストアップされたシェーダー GUI クラスのインスタンスを作成し、関連するコードを実行できます。

簡単な例

さて、シェーダーが2つのモードで働く事が可能な状況があるとします。標準的な拡散反射光のライティングでの描画と、50%の青と緑のチャンネルでの描画です。

Shader "Custom/Redify" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert addshadow
        #pragma shader_feature REDIFY_ON

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;

            #if REDIFY_ON
            o.Albedo.gb *= 0.5;
            #endif
        }
        ENDCG
    } 
    CustomEditor "CustomShaderGUI"
}

シェーダーの設定に REDIFY_ON というキーワードがあるのが判ると思います。これは、マテリアルのシェーダーキーワードプロパティを使う事で、マテリアル毎の基準でオンに変える事ができます。以下はそのようにした ShaderGUI のインターフェースです。

using UnityEngine;
using UnityEditor;
using System;

public class CustomShaderGUI : ShaderGUI
{
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        // デフォルトの GUI をレンダリング
        base.OnGUI(materialEditor, properties);

        Material targetMat = materialEditor.target as Material;

        // redify が設定されているかを確認してからチェックボックスを表示
        bool redify = Array.IndexOf(targetMat.shaderKeywords, "REDIFY_ON") != -1;
        EditorGUI.BeginChangeCheck();
        redify = EditorGUILayout.Toggle("Redify material", redify);
        if (EditorGUI.EndChangeCheck())
        {
            // チェックボックスに基づくキーワードを有効化/無効化
            if (redify)
                targetMat.EnableKeyword("REDIFY_ON");
            else
                targetMat.DisableKeyword("REDIFY_ON");
        }
    }
}

より総合的な ShaderGUI の例は、 Unity Download Archive からダウンロードできる ‘Built-in shaders’ パッケージ内の Standard.shader と、StandardShaderGUI.cs ファイルをあわせて見てください。

上記の簡単な例は、 MaterialPropertyDrawers を使って、さらに単純化できる事に注意してください。以下の行を Custom/Redify シェーダーの Properties セクションに追加します:

[Toggle(REDIFY_ON)] _Redify("Red?", Int) = 0

そして以下を削除します。

CustomEditor "CustomShaderGUI"

MaterialPropertyDrawer も参照してください。

ShaderGUI は、例えば、マテリアルのプロパティが相互依存している場合や、特別なレイアウトが要求されるような、もっと複雑なシェーダー GUI の問題解決に使えます。 MaterialPropertyDrawers を ShaderGUI のクラスと組み合わせて使う事もできます。StandardShaderGUI.cs を参照してください。

Replaced Shaders でのレンダリング
Depth Texture の使用