夜風のMixedReality

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

MixedRealityGraphicsTools StndardShader全機能解説 その⑥ ChannelMapの実装を読み解く

本日はMRGT調査枠です。

前回はメインの機能であるAlbedoを見ていきました。

redhologerbera.hatenablog.com

今回は次に表示されているchannelMapの機能を読み解いていきます。

〇channelMapとは?

channelMapは特殊な画像で、質感を管理する画像です。

一枚でメタリック、なめらかさ、影の陰影、発光といった4つの情報を管理でき、一枚で管理できるため負荷が軽くなっています。

〇ChannelMapの実装を読み解く

ChannelMapの実装はGraphicsToolsのプロパティブロックで次のように定義されています。

        [Toggle(_CHANNEL_MAP)] _EnableChannelMap("Enable Channel Map", Float) = 0.0
        [NoScaleOffset] _ChannelMap("Channel Map", 2D) = "white" {}

_EnableChannelMapはShaderFeatureの機能として定義されています。

インスペクタ上の値をカスタマイズしているStandardShaderGUI.cs_EnableChannelMapのチェックボックスが有効になっている場合_ChannelMapの表示が有効になるように設定されています。

また_EnableChannelMapのチェックボックスが有効になっている場合GraphicsToolsStandardProgoram.hlslの中でShaderFeatureとして定義されており、_CHANNEL_MAPのキーワードが定義されるようになります。

#pragma shader_feature_local _CHANNEL_MAP

これによってフラグメントシェーダー内でChannnelMap関連の機能が有効になっています。

half4 PixelStage(Varyings input, bool facing : SV_IsFrontFace) : SV_Target
{
・・・
#if defined(_CHANNEL_MAP)
#if defined(_URP)
    half4 channel = SAMPLE_TEXTURE2D(_ChannelMap, sampler_ChannelMap, input.uv);
#else
    half4 channel = tex2D(_ChannelMap, input.uv);
#endif
    _Metallic = channel.r;
    albedo.rgb *= channel.g;
    _Smoothness = channel.a;
#else
・・・
#endif


・・・
#if defined(_CHANNEL_MAP)
    output.rgb += emission * channel.b;
#else
・・・
}

おこなわれている処理はhalf4 channelにサンプリングした情報が与えられています。

#if defined(_CHANNEL_MAP)
#if defined(_URP)
    half4 channel = SAMPLE_TEXTURE2D(_ChannelMap, sampler_ChannelMap, input.uv);
#else
    half4 channel = tex2D(_ChannelMap, input.uv);
#endif

次にメタリック情報を扱っている_Metallicにchannelの1次元成分であるRを、最終的な出力であるalbedo.rgbにchannelの2次元成分であるGを、なめらかさの情報を扱ている_Smoothnessのchannelの4次元成分であるAの値をそれぞれ渡しています。

    _Metallic = channel.r;
    albedo.rgb *= channel.g;
    _Smoothness = channel.a;

ここでOcclusionであるchannel.gに関して軽く紹介すると、OcclusionMapでは影を反映させることができます。

ここではalbedoに0~1の値であるchannel.gをかけ合わせることでもともとのalbedoの値が小さくなります。(1より大きい値をかけ合わせない限りもともとの値を大きくなることはないため)

このようにしてchannelmapの緑成分に応じて暗くすることでOcclusionMapを実現しています。

docs.unity3d.com

最後にchannelの3次元成分である青に関してですが、これはemissionに掛け合わされることで発光情報として扱うことができます。

   output.rgb += emission * channel.b;

channelMapの実装は以上です。