版本:Unity 6 (6000.0)
语言:英语
在自定义 URP 着色器中使用摄像机
在自定义 URP 着色器中使用阴影

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

要在自定义通用 渲染管线一系列操作,用于获取场景中的内容并将其显示在屏幕上。Unity 让您可以选择预先构建的渲染管线,或编写自己的渲染管线。更多信息
参见 术语表
(URP) 着色器在 GPU 上运行的程序。更多信息
参见 术语表
中使用光照,请执行以下步骤

  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 由于遮挡直接光源的物体导致的对象阴影程度。

Light

使用 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 着色器中使用摄像机
在自定义 URP 着色器中使用阴影