《Unity着色器圣经》7.0.7 | 标准表面着色器的结构

目录索引

译文

在继续定义一些函数之前,让我们简单了解一下标准表面着色器(Standard Surface shader)的结构。与无光照着色器不同的是,其特点是结构简化,仅在内置渲染管线(Built-in RP)中与光照互动。

在前面几个小节中所编写的反射函数均已包含在标准表面着色器的程序内部,这意味着该着色器在默认情况下具有全局照明、漫反射、反射和菲涅尔反射的功能。

如果我们创建了一个标准表面着色器,我们会注意到着色器自动生成了以下代码,但 CGPROGRAM 语义块被写在 SubShader 语义块内。

要想理解这个操作,我们需要先将注意力放到名为 surf 的函数上,该函数相当于物体表面的颜色输出。在这个函数中,我们可以找到两个参数:

  1. Input IN.
  2. input SurfaceOutputStandard o.

这代表了着色器的输入与输出,它们的语义已经在代码内部预定义了。

Shader "Custom/SurfaceShader"
{
    Properties { ... }
    SubShader
    {
        CGPROGRAM
        ...
        #pragma surface surf Standard fullforwardshadows
        ...
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
           ...
        }
        ENDCG
    }
}

我们之所以认定 surf 为颜色输出函数是因为着色器声明了编译指令 #pragma surface surf。这一过程与顶点/片元着色器类似,不同之处在于我们可以声明其他属性,例如光照模型(标准)和其他可选参数(fullforwardshadows)。

通常情况下,表面着色器配置了标准(Standard)光照模型,其包含了一些可以用作颜色输出的预定义属性。

请注意,我们的 surf 函数中定义的属性是 SurfaceOutputStandard 类型的,这意味着颜色输出将由标准光照模型决定。

#pragma surface surf Standard
...
struct SurfaceOutputStandard
{
    fixed3 Albedo;
    fixed3 Normal;
    half3 Emission;
    half Metallic;
    half Smoothness;
    half Occlusion;
    fixed Alpha;
};

void surf (Input IN, inout SurfaceOutputStandard o)
{
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
    o.Alpha = c.a;
}

原文对照

Before continuing defining some functions, we will take a look into the structure of a Standard Surface shader. This shader, different from the Unlit Shader type, is characterized by having a simplified structure, which is configured to interact with lighting only in Built-in RP.

The reflection functions that we saw in previous sections are included internally in this program, this means that this shader by default has global lighting, diffusion, reflection and fresnel.

If we create a Standard Surface, we notice immediately that its structure does not have a pass defined as such, but that the CGPROGRAM is written inside the SubShader field.

To understand its operation, we must pay attention to the surf function that would be equivalent to the color output of the object surface. Within this function, we can find two arguments,

  1. Input IN.
  2. Input SurfaceOutputStandard o.

These refer to our shader inputs and outputs, and their semantics have been predefined internally in the code.

Shader "Custom/SurfaceShader"
{
    Properties { ... }
    SubShader
    {
        CGPROGRAM
        ...
        #pragma surface surf Standard fullforwardshadows
        ...
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
           ...
        }
        ENDCG
    }
}

The reason why we can determine that surf is the color output function is because it has been declared as such in the #pragma surface surf. This process is similar to a vertex/ fragment shader, with the difference in this case that we can declare other properties, e.g., the lighting model (Standard) and other optional parameters (fullforwardshadows).

By default, a surface shader comes configured with a Standard type lighting model, which contains some predefined properties that we can use as a color output.

Note that the defined properties in our code surf function are of SurfaceOutputStandard type, this means that the color output will be determined by the Standard lighting model.

#pragma surface surf Standard
...
struct SurfaceOutputStandard
{
    fixed3 Albedo;
    fixed3 Normal;
    half3 Emission;
    half Metallic;
    half Smoothness;
    half Occlusion;
    fixed Alpha;
};

void surf (Input IN, inout SurfaceOutputStandard o)
{
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
    o.Alpha = c.a;
}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容