【Unity】URPでUnityのフォグに対応したシェーダを書く

UnityのURPでUnityのフォグに対応したシェーダを書く方法についてまとめました。

Unity2020.3.15f2

はじめに

本記事ではURPのシェーダをUnityのフォグ機能に対応させる方法についてまとめます。
対応自体は簡単ですが、レガシーパイプラインとは書き方が違うのでまとめておきます。

なおURPにおける基本的なシェーダの書き方は以下の記事にまとめていますので、必要に応じて参照してください。

light11.hatenadiary.com

本記事のシェーダも上記のものをベースにして記述しています。

シェーダ

それでは早速シェーダです。

Shader "Example"
{
    Properties
    {
        _BaseMap("Base Map", 2D) = "white" {}
        _BaseColor("Base Color", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "IgnoreProjector" = "True"
            "Queue" = "Geometry"
        }

        Pass
        {
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            // フォグ用のシェーダバリアントを生成するための記述
            #pragma multi_compile_fog

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                // フォグの計算で使うfog factor用のinterpolator
                half fogFactor : TEXCOORD1;
            };

            sampler2D _BaseMap;

            CBUFFER_START(UnityPerMaterial)
            float4 _BaseMap_ST;
            half4 _BaseColor;
            CBUFFER_END

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);

                // Fog factorを計算
                OUT.fogFactor = ComputeFogFactor(OUT.positionHCS.z);
                
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                half4 color = tex2D(_BaseMap, IN.uv) * _BaseColor;
                
                // Fogを適用する
                color.rgb = MixFog(color.rgb, IN.fogFactor);
                
                return color;
            }
            ENDHLSL
        }
    }
}

フォグに関わるコードにはコメントを記載しています。

レンダリング結果

次にレンダリング結果を確認するために、Lightingウィンドウから赤いフォグを設定し、シェーダをアサインしたオブジェクトを作成します。

下図はURPのUnlitを適用したPlaneの上に今回のシェーダをアサインしたSphereを配置している図です。

結果

正常にフォグがかかっていることが確認できました。

関連

light11.hatenadiary.com