Version: Unity 6.0 (6000.0)
言語 : 日本語
レンダーパイプラインコンバータを使用してシェーダーを URP に変換する
Change how lights fade to match the Built-In Render Pipeline

カスタムシェーダーを URP との互換性のためにアップグレードする

ビルトインレンダーパイプライン用に記述されたカスタムシェーダーは、ユニバーサルレンダーパイプライン (URP) と互換性がなく、レンダーパイプラインコンバータで自動的にアップグレードされません。代わりに、シェーダーコードで互換性のない部分を書き直し、URP で使用できるようにする必要があります。

Shader Graph でカスタムシェーダーを再作成することもできます。詳細は、ShaderGraph のドキュメントを参照してください。

ノート: URP にアップグレードすると、カスタムシェーダーを使用しているシーン内のマテリアルは、エラーを表すマゼンタ (明るいピンク) 色に変わりますので、その色の変化で特定することができます。

このガイドでは、ビルトインレンダーパイプラインのカスタム Unlit シェーダーを URP と完全に互換性のあるにものにアップグレードする方法について説明します。このガイドは以下のセクションで構成されています。

ビルトインレンダーパイプラインのシェーダーの例

以下のシェーダーは、ビルトインレンダーパイプラインで動作するシンプルな Unlit シェーダーです。このガイドでは、これを URP と互換性のあるシェーダーにアップグレードする方法について説明します。

Shader "Custom/UnlitShader"
{
    Properties
    {
        [NoScaleOffset] _MainTex("Main Texture", 2D) = "white" {}
        _Color("Color", Color) = (1,1,1,1)
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" }

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct v2f
            {
                float4 position : SV_POSITION;
                float2 uv: TEXCOORD0;
            };

            float4 _Color;
            sampler2D _MainTex;

            v2f vert(appdata_base v)
            {
                v2f o;

                o.position = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed4 texel = tex2D(_MainTex, i.uv);
                return texel * _Color;
            }
            ENDCG
        }
    }
}

カスタムシェーダーに URP との互換性を持たせる

ビルトインレンダーパイプラインのシェーダーには以下の 2 つの問題があり、それらは Inspector ウィンドウに表示されます。

  • Material property is found in another cbuffer (Material プロパティが別の cbuffer で見つかりました) という警告。
  • SRP Batcher プロパティに表示される not compatible (互換性なし)。

これらの問題を解決し、シェーダーを URP や SRP バッチャーと互換性のあるものに変える方法は、以下の手順のとおりです。

  1. CGPROGRAMENDCGHLSLPROGRAMENDHLSL に変更します。

  2. Core.hlsl ファイルを参照するように include ステートメントを更新します。

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

    メモ: Core.hlsl には、コア SRP ライブラリ、URP シェーダー変数、行列の定義と変換が含まれていますが、ライティング関数やデフォルト構造体は含まれていません。

  3. シェーダーのタグに "RenderPipeline" = "UniversalPipeline" を加えます。

    Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
    

    ノート: URP はすべての ShaderLab タグをサポートするわけではありません。URP がサポートするタグの詳細は、URP ShaderLab パスのタグ を参照してください。

  4. struct v2f コードブロックを以下の struct Varyings コードブロックに置き換えます。これにより、v2f ではなく Varyings という URP 命名規則を使用するように構造体が変更され、URP に正しい変数を使用するようにシェーダーが更新されます。

    struct Varyings
    {
        // The positions in this struct must have the SV_POSITION semantic.
        float4 positionHCS  : SV_POSITION;
        float2 uv : TEXCOORD0;
    };
    
  5. include ステートメントの下で、Varyings 構造体の上に、Attributes という名前の新しい構造体を定義します。これはビルトインレンダーパイプラインの appdata 構造体と同等ですが、新しい URP 命名規則があります。

  6. 以下に示す変数を Attributes 構造体に加えます。

    struct Attributes
    {
        float4 positionOS   : POSITION;
        float2 uv : TEXCOORD0;
    };
    
  7. 新しい Varyings 構造体を使用して Attributes 構造体のインスタンスを入力として受け取るように、v2f vert 関数定義を以下のとおりに更新します。

    Varyings vert(Attributes IN)
    
  8. Varyings 構造体のインスタンスを出力し、TransformObjectToHClip 関数を使用してオブジェクト空間からクリップスペースに変換するように、vert 関数を更新します。この関数は、入力 Attributes UV を受け取り、出力 Varyings UV に渡す必要もあります。

    Varyings vert(Attributes IN)
    {
        Varyings OUT;
    
        OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
        OUT.uv = IN.uv;
    
        return OUT;
    }
    

    ノート: URP シェーダーは、サフィックスを使用してスペースを示します。OS はオブジェクト空間、HCS は同種のクリップスペースを意味します。

  9. シェーダーが使用するプロパティの周囲に、UnityPerMaterial パラメーターとともに、CBUFFER コードブロックを配置します。

    CBUFFER_START(UnityPerMaterial)
    float4 _Color;
    sampler2D _MainTex;
    CBUFFER_END
    

    ノート: シェーダーに SRP バッチャーとの互換性を持たせるには、すべてのマテリアルプロパティを CBUFFER コード ブロック内で宣言する必要があります。シェーダーに複数のパスがある場合でも、すべてのパスで同じ CBUFFER ブロックを使用する必要があります。

  10. frag 関数が Varyings 入力とタイプ half4 を使用するように、以下のとおりに更新します。URP シェーダーは固定タイプをサポートしないため、frag 関数はここでこのタイプを使用する必要があります。

    half4 frag(Varyings IN) : SV_Target
    {
        half4 texel = tex2D(_MainTex, IN.uv);
        return texel * _Color;
    }
    

