US2S2L5-3——Pass-渲染通道

回顾:SubShader的基本构成

SubShader语句块中主要由3部分构成:渲染标签,渲染状态,n个渲染通道

1
2
3
4
5
            |--------Tags(渲染标签)
|--------States(渲染状态)
SubShader---|--------Pass(渲染通道1)
|--------Pass(渲染通道2)
|--------....(渲染通道n)

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
UsePass "Pass名(大写)"        //可以调用特定的Shader文件内的有名字的Pass语句,需要使用大写
Pass {} //Pass渲染通道语句块
Name "Pass名" //为Pass渲染通道语句块命名的关键字
Tags {} //Pass语句块内也可以使用渲染标签,但是Pass语句块的渲染标签是独有的
"LightMode" //指定了该 Pass 应该在哪个阶段执行,可以将着色器代码分配给适当的渲染阶段,以实现所需的效果
"Always" //始终渲染;不应用光照
"ForwardBase" //在前向渲染中使用;应用环境光、主方向光、顶点/SH 光源和光照贴图
"ForwardAdd" //在前向渲染中使用;应用附加的每像素光源(每个光源有一个通道)
"Deferred" //在延迟渲染中使用;渲染 G 缓冲区
"ShadowCaster" //将对象深度渲染到阴影贴图或深度纹理中
"MotionVectors" //用于计算每对象运动矢量
"PrepassBase" //在旧版延迟光照中使用;渲染法线和镜面反射指数
"PrepassFinal" //在旧版延迟光照中使用;通过组合纹理、光照和反光来渲染最终颜色
"Vertex" //当对象不进行光照贴图时在旧版顶点光照渲染中使用;应用所有顶点光源
"VertexLMRGBM" //当对象不进行光照贴图时在旧版顶点光照渲染中使用;在光照贴图为 RGBM 编码的平台上(PC 和游戏主机)
"VertexLM" //当对象不进行光照贴图时在旧版顶点光照渲染中使用;在光照贴图为双 LDR 编码的平台上(移动平台)
"RequireOptions" //用于指定当满足某些条件时才渲染该 Pass
"SoftVegetation" //仅当 Quality 窗口中开启了 SoftVegetation 时才渲染此通道
"PassFlags" //一个渲染通道 Pass 可指示一些标志来更改渲染管线向 Pass 传递数据的方式
"OnlyDirectional" //限制一些特殊光源数据给到着色器,这意味着非重要光源的数据将不会传递到顶点光源或球谐函数着色器变量
GrabPass { "变量名"... } //即将绘制对象时的屏幕内容抓取到纹理中,在后续通道中即可使用此纹理,从而执行基于图像的高级效果。

渲染通道

具体实现着色器代码的地方(每个 SubShader​ 语句块中至少有一个渲染通道,可以有多个)

Pass渲染通道语句块中,主要包含了:

  1. 名字:可以帮助我们复用 Pass​ 代码
  2. 渲染标签:不能使用 SubShader​ 中的渲染标签,有自己独有的渲染标签
  3. 渲染状态:SubShader​ 当中的渲染状态同样可以在 Pass​ 中使用,影响的区域不同
  4. 着色器语言逻辑:我们之后会使用CG和HLSL语言编写

四个部分

1
2
3
4
5
6
Pass {
1. Name 名称
2. 渲染标签
3. 渲染状态
4. 其他着色器代码
}

Pass的名字

主要作用:我们对 Pass​ 命名的主要目的
可以利用 UsePass​ 命令在其他Shader当中复用该 Pass​ 的代码,
只需要在其他Shader当中使用 UsePass "Shader路径/Pass名"​ 即可复用

注意:Unity内部会把 Pass​ 名称转换为大写字母,因此在使用 UsePass​ 命令时必须使用大写形式的名字

1
2
3
4
5
6
7
8
9
10
11
12
Shader "TeachShader/Lesson8"
{
Properties {/*...*/}
SubShader
{
// ...
Pass
{
Name "MYLESSON8PASS"
}
}
}

在其他Shader中复用该 Pass​ 代码时:UsePass "Pase所在的Shader名/Pass名字(大写)"

1
2
3
4
SubShader
{
​UsePass "TeachShader/Lesson8/MYLESSON8PASS"
}

Pass中的渲染标签

Pass中的渲染标签语法和SubShader中相同

