12.固定函数着色器

12.ShaderLab-Shader编写形式-固定函数着色器


12.1 知识点

知识回顾

表面着色器

表面着色器是Unity对顶点/片元着色器的封装。它可以用更少的代码实现复杂的逻辑,但性能和可控性较差。其特点包括:

  • 直接在SubShader语句块中书写着色器逻辑。
  • 不需要关心多个Pass如何渲染,Unity会在内部处理。
  • 可以使用CG或HLSL两种Shader语言编写。
  • 代码量较少,可控性较低,性能消耗较高。
  • 适用于需要处理各种光源的着色器,但在移动平台上需要注意性能表现。

顶点/片元着色器

顶点/片元着色器的特点包括:

  • 需要在Pass渲染通道中编写着色器逻辑。
  • 可以使用CG或HLSL两种Shader语言编写。
  • 代码量较多,灵活性较强,性能消耗更可控,可以实现更多渲染细节。
  • 适用于光照处理较少,自定义渲染效果较多时,尤其在移动平台上。

固定函数着色器

表面着色器和顶点/片元着色器这两种 Unity Shader 形式均使用了可编程管线。然而,对于一些老设备(如 DX7.0、OpenGL1.5 或 OpenGL ES 1.1),它们不支持可编程管线着色器,此时便需要使用固定函数着色器进行渲染。这些着色器仅能实现一些极为简单的效果,其特点如下:

  • 需在 Pass 渲染通道中编写着色器逻辑。
  • 要使用 ShaderLab 语法中的渲染设置命令编写,而非 CGHLSL 着色器语言。

但因这类旧设备在当前市面上几乎绝迹,所以固定函数着色器我们几乎不再使用,仅作了解即可。即便现在我们在 Unity 中使用固定函数着色器编写 Shader,在内部也会被编译为顶点/片元着色器。因此,真正意义上的固定函数着色器已不复存在。

固定函数着色器常用命令

固定函数着色器常用命令写在哪里?

在SubShader语句块中的Pass语句块中。

常用命令

  1. Lighting on/off:开启或关闭灯光影响。
  2. Color(R,G,B,A)或Color[颜色属性]:渲染固定的颜色,使用Color命令必须关闭灯光的影响。
  3. Material{}:灯光影响的命令都放在该结构中,在Material语句块中写Diffuse,代表收到光照的漫反射影响。
  4. SetTexture:设置显示图片纹理的命令。

总结

对于Unity Shader的三种编写形式:

  1. 表面着色器。
  2. 顶点/片元着色器。
  3. 固定函数着色器。

我们应该如何选择呢?

  • 固定函数着色器基本已弃用,不是我们学习的重点。
  • 对于PC、主机性能较高的设备,为了追求更好的效果,使用表面着色器可能更加方便。
  • 对于移动设备,为了权衡效果和性能,优先使用顶点/片元着色器。
  • 在有很多自定义的渲染效果时,优先使用顶点/片元着色器,因为更灵活可控。

由于表面着色器本质上是对顶点/片元着色器的封装,所以我们在学习过程中,着重学习顶点/片元着色器开发的相关知识。


12.2 知识点代码