これで、このカスタム Unlit シェーダーは SRP バッチャーと互換性のあるものになり、URP 内で使用できるようになりました。これは Inspector ウィンドウで確認できます。

  • Material property is found in another cbuffer という警告は表示されなくなります。
  • SRP Batcher プロパティに compatible (互換性あり) が表示されます。

シェーダーのタイリングとオフセットを有効にする

これでシェーダーは URP や SRP バッチャーと互換性のあるものになりましたが、Tiling プロパティと Offset プロパティは追加の変更なしでは使用できません。この機能をカスタム Unlit シェーダーに追加するには、以下の手順に従います。

  1. プロパティ _MainTex の名前を _BaseMap に変更し、このプロパティへの参照も変更します。これにより、シェーダーコードが標準の URP シェーダー規則に近づきます。

  2. _BaseMap プロパティから [NoScaleOffset] ShaderLab 属性を削除します。これで、シェーダーの Inspector ウィンドウに Tiling プロパティと Offset プロパティが表示されるようになります。

  3. [MainTexture] ShaderLab 属性を _BaseMap プロパティに加えて、[MainColor] 属性を _Color プロパティに加えます。これは、プロジェクトの他の部分から、またはエディターで、メインテクスチャやメインカラーをリクエストしたときに、どのプロパティを返すのかをエディターに指示するものです。シェーダーの Properties セクションは以下のようになります。

    Properties
    {
        [MainTexture] _BaseMap("Main Texture", 2D) = "white" {}
        [MainColor] _Color("Color", Color) = (1,1,1,1)
    }
    
  4. TEXTURE2D(_BaseMap) マクロと SAMPLER(sampler_BaseMap) マクロを CBUFFER ブロックの上に加えます。これらのマクロは、後で使用するテクスチャとサンプラーの状態変数を定義します。サンプラー状態の詳細は、サンプラー状態の使用 を参照してください。

    TEXTURE2D(_BaseMap);
    SAMPLER(sampler_BaseMap);
    
  5. CBUFFER ブロック内の sampler2D _BaseMap 変数を float4 _BaseMap_ST に変更します。これで、この変数は Inspector で設定されたタイリング値とオフセット値を格納するようになります。

    CBUFFER_START(UnityPerMaterial)
    float4 _Color;
    float4 _BaseMap_ST;
    CBUFFER_END
    
  6. tex2D でテクスチャに直接アクセスする代わりに、マクロを使用するように frag 関数を変更します。それには、以下のように、tex2DSAMPLE_TEXTURE2D マクロに置き換えて、追加パラメーターとして sampler_BaseMap を加えます。

    half4 frag(Varyings IN) : SV_Target
    {
        half4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
        return texel * _Color;
    }
    
  7. vert 関数で、テクスチャ座標を IN.uv として直接渡す代わりに、マクロを使用するように OUT.uv を変更します。それには、IN.uvTRANSFORM_TEX(IN.uv, _BaseMap) に置き換えます。これで vert 関数は以下の例のようになります。

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

    ノート: TRANSFORM_TEX マクロは _ST サフィックスを持つパラメーターを使用するため、vert 関数を CBUFFER ブロックの後に定義することが重要です。

これで、このシェーダーは、色により変更されたテクスチャを持ち、SRP バッチャーと完全に互換性のあるものになりました。Tiling プロパティと Offset プロパティも完全にサポートします。

シェーダーコードの完全なサンプルについては、このページの シェーダーの完全なコード セクションを参照してください。

シェーダーの完全なコード

Shader "Custom/UnlitShader"
{
    Properties
    {
        _BaseMap("Base Map", 2D) = "white" {}
        _Color("Color", Color) = (1,1,1,1)
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag

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

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

            struct Varyings
            {
                float4 positionCS  : SV_POSITION;
                float2 uv: TEXCOORD0;
            };

            TEXTURE2D(_BaseMap);
            SAMPLER(sampler_BaseMap);

            CBUFFER_START(UnityPerMaterial)
            float4 _Color;
            float4 _BaseMap_ST;
            CBUFFER_END

            Varyings vert(Attributes IN)
            {
                Varyings OUT;

                OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);

                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                float4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
                return texel * _Color;
            }
            ENDHLSL
        }
    }
}
レンダーパイプラインコンバータを使用してシェーダーを URP に変換する
Change how lights fade to match the Built-In Render Pipeline