Unity 6.3
0 онлайн 57 гостей 3 в системе
Вход

Обновление пользовательских шейдеров для совместимости с URP

Пользовательские шейдеры, написанные для встроенного Render Pipeline, несовместимы с Universal Render Pipeline (URP), и вы не можете обновить их автоматически с помощью конвертера Render Pipeline. Вместо этого, вы должны переписать несовместимые секции кода шейдера, чтобы работать с URP.

Вы также можете воссоздать настраиваемые шейдеры в Shader Graph. Дополнительные сведения см. в документации по ShaderGraph.

Примечание: Вы можете идентифицировать любые материалы в сцене, которые используют пользовательские шейдеры, когда вы обновляете до 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.

  1. Изменить CGPROGRAM и ENDCG на HLSLPROGRAM и ENDHLSL.

  2. Обновить инструкцию include, чтобы сделать ссылку на файл Core.hlsl.

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

    Примечание: Core.hlsl включает ядро SRP библиотека, URP shader переменные, и матричные определения и преобразования, но не включает в себя функции освещения или структуры по умолчанию.

  3. Добавить "RenderPipeline" = "UniversalPipeline" к тегам шейдера.

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

    Примечание: URP не поддерживает все ShaderLab Для получения дополнительной информации о том, какие теги URP поддержки, см. URP ShaderLab Метки пропуска.

  4. Заменить struct v2f блок кодов со следующими struct Varyings блок кода. Это меняет структуру так, чтобы она использовала имя URP Varyings вместо v2f, и обновляет шейдер, чтобы использовать правильные переменные для URP.

    struct Varyings
    {
        // The positions in this struct must have the SV_POSITION semantic.
        float4 positionHCS  : SV_POSITION;
        float2 uv : TEXCOORD0;
    };
    
  5. Под указанием " включить " и над указанием Varyings структуру, объявите новую структуру с именем Attributes. Это эквивалентно встроенному Render Pipeline appdata struct.

  6. Добавить указанные ниже переменные к Attributes struct.

    struct Attributes
    {
        float4 positionOS   : POSITION;
        float2 uv : TEXCOORD0;
    };
    
  7. Обновить v2f vert определение функции для использования новых Varyings структуру и принимают экземпляр Attributes структуру в качестве входных данных, как показано ниже.

    Varyings vert(Attributes IN)
    
  8. Обновление функции 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 означает однородное пространство клипа.

  9. Поместите блок кода CBUFFER вокруг свойств, используемых шейдером, вместе с параметром UnityPerMaterial.

    CBUFFER_START(UnityPerMaterial)
    float4 _Color;
    sampler2D _MainTex;
    CBUFFER_END
    

    Примечание: Для шейдера быть SRP Совместим с Batcher, вы должны объявить все свойства материала в пределах CBUFFER блок кода. Даже если шейдер имеет несколько проходов, все проходы должны использовать один и тот же CBUFFER блок.

  10. Обновите функцию 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, вы не можете использовать свойства Плитка и Смещение без дальнейших изменений. Чтобы добавить эту функциональность в пользовательский не освещенный шейдер, выполните следующие действия.

  1. Переименуйте свойство _MainTex в _BaseMap вместе с любыми ссылками на это свойство.

  2. Удалить атрибут [NoScaleOffset] ShaderLab из свойства _BaseMap. Теперь вы можете видеть свойства Плитка и Смещение в окне Inspector шейдера.

  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. Измените переменный sampler2D _BaseMap внутри блока CBUFFER на float4 _BaseMap_ST. Эта переменная теперь хранит значения плитки и смещения, установленные в Inspector.

    CBUFFER_START(UnityPerMaterial)
    float4 _Color;
    float4 _BaseMap_ST;
    CBUFFER_END
    
  6. Измените функцию 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;
    }
    
  7. В функции 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
        }
    }
}