Lesson12_ShaderLab_Shader编写形式_固定函数着色器

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

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

        //表面着色器是Unity对顶点/片元着色器的封装
        //可以用更少的代码实现复杂的逻辑
        //但是性能和可控性较差
        //它的特点是
        //1.直接在SubShader语句块中书写着色器逻辑
        //2.我们不需要关心也不需要使用多个Pass,每个Pass如何渲染,Unity会在内部帮助我们去处理
        //3.可以使用CG或HLSL两种Shader语言去编写Shader逻辑
        //4.代码量较少,可控性较低,性能消耗较高
        //5.适用于处理需要和各种光源打交道的着色器,但是在移动平台上需要注意性能表现

        #endregion

        #region 知识回顾 顶点/片元着色器

        //它的特点是
        //1.需要在Pass渲染通道中编写着色器逻辑
        //2.可以使用CG或HLSL两种Shader语言去编写Shader逻辑
        //3.代码量较多,灵活性较强,性能消耗更可控,可以实现更多渲染细节
        //4.适用于光照处理较少,自定义渲染效果较多时(移动平台首选)

        #endregion

        #region 知识点 固定函数着色器

        //表面着色器 和 顶点/片元着色器 这两种Unity Shader形式都使用了可编程管线
        //而对于一些老设备(DX7.0、OpenGL1.5或OpenGL ES 1.1),它们不支持可编程管线着色器
        //这时就需要使用固定函数着色器来进行渲染
        //这些着色器只能实现一些非常简单的效果
        //它的特点是:
        //1.需要在Pass渲染通道中编写着色器逻辑
        //2.需要使用ShaderLab语法中的渲染设置命令来编写,而非CG和HLSL着色器语言

        //但是由于这些旧设备目前市面上几乎已经没有了
        //所以固定函数着色器我们几乎不会再使用
        //只做了解即可
        //即使我们现在在Unity中使用固定函数着色器来编写Shader,在内部也会被编译为顶点/片元着色器
        //因此真正意义的固定函数着色器已经不存在了

        #endregion

        #region 总结

        //对于Unity Shader的三种编写形式
        //1.表面着色器
        //2.顶点/片元着色器
        //3.固定函数着色器
        //我们应该如何选择呢?
        //1.固定函数着色器基本已弃用,不是我们学习的重点
        //2.对于PC、主机性能较高的设备,为了追求更好的效果,使用表面着色器可能更加的方便
        //3.对于移动设备,为了权衡效果和性能,优先使用顶点/片元着色器
        //4.在有很多自定义的渲染效果时,优先使用顶点/片元着色器,因为更灵活可控

        //而表面着色器的本质是对顶点/片元着色器的封装
        //所以我们在学习过程中,着重学习顶点/片元着色器开发的相关知识

        #endregion
    }
}

Lesson12_1.shader

Shader "ShaderTeach/Lesson12_1"
{
    Properties 
    {
        _Color("颜色", Color)=(1,1,1,1)
    }
    SubShader 
    {
        Pass
        {
            //关闭光照
            Lighting off
            //渲染颜色
            //Color(1,1,0,1)
            //利用属性参数设置颜色
            Color[_Color]
        }
    }
    FallBack "Diffuse"
}

Lesson12_2.shader

Shader "ShaderTeach/Lesson12_2" {
Properties 
{
    _Color("漫反射颜色", Color)=(1,1,1,1)
}
SubShader 
{
    Pass
    {
        //开启光照
        Lighting on
        //使用Material命令
        Material
        {
            //设置漫反射光照颜色
            Diffuse[_Color]
        }
    }
}
FallBack "Diffuse"
}

Lesson12_3.shader

Shader "ShaderTeach/Lesson12_3" {
Properties
{
    _MainTex("纹理", 2D) = "white"{}
}
SubShader 
{
    Pass
    {
        //将纹理应用到物体上
        SetTexture[_MainTex]
        {
            //显示纹理的原始颜色
            Combine texture
        }
    }
}
FallBack "Diffuse"
}

Lesson12_4.shader

Shader "ShaderTeach/Lesson12_4" {
Properties 
{
    _DiffuseColor("漫反射颜色", Color)=(1,1,1,1)
    _MainTex("纹理", 2D) = "white"{}
}
SubShader 
{
    Pass
    {
        //开启灯光
        Lighting on 
        //使用Material命令
        Material
        {
            //设置漫反射光照颜色
            Diffuse[_DiffuseColor]
        }
        //受到纹理的影响
        SetTexture[_MainTex]
        {
            // 将之前灯光计算出来的颜色 与 texture相乘才能受到灯光影响
            Combine texture * primary DOUBLE
        }
    }
}
    FallBack "Diffuse"
}

12.3 练习题

Unity Shader中表面着色器、顶点\片元着色器、固定函数着色器的区别是什么?

  1. 表面着色器是对顶点\片元着色器的封装,可以用更少的代码实现出一些效果

  2. 表面着色器和顶点\片元着色器都可以使用CG/HLSL语言进行开发,而固定函数着色器只能使用ShaderLab语法中的相关命令

  3. 表面着色器和顶点\片元着色器使用了可编程管线,而固定函数着色器不支持可编程管线

  4. 固定函数着色器已经被弃用了

  5. 若想要更细节的控制着色器(比如性能、渲染表现等),建议使用顶点\片元着色器

  6. 表面着色器的使用对设备有一定的要求,而顶点\片元着色器更具有针对性,适配性更强(取决于我们的代码)



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

×

喜欢就点赞,疼爱就打赏