夜風のMixedReality

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

MRGT GraphicsToolsStandardShaderに影を受け取る機能を追加する。 その①ShaderGUIの実装

本日はMRGT枠です。

〇MRGTとは?

MixedRealityGraphicsTools(MRGT)はMicrosoftによってオープンソースな形で開発、提供されているMixedRealityデバイス向けのSDKである第三世代のMixedRealityToolkit(MRTK3)で提供されるグラフィック関連のパッケージを指します。

 MRTKのコア機能に当たるGraphicsToolsStandardShaderは多くの機能をサポートしていますが、もともとがHoloLensで使用される想定であったことと軽量化のためにほかのオブジェクトとの影の相互関係の機能がありません。

 今回は影を受けるようにしていきます。

〇Unityにおける影を受け取るシェーダー

redhologerbera.hatenablog.com

〇MRGTシェーダーに影を受け取る機能を追加する。

MRGTShaderではCustomShaderGUIの機能によってUnityのinspector上に表示されるマテリアルの表示がカスタマイズされています。

まずはStandardShaderGUI.csを弄りマテリアルのプロパティにreceiveShadowのチェックボックスを表示することころから実装します。

まずはGraphicsTools StandardShadferに表示するプロパティを追加します。

Shader "Graphics Tools/Standard"
{
    Properties
    {
        // Main maps.
  ・・・

        // Rendering options.
        [Enum(Microsoft.MixedReality.GraphicsTools.Editor.LightMode)] _DirectionalLight("Light Mode", Float) = 1.0 // "LitDirectional"
        [Toggle(_DIRECTIONAL_LIGHT)] _DirectionalLightProxy("Directional Light", Float) = 1.0 // "LitDirectional"
        [Toggle(_SPECULAR_HIGHLIGHTS)] _SpecularHighlights("Specular Highlights", Float) = 1.0
        [Toggle(_SPHERICAL_HARMONICS)] _SphericalHarmonics("Spherical Harmonics", Float) = 0.0
        [Toggle(_NON_PHOTOREALISTIC)] _NPR("Non-Photorealistic Rendering", Float) = 0.0
        [Toggle(_RECEIVESHADOW)] _ReceiveShadow("ReceiveShadow",Float) =0.0//追加
        [Toggle(_REFLECTIONS)] _Reflections("Reflections", Float) = 0.0

[Toggle()]アトリビュートを付けることでマテリアルプロパティ上でチェックボックスとしてシェーダーの機能を使用することができます。

次にシェーダーの中でチェックボックスに応じて処理を変えることができるようにGrahpicsToolsStandardProgram.hlslの冒頭部にShader Featureを追加します。

#pragma shader_feature_local _LOCAL_SPACE_TRIPLANAR_MAPPING
#pragma shader_feature_local_fragment _USE_SSAA
#pragma shader_feature_local _ _DIRECTIONAL_LIGHT _DISTANT_LIGHT
#pragma shader_feature_local _NON_PHOTOREALISTIC
#pragma shader_feature_local _RECEIVESHADOW//追加

これでReceiveShadowが有効な場合#if defined(_RECEIVESHADOW)で条件コンパイルを使用することができるようになりました。

通常のシェーダーの場合これで早速機能を衣装することができますが、今回ば前述のとおりStandardShaderGUI.csで表示が管理されているためこのままではプロパティが表示されることはありません。

StandardShaderGUI.csの追加点は次の4点です。

    public class StandardShaderGUI : BaseShaderGUI
    {
        /// <summary>
        /// Common names, keywords, and tooltips.
        /// </summary>
        protected static class Styles
        {
   ・・・
            public static readonly GUIContent receiveShadow = new GUIContent("Receive Shadow");
   ・・・
       }
   ・・・
        protected MaterialProperty receiveShadow;
   ・・・
   protected override void FindProperties(MaterialProperty[] props)
        {
            base.FindProperties(props);
   ・・・
            receiveShadow = FindProperty("_ReceiveShadow", props);
   ・・・
        }

       protected void RenderingOptions(MaterialEditor materialEditor, Material material)
        {
            EditorGUILayout.Space();
            GUILayout.Label(Styles.renderingOptionsTitle, EditorStyles.boldLabel);

    ・・・

            if ((LightMode)lightMode.floatValue != LightMode.Unlit)
            {
    ・・・
                materialEditor.ShaderProperty(receiveShadow, Styles.receiveShadow, 2);
            }

行っているのはStandardShaderGUI.cs内で変数の定義を行い、Shader側から変数を取得しています。

    public class StandardShaderGUI : BaseShaderGUI
    {
        /// <summary>
        /// Common names, keywords, and tooltips.
        /// </summary>
        protected static class Styles
        {
   ・・・
            public static readonly GUIContent receiveShadow = new GUIContent("Receive Shadow");
   ・・・
       }
   ・・・
        protected MaterialProperty receiveShadow;
   ・・・
   protected override void FindProperties(MaterialProperty[] props)
        {
            base.FindProperties(props);
   ・・・
            receiveShadow = FindProperty("_ReceiveShadow", props);//Shaderから変数を基に対応させる。
   ・・・
        }

最後にlightModeUnlit以外の場合、つまりライトを使用できる状態の場合マテリアルのプロパティに表示を行っています。

これでReceiveShadowのプロパティが表示されます。

本日は以上です。

次回MRGTのシェーダー内部に影の描画を組み込んでいきます。

redhologerbera.hatenablog.com