本日はShader学習枠です。
先日より開発しているMRGT向けのNPR機能を本家MRGTへ提出しようと思います。
今回はまずシェーダーの機能を埋め込む場所を準備していきます。
〇LightMode
MRGTではv0.4以降のDevelopブランチではLightModeが従来のDirectionalLightのチェックボックスからEnum型の選択になっています。
今回ここにNPRの選択肢を追加します。
このLightModeはGraphicsToolsStandardShaderのPropetiesブロックで定義されています。
// Rendering options. [Enum(Microsoft.MixedReality.GraphicsTools.Editor.LightMode)] _DirectionalLight("Light Mode", Float) = 1.0 // "LitDirectional"
さらにカスタムシェーダーGUIの機能によりStandardShaderGUI.csによってインスペクター上の表示を制御されています。
/// <summary> /// What type of direct light affects the surface. /// </summary> public enum LightMode { Unlit = 0, LitDirectional = 1, LitDistant = 2 }
まずはここに新しいモードとしてNPRを追加します。
public enum LightMode { Unlit = 0, LitDirectional = 1, LitDistant = 2, NonPhotorealistic = 3//追加 }
次に実際に新しく追加したパラメータを使用できるようにstring[] lightModeNamesに登録します。
public static readonly string[] lightModeNames = new string[] { "Unlit", "Lit - Directional", "Lit - Distant" , "Non - Photorealistic" };//追加 public static readonly string lightModeLitDirectional = "_DIRECTIONAL_LIGHT"; public static readonly string lightModeLitDistant = "_DISTANT_LIGHT";
これでマテリアルのパラメータとして使用できるようになります。
次に実際にパラメータが選択されたときのマテリアルの処理を記述します。
これはprotected void RenderingOption()で定義されています。
ここはLightModeの選択によって処理を分岐するSwitch文があります。
ここにLightMode.NonPhotorealisticとして新たな処理を追記します。
case LightMode.LitDistant: { material.DisableKeyword(Styles.lightModeLitDirectional); material.EnableKeyword(Styles.lightModeLitDistant); GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(DistantLight), Styles.lightModeNames[(int)LightMode.LitDistant]), EditorStyles.helpBox, Array.Empty<GUILayoutOption>()); } break; case LightMode.NonPhotorealistic: { material.EnableKeyword(Styles.lightModeLitDirectional); material.DisableKeyword(Styles.lightModeLitDistant); } break;
処理の中身は
material.EnableKeyword(Styles.lightModeLitDirectional); //シェーダーキーワードからlightModeLitDirectionalを有効化 material.DisableKeyword(Styles.lightModeLitDistant); // シェーダーキーワードからlightModeLitDistantを無効か //それぞれ定義されているstring型の名前が使用される // public static readonly string lightModeLitDirectional = "_DIRECTIONAL_LIGHT"; // public static readonly string lightModeLitDistant = "_DISTANT_LIGHT";
を行います。
このシェーダーキーワードとはGraphicsToolsStandardProgram.hlslの冒頭に定義されています。
MRGTのシェーダーではここで定義されたシェーダーキーワードをもとに必要な処理と不要な処理で条件コンパイルしています。
#pragma shader_feature_local _ _DIRECTIONAL_LIGHT _DISTANT_LIGHT
今回はDirectonaliLightを使うかどうかの分岐ではないので新たにキーワードを追加しました。
#pragma shader_feature_local _NPR_Rendering
ShaderGUI.csに戻り追加したキーワードを使用できるようにします。
public static readonly string lightModeLitDirectional = "_DIRECTIONAL_LIGHT"; public static readonly string lightModeLitDistant = "_DISTANT_LIGHT"; public static readonly string lightModeNPR = "_NPR_Rendering";
最後に作成したSwitch文の処理にlightModeNPRを有効化する処理を加えます。
case LightMode.NonPhotorealistic: { material.EnableKeyword(Styles.lightModeLitDirectional); material.EnableKeyword(Styles.lightModeNPR);//追加 material.DisableKeyword(Styles.lightModeLitDistant); } break;
以上でShaderGUIの編集が完了して分岐処理を組み込めるようになりました。
次回今回作成した準備を使用してレンダリングの処理を分けていきます。