ビルトインレンダーパイプライン用に記述されたカスタムシェーダーは、ユニバーサルレンダーパイプライン (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
}
}
}
ビルトインレンダーパイプラインのシェーダーには以下の 2 つの問題があり、それらは Inspector ウィンドウに表示されます。
これらの問題を解決し、シェーダーを URP や SRP バッチャーと互換性のあるものに変える方法は、以下の手順のとおりです。
CGPROGRAM と ENDCG を HLSLPROGRAM と ENDHLSL に変更します。
Core.hlsl ファイルを参照するように include ステートメントを更新します。
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
メモ:
Core.hlslには、コア SRP ライブラリ、URP シェーダー変数、行列の定義と変換が含まれていますが、ライティング関数やデフォルト構造体は含まれていません。
シェーダーのタグに "RenderPipeline" = "UniversalPipeline" を加えます。
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
ノート: URP はすべての ShaderLab タグをサポートするわけではありません。URP がサポートするタグの詳細は、URP ShaderLab パスのタグ を参照してください。
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;
};
include ステートメントの下で、Varyings 構造体の上に、Attributes という名前の新しい構造体を定義します。これはビルトインレンダーパイプラインの appdata 構造体と同等ですが、新しい URP 命名規則があります。
以下に示す変数を Attributes 構造体に加えます。
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
新しい Varyings 構造体を使用して Attributes 構造体のインスタンスを入力として受け取るように、v2f vert 関数定義を以下のとおりに更新します。
Varyings vert(Attributes IN)
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は同種のクリップスペースを意味します。
シェーダーが使用するプロパティの周囲に、UnityPerMaterial パラメーターとともに、CBUFFER コードブロックを配置します。
CBUFFER_START(UnityPerMaterial)
float4 _Color;
sampler2D _MainTex;
CBUFFER_END
ノート: シェーダーに SRP バッチャーとの互換性を持たせるには、すべてのマテリアルプロパティを
CBUFFERコード ブロック内で宣言する必要があります。シェーダーに複数のパスがある場合でも、すべてのパスで同じCBUFFERブロックを使用する必要があります。
frag 関数が Varyings 入力とタイプ half4 を使用するように、以下のとおりに更新します。URP シェーダーは固定タイプをサポートしないため、frag 関数はここでこのタイプを使用する必要があります。
half4 frag(Varyings IN) : SV_Target
{
half4 texel = tex2D(_MainTex, IN.uv);
return texel * _Color;
}
これで、このカスタム Unlit シェーダーは SRP バッチャーと互換性のあるものになり、URP 内で使用できるようになりました。これは Inspector ウィンドウで確認できます。
これでシェーダーは URP や SRP バッチャーと互換性のあるものになりましたが、Tiling プロパティと Offset プロパティは追加の変更なしでは使用できません。この機能をカスタム Unlit シェーダーに追加するには、以下の手順に従います。
プロパティ _MainTex の名前を _BaseMap に変更し、このプロパティへの参照も変更します。これにより、シェーダーコードが標準の URP シェーダー規則に近づきます。
_BaseMap プロパティから [NoScaleOffset] ShaderLab 属性を削除します。これで、シェーダーの Inspector ウィンドウに Tiling プロパティと Offset プロパティが表示されるようになります。
[MainTexture] ShaderLab 属性を _BaseMap プロパティに加えて、[MainColor] 属性を _Color プロパティに加えます。これは、プロジェクトの他の部分から、またはエディターで、メインテクスチャやメインカラーをリクエストしたときに、どのプロパティを返すのかをエディターに指示するものです。シェーダーの Properties セクションは以下のようになります。
Properties
{
[MainTexture] _BaseMap("Main Texture", 2D) = "white" {}
[MainColor] _Color("Color", Color) = (1,1,1,1)
}
TEXTURE2D(_BaseMap) マクロと SAMPLER(sampler_BaseMap) マクロを CBUFFER ブロックの上に加えます。これらのマクロは、後で使用するテクスチャとサンプラーの状態変数を定義します。サンプラー状態の詳細は、サンプラー状態の使用 を参照してください。
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER ブロック内の sampler2D _BaseMap 変数を float4 _BaseMap_ST に変更します。これで、この変数は Inspector で設定されたタイリング値とオフセット値を格納するようになります。
CBUFFER_START(UnityPerMaterial)
float4 _Color;
float4 _BaseMap_ST;
CBUFFER_END
tex2D でテクスチャに直接アクセスする代わりに、マクロを使用するように frag 関数を変更します。それには、以下のように、tex2D を SAMPLE_TEXTURE2D マクロに置き換えて、追加パラメーターとして sampler_BaseMap を加えます。
half4 frag(Varyings IN) : SV_Target
{
half4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
return texel * _Color;
}
vert 関数で、テクスチャ座標を IN.uv として直接渡す代わりに、マクロを使用するように OUT.uv を変更します。それには、IN.uv を TRANSFORM_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
}
}
}