夜風のMixedReality

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

GraphicsToolsStandardシェーダーにEmissiveMapの機能を追加する。 その② Shaderの改造

本日は昨日に引き続きGraphicsToolsのStandardシェーダー機能開発を行います。

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

 

github.com

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

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

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

 GraphicsToolsStandardシェーダーに新しいプロパティを追加し、機能を追加するにはシェーダー本体の処理の追加に加えStandardShaderGUI.csの改修を行いUnityのインスペクタにマテリアルプロパティとしての表示をカスタマイズする必要があります。

 前回はこのカスタムエディタの実装を行いました。

redhologerbera.hatenablog.com

 今回はShader本体の処理を行います。

〇GraphicsToolsStandardInput.hlsl

GraphicsToolsStandardInput.hlslGraphicsToolsStandardシェーダーで使用されるサンプラーや変数の定義が行われています。

新しいプロパティを追加した場合、このファイルで変数を定義する必要があります。

テクスチャの定義は100行目当たりから行われており、#if defined(_URP)~ #else~ #endifでURPの場合とビルドインの場合で定義を分岐させています。

つまりURP、ビルドインそれぞれで定義を行う必要があります。

今回は次のようにEmissionに関連してテクスチャを定義しました。

#if defined(_URP)
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
 ...
#if defined(_EMISSION)
TEXTURE2D(_EmissiveMap); //追加
SAMPLER(sampler_EmissiveMap);//追加
#endif
 ...
#else
sampler2D _MainTex;
  ...
#if defined(_EMISSION)
sampler2D _EmissiveMap;//追加
#endif
 ...
#endif

URPではTexture2DとSamplerをそれぞれ定義しています。

〇GraphicsToolsStandardProgram.hlsl

GraphicsToolsStandardProgram.hlslはStandardシェーダーのメインの処理を行っています。

 今回EmissiveMapの機能は380行目当たりのピクセルシェーダーに処理を記述します。

half4 PixelStage(Varyings input, bool facing : SV_IsFrontFace) : SV_Target
{
...
}

ピクセルシェーダーでは冒頭部でテクスチャ関連のサンプリングを行っています。

今回はGrapcisToolsStandardシェーダーのマテリアルプロパティの並びにのっとってChannelMapのサンプリングの次にEmissiveMapの処理を記述しました。

#if defined(_EMISSION)//Emissionを有効にしている場合
#if defined(_URP)//URPの処理
    half3 emissionMap = SAMPLE_TEXTURE2D(_EmissiveMap, sampler_EmissiveMap, input.uv);
#else//ビルドインの処理
    half3 emissionMap = tex2D(_EmissiveMap, input.uv);
#endif
#endif

処理内容としてはいずれもemissonMapという変数を用意し、テクスチャをサンプリングしているだけです。

最後にサンプリングした値を_EmissiveColorと掛け合わせます。

この処理は480行目当たりで行われています。

#if defined(_EMISSION)
#if defined(UNITY_COLORSPACE_GAMMA)
    half3 emission = _EmissiveColor.rgb;
    emission *= emissionMap;
#else // Since emission is an HDR color convert from sRGB to linear.
    half3 emission = GTsRGBToLinear(_EmissiveColor.rgb);
    emission *= emissionMap;
#endif

これによって最終的に出力される値に加算されているemission_EmissiveColor_EmissiveMapを掛け合わせた値が加算されることになります。

以上でGraphicsToolsStandardシェーダーにEmissiveMap(発光マップ)を追加することができました。

以上で機能としては完成しましたが、OSSとしてPRを出すうえでコードなどをもう少ししてPRを出したいと思います。