빌트인 렌더 파이프라인용으로 작성된 커스텀 셰이더는 URP(유니버설 렌더 파이프라인)와 호환되지 않으며, 렌더 파이프라인 컨버터를 사용하여 자동으로 업그레이드할 수 없습니다. URP와 호환되도록 하려면 셰이더 코드의 호환되지 않는 섹션을 다시 작성해야 합니다.
Shader Graph에서 커스텀 셰이더를 재생성하는 것도 가능합니다. 자세한 내용은 ShaderGraph에 대한 기술 자료를 참조하십시오.
참고: URP로 업그레이드하면 커스텀 셰이더를 사용하는 씬의 모든 머티리얼이 오류가 있을 경우 자홍색(밝은 분홍색)으로 바뀌므로 이를 식별할 수 있습니다.
이 가이드에서는 다음 섹션을 통해 빌트인 렌더 파이프라인에서 커스텀 언릿 셰이더를 업그레이드하여 URP와 완벽하게 호환되는 방법을 설명합니다.
다음 셰이더는 빌트인 렌더 파이프라인과 호환되는 간단한 언릿 셰이더입니다. 이 가이드는 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 및 SRP 배처와 호환되도록 하는 방법은 다음과 같습니다.
CGPROGRAM과 ENDCG를 HLSLPROGRAM과 ENDHLSL로 변경합니다.
include 문을 업데이트하여 Core.hlsl 파일을 참조합니다.
#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)
vert 함수를 업데이트하여 Varyings 구조체의 인스턴스를 출력하고 TransformObjectToHClip 함수를 사용하여 오브젝트 공간에서 클립 공간으로 전환합니다. 또한 이 함수는 입력 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는 균일한 클립 공간을 의미합니다.
셰이더가 사용하는 프로퍼티 주위에 CBUFFER 코드 블록을 UnityPerMaterial 파라미터와 함께 배치합니다.
CBUFFER_START(UnityPerMaterial)
float4 _Color;
sampler2D _MainTex;
CBUFFER_END
참고: 셰이더가 SRP 배처와 호환되려면
CBUFFER코드 블록 내에서 모든 머티리얼 프로퍼티를 선언해야 합니다. 셰이더에 여러 패스가 있는 경우에도 모든 패스가 동일한CBUFFER블록을 사용해야 합니다.
Varyings 입력과 half4 유형을 사용하도록 frag 함수를 아래와 같이 업데이트합니다. 이제 frag 함수는 URP 셰이더가 고정 유형을 지원하지 않으므로 이 유형을 사용해야만 합니다.
half4 frag(Varyings IN) : SV_Target
{
half4 texel = tex2D(_MainTex, IN.uv);
return texel * _Color;
}
이 커스텀 언릿 셰이더는 이제 SRP 배처와 호환되며 URP에서 사용할 수 있습니다. 이는 인스펙터 창에서 확인할 수 있습니다.
이제 셰이더가 URP 및 SRP 배처와 호환되지만, 추가적인 변경 없이는 Tiling 및 Offset 프로퍼티를 사용할 수 없습니다. 커스텀 언릿 셰이더에 이 기능을 추가하려면 다음 과정을 따르십시오.
프로퍼티 _MainTex의 이름을 이 프로퍼티에 대한 모든 레퍼런스와 함께 _BaseMap으로 변경합니다. 이렇게 하면 셰이더 코드가 표준 URP 셰이더 규칙에 가까워집니다.
_BaseMap 프로퍼티에서 [NoScaleOffset] ShaderLab 속성을 제거합니다. 이제 셰이더의 인스펙터 창에서 Tiling 및 Offset 프로퍼티가 표시됩니다.
_BaseMap 프로퍼티에 [MainTexture] ShaderLab 속성을 추가하고 _Color 프로퍼티에 [MainColor] 속성을 추가합니다. 이는 프로젝트의 다른 부분이나 에디터에서 메인 텍스처나 메인 컬러를 요청할 때 에디터가 어떤 프로퍼티를 반환해야 하는지 알려줍니다. 이제 셰이더의 Properties 섹션이 다음과 같게 됩니다.
Properties
{
[MainTexture] _BaseMap("Main Texture", 2D) = "white" {}
[MainColor] _Color("Color", Color) = (1,1,1,1)
}
CBUFFER 블록 위에 TEXTURE2D(_BaseMap) 및 SAMPLER(sampler_BaseMap) 매크로를 추가합니다. 이러한 매크로는 나중에 사용할 텍스처 및 샘플러 상태 변수를 정의합니다. 샘플러 상태에 대한 상세 내용은 샘플러 상태 사용을 참고하십시오.
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER 블록 내의 sampler2D _BaseMap 변수를 float4 _BaseMap_ST로 변경합니다. 이제 이 변수는 인스펙터에 설정된 타일링 및 오프셋 값을 저장합니다.
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접미사가 붙은 매개변수를 사용하므로,CBUFFER블록 뒤에vert함수를 정의하는 것이 중요합니다.
이 셰이더는 이제 컬러로 수정된 텍스처를 가지며 SRP Batcher와 완벽하게 호환됩니다. 또한 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
}
}
}