Version: Unity 6.0 (6000.0)
语言 : 中文
Use indirect lighting in a custom URP shader
URP 参考中的 ShaderLab 通道标签

在自定义 URP 着色器中使用阴影

要在自定义通用渲染管线 (URP) 着色器中使用阴影,请执行以下步骤:

  1. 在着色器文件中的 HLSLPROGRAM 中添加 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"Core.hlsl 文件将导入 Shadows.hlslRealtimeLights.hlsl 文件。
  2. 使用以下部分中的任一方法。

获取阴影空间中的位置

使用这些方法可将位置转换为阴影贴图位置。

方法 语法 描述
GetShadowCoord float4 GetShadowCoord(VertexPositionInputs vertexInputs) 将顶点位置转换为阴影空间。请参阅变换自定义 URP 着色器中的位置以了解有关 VertexPositionInputs 结构的信息。
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) 向世界空间中的位置添加阴影偏差。请参阅阴影故障排除以了解更多信息。

示例

以下 URP 着色器在表面上绘制简单的阴影。

要生成阴影,请确保场景中存在具有 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
        }
    }
}

其他资源

Use indirect lighting in a custom URP shader
URP 参考中的 ShaderLab 通道标签