Version: 6000.3
语言: 中文
在自定义URP着色器中使用间接光照
URP 参考中的 ShaderLab Pass 标签

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

在自定义通用中使用阴影渲染管线(Render Pipeline) 获取场景内容并将其显示在屏幕上的一系列作。Unity 允许您从预构建的渲染管道中进行选择,或编写自己的渲染管道。更多信息
请参阅术语表
(URP)着色器在 GPU 上运行的程序。更多信息
请参阅术语表
,请按照下列步骤作:

  1. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"HLSLPROGRAM在着色器文件中。这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) 为世界空间中的位置添加阴影偏差。有关详细信息,请参阅影子故障排除

此代码示例是在表面上绘制阴影的简化示例。它可能无法在多个阴影级联时正常工作。

要生成阴影,请确保场景中有一些对象具有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
        }
    }
}

其他资源

在自定义URP着色器中使用间接光照
URP 参考中的 ShaderLab Pass 标签