1
2
3
4
Pass
{
Tags{ "标签名1" = "标签值1" "标签名2" = "标签值2" "标签名2" = "标签值2" .......}
}

但是我们之前讲解过的 SubShader​ 语句块中的渲染标签不能够在 Pass​ 中使用,Pass​ 当中有自己专门的渲染标签

  1. 指定Pass执行阶段

    主要作用:指定了该 Pass​ 应该在哪个阶段执行
    可以将着色器代码分配给适当的渲染阶段,以实现所需的效果

    1
    Tags{ "LightMode" = "标签值" }
    1. Always​ - 始终渲染;不应用光照
    2. ForwardBase​ - 在前向渲染中使用;应用环境光、主方向光、顶点/SH 光源和光照贴图
    3. ForwardAdd​ - 在前向渲染中使用;应用附加的每像素光源(每个光源有一个通道)
    4. Deferred​ - 在延迟渲染中使用;渲染 G 缓冲区
    5. ShadowCaster​ - 将对象深度渲染到阴影贴图或深度纹理中
    6. MotionVectors​ - 用于计算每对象运动矢量
    7. PrepassBase​ - 在旧版延迟光照中使用;渲染法线和镜面反射指数
    8. PrepassFinal​ - 在旧版延迟光照中使用;通过组合纹理、光照和反光来渲染最终颜色
    9. Vertex​ - 当对象不进行光照贴图时在旧版顶点光照渲染中使用;应用所有顶点光源
    10. VertexLMRGBM​ - 当对象不进行光照贴图时在旧版顶点光照渲染中使用;在光照贴图为 RGBM 编码的平台上(PC 和游戏主机)
    11. VertexLM​ - 当对象不进行光照贴图时在旧版顶点光照渲染中使用;在光照贴图为双 LDR 编码的平台上(移动平台)

    关于向前渲染、延迟渲染、旧版光照等概念了解:内置渲染管线中的渲染路径 - Unity 手册

  2. 指定Pass执行条件

    主要作用:用于指定当满足某些条件时才渲染该 Pass

    1
    Tags{ "RequireOptions" = "标签值" }

    目前Unity仅支持:

    1
    Tags{ "RequireOptions" = "SoftVegetation" }

    仅当 Quality 窗口中开启了 SoftVegetation​ 时才渲染此通道:QualitySettings-softVegetation - Unity 脚本 API

  3. 指示Pass标志

    主要作用:一个渲染通道 Pass​ 可指示一些标志来更改渲染管线向 Pass​ 传递数据的方式

    1
    Tags{ "PassFlags" = "标签值" }

    目前Unity仅支持:

    1
    Tags{ "PassFlags" = "OnlyDirectional" }

    ForwardBase​ 向前渲染的通道类型中使用时,此标志的作用是仅允许主方向光和环境光/光照探针数据传递到着色器
    简单来说,限制一些特殊光源数据给到着色器,这意味着**非重要光源的数据将不会传递到顶点光源或球谐函数着色器变量**

Pass中的渲染状态

我们上节课在 SubShader​ 语句块中学习的渲染状态同样适用于 Pass

比如:

  • 剔除方式:决定了模型正面背面是否能够被渲染
  • 深度缓冲和深度测试:决定了景深关系的确定以及透明效果的正确表达等
  • 混合方式:决定了透明半透明颜色的正确表现,以及一些特殊颜色效果的表现

这些渲染状态都可以在单个Pass中进行设置

需要注意的是:
如果在 SubShader​ 语句块中使用会影响之后的所有渲染通道 Pass
如果在 Pass​ 语句块中使用只会影响当前 Pass​ 渲染通道,不会影响其他的 Pass

不仅如此,Pass​ 中还可以使用固定管线着色器的命令

其他着色器代码

其他代码部分就是实现着色器的核心代码部分
我们可能会用到CG或HLSL等着色器语言来进行逻辑书写

GrabPass命令

我们可以利用 GrabPass​ 命令把即将绘制对象时的屏幕内容抓取到纹理中(如同截屏一样)
在后续通道中即可使用此纹理,从而执行基于图像的高级效果。(常用于制作一些滤镜)

举例:将绘制该对象之前的屏幕抓取到 _BackgroundTexture​ 中

1
2
3
4
GrabPass
{
"_BackgroundTexture"
}

注意:该命令一般写在某个 Pass​ 前,在之后的 Pass​ 代码中可以利用 _BackgroundTexture​ 变量进行处理