夜風のMixedReality

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

Unity URP環境でMultiPassのシェーダーを描く

本日はShader学習枠です。

〇URP環境でマルチパスが実行されない問題

次のようなごく簡単なアウトラインシェーダーを描きました。

f:id:Holomoto-Sumire:20220127191957p:plain

仕組みとしては2つのPassブロックを使用して、2回描画を行っています。

1回目でオブジェクトを法線方向に大きく、そして面の裏面を描画しています。

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex+v.normal*0.02);
                return o;
            }

2回目の描画で通常のオブジェクトを描画することでアウトラインを再現しています。

〇コード
Shader "Unlit/test"
{
    Properties
    {
        _MainColor("color",color)=(1,1,1,1)
        _OutLineColor("outlineColor",color)=(1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
                Tags{ "LightMode" = "UniversalForward"}
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            float4 _OutLineColor;
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex+v.normal*0.02);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col =_OutLineColor;
                return col;
            }
            ENDCG
        }
        pass{
             CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            float4 _MainColor;
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = _MainColor;
                return col;
            }
            ENDCG
        }
        
    }
}

しかしURPプロジェクトでは画像のように一つ目のパスは実行され描画されますが、2つ目のパスが描画されない問題があります。

f:id:Holomoto-Sumire:20220127192639p:plain

これはURP環境ではレンダリングの仕組みが変わっているためです。

〇解消

一つ目のパスにTagsブロックを追加します。

  Pass
        {
            Tags{ "LightMode" = "UniversalForward"}←追加
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            float4 _OutLineColor;
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };
          ...
    }
Pass
          {
             ...
          }

この"LightMode" = "UniversalForward"を一行追加することでマルチパスが実行されるようになります。

f:id:Holomoto-Sumire:20220127192254p:plain