Version: Unity 6.0 (6000.0)
语言 : 中文
在自定义 URP 着色器中使用摄像机
Use indirect lighting in a custom URP shader

在自定义 URP 着色器中使用光照

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

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

获取光源数据

Lighting.hlsl 文件将导入 RealtimeLights.hlsl 文件,其中包含以下方法。

方法 语法 描述
GetMainLight Light GetMainLight() 返回场景中的主光源。
GetAdditionalLight Light GetAdditionalLight(uint lightIndex, float3 positionInWorldSpace) 返回影响 positionWSlightIndex 附加光源。例如,如果 lightIndex0,则此方法返回首个附加光源。
GetAdditionalLightsCount int GetAdditionalLightsCount() 返回附加光源的数量。

请参阅在自定义 URP 着色器中使用阴影,了解可用于计算阴影的这些方法的版本。

计算表面法线的光照

方法 语法 描述
LightingLambert half3 LightingLambert(half3 lightColor, half3 lightDirection, half3 surfaceNormal) 返回使用 Lambert 模型计算的表面法线的漫射光照。
LightingSpecular half3 LightingSpecular(half3 lightColor, half3 lightDirection, half3 surfaceNormal, half3 viewDirection, half4 specularAmount, half smoothnessAmount) 使用简单着色返回表面法线的镜面光照。

计算环境光遮挡

Lighting.hlsl 文件将导入 AmbientOcclusion.hlsl 文件,其中包含以下方法。

方法 语法 描述
SampleAmbientOcclusion half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV) 返回屏幕空间位置的环境光遮挡值,其中 0 表示被遮挡,1 表示未被遮挡。
GetScreenSpaceAmbientOcclusion AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV) 返回屏幕空间位置的间接和直接环境光遮挡值,其中 0 表示被遮挡,1 表示未被遮挡。

有关更多信息,请参阅环境光遮挡

结构

AmbientOcclusionFactor

使用 GetScreenSpaceAmbientOcclusion 方法返回此结构。

字段 描述
half indirectAmbientOcclusion 因对象阻挡间接光导致的环境光遮挡所产生阴影中对象的数量。
half directAmbientOcclusion 因对象阻挡直接光导致的环境光遮挡所产生阴影中对象的数量。

光源

使用 GetMainLightGetAdditionalLight 方法返回此结构。

字段 描述
half3 direction 光的方向。
half3 color 光的颜色。
float distanceAttenuation 光的强度(基于其与对象的距离)。
half shadowAttenuation 光的强度(基于对象是否在阴影中)。
uint layerMask 光的层遮罩。

示例

以下 URP 着色器使用对象从主方向光接收的光量绘制对象表面。

Shader "Custom/LambertLighting"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag

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

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv: TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionCS  : SV_POSITION;
                float2 uv: TEXCOORD0;
                half3 lightAmount : TEXCOORD2;
            };

            Varyings vert(Attributes IN)
            {
                Varyings OUT;

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

                // Get the VertexNormalInputs of the vertex, which contains the normal in world space
                VertexNormalInputs positions = GetVertexNormalInputs(IN.positionOS);

                // Get the properties of the main light
                Light light = GetMainLight();

                // Calculate the amount of light the vertex receives
                OUT.lightAmount = LightingLambert(light.color, light.direction, positions.normalWS.xyz);

                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                // Set the fragment color to the interpolated amount of light
                return float4(IN.lightAmount, 1);
            }
            ENDHLSL
        }
    }
}

其他资源

在自定义 URP 着色器中使用摄像机
Use indirect lighting in a custom URP shader