Version: Unity 6.0 (6000.0)
语言 : 中文
在内置渲染管线中创建表面着色器
优化表面着色器

为内置渲染管线中的表面着色器设置光照模型

在内置渲染管线中编写表面着色器时,您需要描述表面的属性(如反照率颜色和法线),并利用__光照模型__计算光照的交互。

内置的光照模型有两种,分别是 LambertBlinnPhong,前者用于漫反射光照,后者用于镜面反射光照。Unity 使用 Lighting.cginc 文件定义这些模型(Windows: <unity 安装路径>/Data/CGIncludes/Lighting.cginc; macOS: _/Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc_)。

有些您可能更希望使用自定义光照模型。这时就可以用表面着色器。光照模型实际上就是符合一定规范的 Cg/HLSL 函数。

渲染管线兼容性

功能名称 通用渲染管线 (URP) 高清渲染管线 (HDRP) 自定义 SRP 内置渲染管线
表面着色器

如需了解在 URP 中创建着色器对象的简化方法,请参阅着色器图表


如需了解在 HDRP 中创建着色器对象的简化方法,请参阅着色器图表

声明光照模型

光照模型中包含多个以 Lighting 开头的常规函数。您可以在着色器文件中的任何位置,或其中一个被包含的文件中,声明这些函数。这些函数是:

  1. half4 Lighting<Name> (SurfaceOutput s, UnityGI gi); 请针对_不依赖_视图方向的光照模型,在前向渲染路径中使用此函数。

  2. half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi); 请针对_依赖_视图方向的光照模型,在前向渲染路径中使用此函数。

  3. half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal); 对延迟着色路径使用此函数。

请注意,您无需声明所有函数。光照模型不一定会使用视图方向。同样的,如果光照模型仅在前向渲染中生效,请勿声明 _Deferred 函数。这能确保使用视图方向的着色器仅会编译到前向渲染。

自定义 GI

声明以下函数以自定义光照贴图数据和探针的解码:

  1. half4 Lighting<Name>_GI (SurfaceOutput s, UnityGIInput data, inout UnityGI gi);

请注意,要解码 Unity 标准光照贴图和 SH 探针,您可以使用内置函数 DecodeLightmapShadeSHPerPixel;这些函数位于 Unity 内部 UnityGlobalIllumination.cginc 文件中的 UnityGI_Base 内(Windows: <unity 安装路径>/Data/CGIncludes/UnityGlobalIllumination.cginc; macOS: _/Applications/Unity/Unity.app/Contents/CGIncludes/UnityGlobalIllumination.cginc__)。

示例

以下是使用内置 Lambert 光照模型的着色器示例:

  Shader "Example/Diffuse Texture" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      
      struct Input {
          float2 uv_MainTex;
      };
      
      sampler2D _MainTex;
      
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

以下是有纹理和没有纹理时的外观对比(在场景中使用一个方向光):

在内置渲染管线中创建表面着色器
优化表面着色器