开始之前
我在学习本书时使用的 Unity 版本为 2021.3.6f1。
我对于书中内容的注释会标明为 arimx 注,并使用斜体。
更多内容
全部章节
Unity Shader 概述
材质和 Unity Shader
在 Unity 中需要配合使用材质(Material)和 Unity Shader 来达到需要的效果。一个常见的流程是:
- 创建一个材质
- 创建一个 Unity Shader,赋给上一步创建的材质
- 把材质赋给要渲染的对象
- 在材质面板中调整 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" 是出现在材质面板上的名字。除此之外,还要对每个属性指定类型和默认值。
属性类型 | 默认值的定义语法 |
Int | number |
Float | number |
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
咕咕咕
Comments NOTHING