Unity 6.3
0 онлайн 118 гостей 3 в системе
Вход
Материалы и шейдеры Шаг 302 из 442

Использование теней в пользовательском шейдере URP

Чтобы использовать тени в пользовательском шейдере Universal Render Pipeline (URP), выполните следующие действия:

  1. Добавьте #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" внутрь HLSLPROGRAM в вашем файле шейдера. Файл Core.hlsl импортирует файлы Shadows.hlsl и RealtimeLights.hlsl.
  2. Используйте любой из методов, описанных в следующих разделах.

Получить позицию в теневом пространстве

Используйте эти методы для преобразования позиций в позиции теневых карт.

Метод Синтаксис Описание
GetShadowCoord float4 GetShadowCoord(VertexPositionInputs vertexInputs) Преобразует положение вершины в пространство тени. См. Transform позиции в пользовательском URP шейдере для информации о ходе работы VertexPositionInputs struct.
TransformWorldToShadowCoord float4 TransformWorldToShadowCoord(float3 positionInWorldSpace) Преобразует позицию в мировом пространстве в пространство тени.

Вычисление теней

Следующие методы рассчитывают тени с помощью сопоставлений теней. Чтобы использовать эти методы, сначала выполните следующие действия:

  1. Убедитесь, что в вашей сцене есть объекты, которые имеют пропуск шейдера ShadowCaster, например объекты, которые используют шейдер Universal Render Pipeline/Lit.
  2. Добавьте #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN к вашему шейдеру, чтобы он мог получить доступ к карте теней для основного света.
  3. Добавьте #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS к вашему шейдеру, чтобы он мог получить доступ к картам теней для дополнительного освещения.
Метод Синтаксис Описание
GetMainLight Light GetMainLight(float4 shadowCoordinates) Возвращает главный свет в сцене, со значением shadowAttenuation, основанным на том, находится ли позиция в координатах тени в тени.
ComputeCascadeIndex half ComputeCascadeIndex(float3 positionInWorldSpace) Возвращает индекс каскада теней на позиции в мировом пространстве. Подробнее см. в Каскады теней.
MainLightRealtimeShadow half MainLightRealtimeShadow(float4 shadowCoordinates) Возвращает значение тени из главного отображения тени на координатах. Подробнее см. в Отображение тени.
AdditionalLightRealtimeShadow half AdditionalLightRealtimeShadow(int lightIndex, float3 positionInWorldSpace) Возвращает значение тени из дополнительной карты светлых теней на позиции в мировом пространстве.
GetMainLightShadowFade half GetMainLightShadowFade(float3 positionInWorldSpace) Возвращает величину, на которую тени от основного света должны исчезнуть, исходя из расстояния между позицией и камерой.
GetAdditionalLightShadowFade half GetAdditionalLightShadowFade(float3 positionInWorldSpace) Возвращает величину, на которую должна затухать тень от дополнительных источников света, исходя из расстояния между позицией и камерой.
ApplyShadowBias float3 ApplyShadowBias(float3 positionInWorldSpace, float3 normalWS, float3 lightDirection) Добавление тени к позиции в пространстве мира. Подробнее см. в Устранение неисправностей тени.

Пример

Этот пример кода является упрощенным примером рисования теней на поверхности. Он может не работать правильно с более чем одним каскад тени.

Чтобы генерировать тени, убедитесь, что в вашей сцене есть объекты, которые имеют пропуск шейдера ShadowCaster, например объекты, которые используют шейдер Universal Render Pipeline/Lit.

Shader "Custom/SimpleShadows"
{
    SubShader
    {

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

        Pass
        {
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN

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

            struct Attributes
            {
                float4 positionOS  : POSITION;
            };

            struct Varyings
            {
                float4 positionCS  : SV_POSITION;
                float4 shadowCoords : TEXCOORD3;
            };

            Varyings vert(Attributes IN)
            {
                Varyings OUT;

                OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);

                // Get the VertexPositionInputs for the vertex position  
                VertexPositionInputs positions = GetVertexPositionInputs(IN.positionOS.xyz);

                // Convert the vertex position to a position on the shadow map
                float4 shadowCoordinates = GetShadowCoord(positions);

                // Pass the shadow coordinates to the fragment shader
                OUT.shadowCoords = shadowCoordinates;

                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                // Get the value from the shadow map at the shadow coordinates
                half shadowAmount = MainLightRealtimeShadow(IN.shadowCoords);

                // Set the fragment color to the shadow value
                return shadowAmount;
            }
            
            ENDHLSL
        }
    }
}

Дополнительные ресурсы