夜風のMixedReality

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

GraphicsToolsStandardShaderのMetaShaderに関して学ぶ

本日はMRGT勉強枠です。

現在MRGTのプロジェクトへPRを提出しています。

 レビューアーの方がチェックしていただいており、いくつかの修正依頼が来ています。

 今回は残す最後の修正依頼にトライします。

〇メタシェーダーの役割と実装

最後に残った修正依頼はMetaShaderに関するものでした。

Could you update the meta shader to also sample this emissive map? That way when generating static lighting (light maps) this texture is considered.

メタシェーダを更新して、このエミッシブマップもサンプリングできるようにできませんか?

MetaShaderとはGraphicsToolsStandardMetaProgram.hlslのことでGraphicsToolsStandardShaderでメインの処理の次に2つ目のSubShaderとして記述されているシェーダーです。

github.com

        // Extracts information for lightmapping, GI (emission, albedo, ...)
        // This pass it not used during regular rendering.
        Pass
        {
            Name "Meta"
            Tags { "LightMode" = "Meta" }

            HLSLPROGRAM

            #define _URP

            #include_with_pragmas "GraphicsToolsStandardMetaProgram.hlsl"
            
            ENDHLSL
        }

このシェーダーは実機上で実行されることはなくエディタ上のみで実行されます。

役割としてはライトベイクなどの静的ライティングなどで使用されます。

処理内容としてはメインの処理よりもはるかに短くなっています。

/// <summary>
/// Fragment (pixel) shader entry point.
/// </summary>
half4 PixelStage(MetaVaryings input) : SV_Target
{
#if defined(_URP)
    MetaInput output = (MetaInput)0;
    output.Albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv).rgb * _Color.rgb;
#if defined(_EMISSION)
#if defined(_CHANNEL_MAP)
    output.Emission = SAMPLE_TEXTURE2D(_ChannelMap, sampler_ChannelMap, input.uv) * _EmissiveColor;
#endif
#endif

    return MetaFragment(output);
#else
    UnityMetaInput output = (UnityMetaInput)0;
    output.Albedo = tex2D(_MainTex, input.uv) * _Color;
#if defined(_EMISSION)
#if defined(_CHANNEL_MAP)
    output.Emission += tex2D(_ChannelMap, input.uv).b * _EmissiveColor;
#else
    output.Emission += _EmissiveColor;
#endif
#endif
    output.SpecularColor = _LightColor0.rgb;

    return UnityMetaFragment(output);
#endif
}

ここでMetaInput,UnityMetaInputはURPのShaderlibraryから提供されている型(Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl" )でURPの場合MetaInput,ビルドインの場合UnityMetaInputが使用されます。

 これらはUnityのライトマップに使用される専用のシェーダーで、ライトマップ用のテクスチャ座標で値が返されます。

docs.unity3d.com

今回は追加実装した発光マップを使用してemissionとして登録されるようにそれぞれoutput.Emissionに_EmissiveMapの処理を追加しました。

half4 PixelStage(MetaVaryings input) : SV_Target
{
 ...
#if defined(_EMISSION)
#if defined(_CHANNEL_MAP)
    output.Emission = SAMPLE_TEXTURE2D(_ChannelMap, sampler_ChannelMap, input.uv) * _EmissiveColor;
#else
    output.Emission = SAMPLE_TEXTURE2D(_EmissiveMap, sampler_EmissiveMap, input.uv) * _EmissiveColor; //追加
#endif
#endif

    return MetaFragment(output);
#else
    UnityMetaInput output = (UnityMetaInput)0;
    output.Albedo = tex2D(_MainTex, input.uv) * _Color;
#if defined(_EMISSION)
#if defined(_CHANNEL_MAP)
    output.Emission += tex2D(_ChannelMap, input.uv).b * _EmissiveColor;
#else
    output.Emission += _EmissiveColor;
    output.Emission = tex2D(_EmissiveMap, input.uv) * _EmissiveColor;//追加
#endif
#endif
    output.SpecularColor = _LightColor0.rgb;
    return UnityMetaFragment(output);
#endif
}

本日は以上です。

これでPRに対してのフィードバックはすべて修正しました。 再びレビューしていただいていきます。