Обновление пользовательских шейдеров для совместимости с URP
Пользовательские шейдеры, написанные для встроенного Render Pipeline, несовместимы с Universal Render Pipeline (URP), и вы не можете обновить их автоматически с помощью конвертера Render Pipeline. Вместо этого, вы должны переписать несовместимые секции кода шейдера, чтобы работать с URP.
Вы также можете воссоздать настраиваемые шейдеры в Shader Graph. Дополнительные сведения см. в документации по ShaderGraph.
Примечание: Вы можете идентифицировать любые материалы в сцене, которые используют пользовательские шейдеры, когда вы обновляете до URP когда они становятся пурпурными (ярко-розовыми), чтобы указать на ошибку.
В этом руководстве показано, как обновить пользовательский неосвещенный шейдер из Встроенного Render Pipeline, чтобы он был полностью совместим с URP в следующих разделах:
- Пример Встроенный Render Pipeline пользовательский шейдер
- Сделать пользовательский шейдер URP совместимым с
- Включить плитку и смещение для шейдера
- Полный код шейдера
Пример Встроенный Render Pipeline пользовательский шейдер
Следующий шейдер является простым не освещенным шейдером, который работает со встроенным Render Pipeline. Это руководство показывает, как обновить этот шейдер, чтобы он был совместим с 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
Встроенные Render Pipeline шейдеры имеют две проблемы, которые вы можете увидеть в окне Inspector:
- Предупреждение, что свойство Material находится в другом cbuffer.
- Свойство SRP Batcher отображает несовместимое.
Следующие шаги показывают, как решить эти проблемы и сделать шейдер совместимым с URP и SRP Batcher.
Изменить
CGPROGRAMиENDCGнаHLSLPROGRAMиENDHLSL.-
Обновить инструкцию include, чтобы сделать ссылку на файл
Core.hlsl.#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"Примечание:
Core.hlslвключает ядро SRP библиотека, URP shader переменные, и матричные определения и преобразования, но не включает в себя функции освещения или структуры по умолчанию. -
Добавить
"RenderPipeline" = "UniversalPipeline"к тегам шейдера.Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }Примечание: URP не поддерживает все ShaderLab Для получения дополнительной информации о том, какие теги URP поддержки, см. URP ShaderLab Метки пропуска.
-
Заменить
struct v2fблок кодов со следующимиstruct Varyingsблок кода. Это меняет структуру так, чтобы она использовала имя URPVaryingsвместоv2f, и обновляет шейдер, чтобы использовать правильные переменные для URP.struct Varyings { // The positions in this struct must have the SV_POSITION semantic. float4 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; }; Под указанием " включить " и над указанием
Varyingsструктуру, объявите новую структуру с именемAttributes. Это эквивалентно встроенному Render Pipelineappdatastruct.-
Добавить указанные ниже переменные к
Attributesstruct.struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; -
Обновить
v2f vertопределение функции для использования новыхVaryingsструктуру и принимают экземплярAttributesструктуру в качестве входных данных, как показано ниже.Varyings vert(Attributes IN) -
Обновление функции vert для вывода экземпляра
Varyingsструктуру и используйтеTransformObjectToHClipфункция для преобразования из пространства объекта в пространство клипа. Функция также должна принимать входAttributesUV и передать его на выходVaryingsUV.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 Совместим с Batcher, вы должны объявить все свойства материала в пределах
CBUFFERблок кода. Даже если шейдер имеет несколько проходов, все проходы должны использовать один и тот жеCBUFFERблок. -
Обновите функцию
fragдля использования входаVaryingsи типаhalf4, как показано ниже. Функцияfragтеперь должна использовать этот тип, так как шейдеры URP не поддерживают фиксированные типы.half4 frag(Varyings IN) : SV_Target { half4 texel = tex2D(_MainTex, IN.uv); return texel * _Color; }
Этот пользовательский неосвещенный шейдер теперь совместим с SRP Batcher и готов для использования в URP.. Вы можете проверить это в окне Inspector:
- Предупреждение о том, что свойство Material находится в другом cbuffer больше не появляется.
- Свойство SRP Batcher отображает совместимый.
Включить плитку и смещение для шейдера
Несмотря на то, что шейдер теперь совместим с URP и SRP Batcher, вы не можете использовать свойства Плитка и Смещение без дальнейших изменений. Чтобы добавить эту функциональность в пользовательский не освещенный шейдер, выполните следующие действия.
Переименуйте свойство
_MainTexв_BaseMapвместе с любыми ссылками на это свойство.Удалить атрибут
[NoScaleOffset]ShaderLab из свойства_BaseMap. Теперь вы можете видеть свойства Плитка и Смещение в окне Inspector шейдера.-
Добавьте атрибут
[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); -
Измените переменный
sampler2D _BaseMapвнутри блокаCBUFFERнаfloat4 _BaseMap_ST. Эта переменная теперь хранит значения плитки и смещения, установленные в Inspector.CBUFFER_START(UnityPerMaterial) float4 _Color; float4 _BaseMap_ST; CBUFFER_END -
Измените функцию
fragдля доступа к текстуре с макроса вместоtex2Dнапрямую. Для этого заменитеtex2DмакросомSAMPLE_TEXTURE2Dи добавьтеsampler_BaseMapв качестве дополнительного параметра, как показано ниже:half4 frag(Varyings IN) : SV_Target { half4 texel = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); return texel * _Color; } -
В функции
vertизменитеOUT.uv, чтобы использовать макрос вместо передачи координат текстуры какIN.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; }Примечание: Важно, чтобы вы определили
vertфункции послеCBUFFERблок, какTRANSFORM_TEXмакрос использует параметр с_STсуффикс.
Этот шейдер теперь имеет текстуру, модифицированную цветом, и полностью совместим с SRP Batcher. Он также полностью поддерживает свойства Плитка и Смещение.
Чтобы увидеть пример полного кода шейдера, обратитесь к разделу Полный код шейдера на этой странице.
Полный код шейдера
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
}
}
}