夜風のMixedReality

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

GraphicsToolsStandardシェーダーにEmissiveMapの機能を追加する。

本日はShader調査枠です。

ここ数日でGraphicsToolsに関して調査していますが、現在GraphicsToolsへ筆者がFeatureRequestを行いイシューを立て新機能の開発を行っています。

github.com

MixedRealityToolkitはMicrosoft主導でオープンソースソフトウェアとして提供、開発されています。

我々Microsoft社外の開発者でも、開発に参加することができ、これにはバグレポート、ドキュメント、クエスチョン、そして機能開発のような部類があります。

今回GraphicsToolsStandardシェーダーの新機能として、EmissitionMap(発行マップ)を提案し、リーダーであるMicrosoftのエンジニア、Cameronさんより提案に対して賛成をいただいたため開発に取り掛かっています。

〇インスペクタのマテリアルプロパティにオリジナルのプロパティを追加する。

 通常UnityのシェーダーではPropertiesブロックに任意の変数を追加することでUnityのインスペクター上でマテリアルのプロパティとして扱うことができます。

 Properties
    {
  ...
    }

 GraphicsToolsStandardシェーダーはCustomEditorによってマテリアルのインスペクタに表示される表示をカスタマイズしています。

    CustomEditor "Microsoft.MixedReality.GraphicsTools.Editor.StandardShaderGUI"

ちなみにこのCustomEditorをコメントアウトすると次の画像のようにGraphicsToolsStandardシェーダーの機能すべてのプロパティが表示されるため非常に可読性が悪くなっています。

このためShader機能として新しいプロパティを追加してもインスペクタ上に表示されることがありません。

まずは新しいプロパティが表示されるように取り組みます。

Graphics ToolsStandardシェーダーのPropertiesブロックに_EmissiveMapを追加します。

    Properties
    {
  ...
        [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"{}
      ...
    }

前述のとおりこの時点ではマテリアルのプロパティとして作成したEmissive Mapが表示されることはありません。

StandardShaderGUI.csを開き90行目当たりのGUIContent enableEmissionの次の行にGUIContentの処理を追加します。

            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("Emission Map"); //追加
            public static readonly GUIContent enableTriplanarMapping = new GUIContent("Triplanar Mapping", "Enable Triplanar Mapping, a technique which programmatically generates UV coordinates");
            public static readonly GUIContent enableLocalSpaceTriplanarMapping = new GUIContent("Local Space", "If True Triplanar Mapping is Calculated in Local Space");

これはインスペクタのプロパティに関する関数で、表示するパラメータの方を作っています。

docs.unity3d.com

GUIContentの引数のうち第一引数が名称、第二引数がToolTip(カーソルを当てた際に表示される説明文)を示しています。

次に200行目当たりにMaterialProperty型の変数emissiveMapを定義します。

        protected MaterialProperty emissiveColor;
        protected MaterialProperty emissiveMap; //追加
        protected MaterialProperty enableTriplanarMapping;

次にFindProperties関数にemissiveMapとしてShaderのプロパティから_EmissiveMapを取得するようにします。

        protected override void FindProperties(MaterialProperty[] props)
        {
            base.FindProperties(props);

             ...
            enableEmission = FindProperty("_EnableEmission", props);
            emissiveColor = FindProperty("_EmissiveColor", props);
            emissiveMap = FindProperty("_EmissiveMap", props);//追加
            enableTriplanarMapping = FindProperty("_EnableTriplanarMapping", props);
            ...
         }

最後に実際にEmissionが有効である際に表示されるようにしている処理である620行目当たりのif (PropertyEnabled(enableEmission))にpropertyを追加します。

            materialEditor.ShaderProperty(enableEmission, Styles.enableEmission);

            if (PropertyEnabled(enableEmission))
            {
                materialEditor.ShaderProperty(emissiveColor, Styles.emissiveColor, 2);
                materialEditor.ShaderProperty(emissiveMap,Styles.emissiveMap,2);//追加
            }

これによってEmissionMapが使用できるようになりました。

今回はEmissiveMapの機能をマテリアルプロパティから使用可能にしました。

Shaderの処理自体は変更していないので次回以降詳しく解説していきます。

ShaderのCustomEditor機能は興味はあったものの触ったことがなかったので実際のShaderを見ながら改修していくととても勉強になります。