《Unity Shader 入门精要》读书笔记 | 第 3 章 Unity Shader 基础

arimx 发布于 2023-09-06 0 次阅读


开始之前

我在学习本书时使用的 Unity 版本为 2021.3.6f1。

我对于书中内容的注释会标明为 arimx 注,并使用斜体

更多内容

全部章节

Unity Shader 概述

材质和 Unity Shader

在 Unity 中需要配合使用材质(Material)和 Unity Shader 来达到需要的效果。一个常见的流程是:

  1. 创建一个材质
  2. 创建一个 Unity Shader,赋给上一步创建的材质
  3. 把材质赋给要渲染的对象
  4. 在材质面板中调整 Unity Shader 的属性,以得到满意的效果

Unity Shader 定义了渲染所需的各种代码(如顶点着色器和片元着色器)、属性(如使用哪些纹理)和指令(如渲染和标签设置),而材质允许调节这些属性,并将其赋给相应的模型。

Unity 中的材质

Unity 中的材质需要结合一个 GameObject 的 Mesh 或 Particle Systems 组件来工作。它(与 Unity Shader 配合)决定了游戏对象看起来是什么样子的。

Unity 中的 Shader

Unity 中的 Shader 与渲染管线的 Shader 不同。

Unity 5.2 版本提供了 4 种 Unity Shader 模板(arimx:2021.3 版本中是 5 种)

  • Standard Surface Shader
  • Unlit Shader
  • Image Effect Shader
  • Compute Shader
  • Ray Tracing Shader(arimx 注)

其中,Standard Surface Shader 会产生一个包含了标准光照模型(使用了基于物理的渲染方法)的表面着色器模板;Unlit Shader 则会产生一个不包含光照(但包含雾效)的基本顶点/片元着色器;Image Effect Shader 则为实现各种屏幕后处理效果提供了一个基本模板;Compute Shader 会产生一种特殊的 Shader 文件,利用 GPU 的并行性进行一些与常规渲染流水线无关的计算。

单独的 Unity Shader 无法发挥作用,必须与材质配合。

在 Inspector 面板中可以看到一个 Unity Shader 的导入设置。Default Maps 指定了该 Unity Shader 使用的默认纹理。下方显示了一些与该 Unity Shader 相关的信息。如果该 Unity Shader 是表面着色器,可以单击 Surface shader 一栏后的“Show generated code”来查看生成的顶点/片元着色器;如果该 Unity Shader 是固定函数着色器,可以单击 Fixed function 一栏后的“Show generated code”来查看生成的代码。“Compile and show code”允许开发者检查该 Unity Shader 针对不同图像编程接口编译的 Shader 代码。除此之外,Unity Shader 的导入面板还可以查看其使用的渲染队列(Render queue)、是否关闭批处理(Disable batching)、属性列表(Properties)等信息。

Unity Shader 的基础:ShaderLab

Unity Shader 是 Unity 为开发者提供的高层级的渲染抽象层。ShaderLab 是 Unity 提供的专门为 Unity Shader 服务的语言。它使用了一些嵌套在花括号内部的语义(syntax)来描述一个 Unity Shader 文件的结构。ShaderLab 定义了显示一个材质所需的所有东西,而不仅仅是着色器代码。

一个 Unity Shader 的基础结构如下所示:

Shader "ShaderName" {
    Properties {
        // 属性
    }
    SubShader {
        // 显卡 A 使用的子着色器
    }
    SubShader {
        // 显卡 B 使用的子着色器
    }
    Fallback "VertexLit"
}

Unity Shader 的结构

名字

每个 Unity Shader 文件的第一行都要通过 Shader 语义来指定该 Unity Shader 的名字。通过在字符串中添加斜杠,可以控制 Unity Shader 在材质面板出现的位置,如:

Shader "Custom/MyShader" { }

Properties

Properties 语义块包含一系列属性(Property),这些属性将会出现在材质面板中。

Properties 语义块的定义通常如下:

Properties {
    Name ("display name", PropertyType) = DefaultValue
    Name ("display name", PropertyType) = DefaultValue
    // 更多属性
}

在 Shader 中使用属性的名字 Name 来访问它们,Unity 中属性的名字通常以一个下划线开始。"display name" 是出现在材质面板上的名字。除此之外,还要对每个属性指定类型和默认值。

属性类型默认值的定义语法
Intnumber
Floatnumber
Range(min, max)number
Color(number, number, number, number)
Vector(number, number, number, number)
2D"defaulttexture" {}
Cube"defaulttexture" {}
3D"defaulttexture" {}

下面是一个示例:

Properties {
    _Int ("Int", Int) = 2
    _Float ("Float", Float) = 1.5
    _Range ("Range", Range(0.0, 5.0)) = 3.0
    _Color ("Color", Color) = (1, 1, 1, 1)
    _Vector ("Vector", Vector) = (2, 3, 6, 1)
    _2D ("2D", 2D) = "" {}
    _Cube ("Cube", Cube) = "white" {}
    _3D ("3D", 3D) = "black" {}
}

Unity 允许重载默认的材质编辑面板,以提供更多自定义的数据类型。

为了在 Shader 中可以访问到这些变量,需要在 Cg 代码片段中定义和这些属性类型相匹配的变量。

SubShader

咕咕咕