夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

ShaderでプロパティにEnumを使用する。

本日はShader学習枠です。

UnityのShaderではCustomShaderGUIを使用することでInspector上のマテリアルのプロパティ表示をカスタマイズすることができます。

〇ShaderプロパティでEnumを使用する

ShaderのプロパティではEnumが使用されている場面をよく見ます。

例えばStandardShaderではCullModeなどでEnumによって定義されている値を使用できます。

今回はMixedRealityGraphicsTools/StandardShaderの例をもとにShaderのプロパティにEnumを使用します。

今回は以前筆者が実装したEmissionMapの機能にUVの選択機能を追加する艇で進めます。

①Shaderのプロパティに使用する変数をFloat型で定義します。

Shader "Graphics Tools/Standard"
{
    Properties
    {
        // Main maps.
     ・・・
        [Toggle(_EMISSION)] _EnableEmission("Enable Emission", Float) = 0.0
        [HDR]_EmissiveColor("Emissive Color", Color) = (0.0, 0.0, 0.0, 1.0)
        _EmissiveMap("Emissive Map",2D) = "white" {}
         [Enum(Microsoft.MixedReality.GraphicsTools.Editor.EmisiveUV)] _EmissiveUV("Emissive UVs",Float) = 0.0//追加
        
   ・・・
        // Rendering options.
       ・・・   

ここで[Enum()]アトリビュートをつけることでEnumが使用できます。

ここで()内の引数はCustomShaderGUIを示します。

今回の場合はMicrosoft.MixedReality.GraphicsTools.Editorがそれにあたり、今回はその中にEmisiveUVという変数を定義します。

②ShaderGUI.cs側でEnum型を定義します。

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;

namespace Microsoft.MixedReality.GraphicsTools.Editor
{
 ・・・

    public enum EmissiveUV
    {
        UV0 = 0,
        UV1 = 1,
        UV2 = 2
    }

    ・・・

③次にStylesクラスにEnum型の変数を定義します。

        protected static class Styles
        {
       ・・・
            public static readonly GUIContent enableEmission = new GUIContent("Emission", "Enable Emission");
            public static readonly GUIContent emissiveColor = new GUIContent("Color");
            public static readonly GUIContent emissiveMap = new GUIContent("EmissionMap");
            public static readonly GUIContent emissiveUV = new GUIContent("EmissionUV");//追加
            public static readonly string[] emissiveUVNames = new String[] { "UV0", "UV1", "UV2" };//追加
            public static readonly string emissiveUV0 = "_UV0";//追加
            public static readonly string emissiveUV1 = "_UV1";//追加
            public static readonly string emissiveUV2 = "_UV2";//追加
            public static readonly GUIContent enableTriplanarMapping = new GUIContent("Triplanar Mapping", "Enable Triplanar Mapping, a technique which programmatically generates UV coordinates");
 ・・・

④またマテリアルのプロパティを取得するための型も定義します。

        protected MaterialProperty emissiveUV;

FindProperties関数でMRGTShaderからプロパティを取得します。

 emissiveUV = FindProperty("_EmissiveUV", props);

ここではShader側のPropetiesに指定した値を使用しています。

最後にShaderGUI.csでGUIのレイアウトに反映させます。

⑤今回はEmissionを有効にしている場合表示されるようにしたいのでMainMapOptions関数の中のEmissionのif文内に記述します。

 if (PropertyEnabled(enableEmission))
            {
                EditorGUI.indentLevel += 2;
                materialEditor.ShaderProperty(emissiveColor, Styles.emissiveColor, 2);
                materialEditor.ShaderProperty(emissiveMap, Styles.emissiveMap, 2);
                EditorGUI.indentLevel -= 2;
                emissiveUV.floatValue = EditorGUILayout.Popup(Styles.emissiveUV, (int)emissiveUV.floatValue, Styles.emissiveUVNames);//追加
                }
            }

以上でEnum型のプロパティが使用できるようになりました。

しかしながらここではプロパティに表示できるようにしただけで、Shader側へ値をフィードバックする実装はありません。

 次回実装していきます。