10.表面着色器

10.ShaderLab-Shader编写形式-表面着色器


10.1 知识点

知识回顾

ShaderLab主要由4个部分组成:

  1. Shader的名字
  2. Shader的属性
  3. 1~n个子着色器
  4. 备用的Shader
第一部分:
Shader "着色器名字" 
{ 
    //第二部分
    Properties
    {
        //材质面板上可以看到的属性
    }

    //第三部分
    SubShader
    {
        Tags(渲染标签)
        States(渲染状态)
        Pass(渲染通道1)
        Pass(渲染通道2)
        ....(渲染通道n)
    }
    SubShader
    {
        Tags(渲染标签)
        States(渲染状态)
        Pass(渲染通道1)
        Pass(渲染通道2)
        ....(渲染通道n)
    }
    .....可以有n个SubShader代码块

    //第四部分
    Fallback "备用的Shader"
}

Shader的形式是什么

  • 通过之前的课程,我们已经对Shader文件的文件结构有一定的认识,并且学习了ShaderLab语法相关的知识。

  • 通过学习我们知道,在Unity Shader中我们可以通过ShaderLab语法去设置很多内容,比如属性、渲染状态、渲染标签等等。但是其最主要的作用是需要指定各种着色器所需的代码。

  • 而这些着色器代码即可以放在SubShader子着色器语句块中,也可以放在其中的Pass渲染通道语句块中。不同的Shader形式放置着色器代码的位置也有所不同。

  • 我们一般会使用以下3种形式来编写Unity Shader:

    1. 表面着色器(可控性较低)
    2. 顶点/片元着色器(重点学习)
    3. 固定函数着色器(基本已弃用,了解即可)

表面着色器

  • 表面着色器(Surface Shader)是Unity自己创造的一种着色器代码类型。它的本质是对顶点/片元着色器的一层封装。它需要的代码量很少,很多工作都帮助我们去完成了,但是缺点是渲染的消耗较大,可控性较低。它的优点在于,它帮助我们处理了很多光照细节,我们可以直接使用而无需自己计算实现光照细节。

  • 我们可以在创建Shader时,选择创建Standard Surface Shader。通过观察该Shader文件的内部结构,你会发现,着色器相关代码被放在SubShader语句块中(并非Pass)的 CGPROGRAM 和 ENDCG 之间。

  • 如下是默认的表面着色器,注意CGPROGRAM 和 ENDCG 之间之间的代码。

Shader "ShaderTeach/Lesson10_NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • 表面着色器的特点就是:
    1. 直接在SubShader语句块中书写着色器逻辑。
    2. 我们不需要关心也不需要使用多个Pass,每个Pass如何渲染,Unity会在内部帮助我们去处理。
    3. 可以使用CG或HLSL两种Shader语言去编写Shader逻辑。
    4. 代码量较少,可控性较低,性能消耗较高。
    5. 适用于处理需要和各种光源打交道的着色器(主机、PC平台时更适用,移动平台需要考虑性能消耗)。

10.2 知识点代码

Lesson10_ShaderLab_Shader编写形式_表面着色器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson10_ShaderLab_Shader编写形式_表面着色器 : MonoBehaviour
{
    void Start()
    {
        #region 知识回顾

        //ShaderLab主要由4个部分组成
        //1.Shader的名字
        //2.Shader的属性
        //3.1~n个子着色器
        //4.备用的Shader

        //第一部分
        //Shader "着色器名字" 
        //{ 
        //      //第二部分
        //      Properties
        //      {
        //          //材质面板上可以看到的属性
        //      }

        //      //第三部分
        //      SubShader
        //      {
        //           Tags(渲染标签)
        //           States(渲染状态)
        //           Pass(渲染通道1)
        //           Pass(渲染通道2)
        //           ....(渲染通道n)
        //      }
        //      SubShader
        //      {
        //           Tags(渲染标签)
        //           States(渲染状态)
        //           Pass(渲染通道1)
        //           Pass(渲染通道2)
        //           ....(渲染通道n)
        //      }
        //      .....可以有n个SubShader代码块

        //      //第四部分
        //      Fallback "备用的Shader"
        //}

        #endregion

        #region 知识点一 Shader的形式是什么?

        //通过之前的课程,我们已经对Shader文件的文件结构有一定的认识
        //并且学习了ShaderLab语法相关的知识

        //通过学习我们知道 在Unity Shader当中我们可以通过ShaderLab语法去设置很多内容
        //比如属性、渲染状态、渲染标签等等
        //但是其最主要的作用是需要指定各种着色器所需的代码

        //而这些着色器代码即可以放在SubShader子着色器语句块中,也可以放在其中的Pass渲染通道语句块中
        //不同的Shader形式放置着色器代码的位置也有所不同

        //我们一般会使用以下3种形式来编写Unity Shader
        //1.表面着色器(可控性较低)
        //2.顶点/片元着色器(重点学习)
        //3.固定函数着色器(基本已弃用,了解即可)

        #endregion

        #region 知识点二 表面着色器

        //表面着色器(Surface Shader)是Unity自己创造的一种着色器代码类型
        //它的本质是对顶点/片元着色器的一层封装
        //它需要的代码量很少,很多工作都帮助我们去完成了
        //但是缺点是渲染的消耗较大,可控性较低
        //它的优点在于,它帮助我们处理了很多光照细节,我们可以直接使用而无需自己计算实现光照细节

        //我们可以在创建Shader时,选择创建Standard Surface Shader
        //通过观察该Shader文件的内部结构,你会发现
        //着色器相关代码被放在SubShader语句块中(并非Pass)的 CGPROGRAM 和 ENDCG 之间

        //表面着色器的特点就是
        //1.直接在SubShader语句块中书写着色器逻辑
        //2.我们不需要关心也不需要使用多个Pass,每个Pass如何渲染,Unity会在内部帮助我们去处理
        //3.可以使用CG或HLSL两种Shader语言去编写Shader逻辑
        //4.代码量较少,可控性较低,性能消耗较高
        //5.适用于处理需要和各种光源打交道的着色器(主机、PC平台时更适用,移动平台需要考虑性能消耗)

        #endregion
    }
}

Lesson10_NewSurfaceShader.shader

Shader "ShaderTeach/Lesson10_NewSurfaceShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