US3S5L2——在Shader中判断光源类型
US3S5L2——在Shader中判断光源类型
知识回顾
预处理指令:Shader中也存在预处理指令,它的使用和C#的预处理器指令类似
前向渲染路径在哪里进行光照计算
- Base Pass(基础渲染通道):主要用于处理影响该物体的一个高质量光源(平行光)、所有中(逐顶点处理)低质量(SH处理)光源 等
- Additional Pass(附加渲染通道):主要用于处理影响该物体的除平行光以外的其它高质量光源(每个高质量光源都会调用)
本章代码关键字
1 | // Unity 内置的判断光源的宏 |
前向渲染路径主要关注的处理内容
两个 Pass
:
-
Base Pass(基础渲染通道,每个片元只会计算一次):
只需要处理一个逐像素平行光源(一般场景中最亮会自动赋值对应变量),其他的中(逐顶点)、低质量(SH)光源,Unity 会帮助我们处理
-
Additional Pass(附加渲染通道):
除了最亮的平行光、其他高质量的光源(可能是平行光、点光源、聚光灯)都会调用一次该
Pass
进行计算
因此我们一般需要在 Additional Pass 中判断光源类型来分别处理部分逻辑
如何在 Shader 中判断光源类型
Unity中提供了三个重要的宏,分别是:
-
_DIRECTIONAL_LIGHT
:平行光 -
_POINT_LIGHT
:点光源 -
_SPOT_LIGHT
:聚光灯
宏在这里的作用:
可以用于在编译时根据条件判断来包含或排除不同的代码块,实现条件编译
我们可以使用这些宏配合 Unity Shader 中的条件编译预处理指令,用于在编译时根据一定的条件选择性地包含或排除代码块
1 |
|
不过,上面的宏判断,可能会出现无法准确判断光源类型的问题,导致探照灯在平面上显示时会出现问题,
因此我们采用 AutoLight.cginc
内置文件中的宏来进行判断,它为我们提供了如下宏去做判断:
-
USING_DIRECTIONAL_LIGHT
:平行光 -
POINT
:点光源 -
SPOT
:聚光灯
因此判断代码修改为:
首先需要引用 AutoLight.cginc
1 |
然后,根据 USING_DIRECTIONAL_LIGHT
是否被定义来判断光源是否为平行光,若不是,则通过 POINT
和 SPOT
来判断是点光源还是聚光灯
1 |
|
其中 #ifdef
用来判断一个宏是否被定义
Unity 底层会根据该条件编译指令生成多个 Shader Variants(着色器变体)
这些 Variants 变体共享相同的核心代码,但根据条件编译的选择会包含不同的代码块
Shader variants 的基本概念是在编写 shader 时,通过条件编译指令(if
, #elif
,#else
,#endif
)
根据不同的配置选项生成多个版本的 shader。这些不同版本的 shader 称为 shader variants。