渲染五 多个光照
- 每个物体渲染多个光照
- 支持不同的光照类型
- 使用光照 cookies
- 计算顶点光照
- 引入球谐函数
这是渲染系列教程的第五篇教程。前一章我们介绍了光照,只是一个单一的方向光。现在我们将支持多个光照。
包含文件
为了能为我们的shader 支持多个光照,我们需要在 shader 里面添加更多的通道 pass。这些通道 pass 最终会包含很接近的代码(因为有很多相同的渲染处理,只是部分细节不一样而已)。为了避免重复性的代码,我们会把我们的 shader 代码移到一个包含文件里面(include file)。
Unity 没有一个创建shader 包含文件的菜单。因此我们得通过你的操作系统的文件浏览器,手动前往asset 文件夹下。创建一个名为My Lighting.cginc的纯文本文件。你可以复制一个我们前面写的 shader 文件,改个名字,然后清除里面的内容。
拷贝我们光照 shader 的所有代码到这个文件中,从#pragma语句的下方复制到ENDCG。
#include "UnityPBSLighting.cginc"
…
float4 MyFragmentProgram (Interpolators i) : SV_TARGET {
…
}
我们现在可以将这个文件包含在我们的着色器中,替换以前的代码。因为它在同一个文件夹,我们可以直接引用它。
CGPROGRAM
#pragma target 3.0
#pragma vertex MyVertexProgram
#pragma fragment MyFragmentProgram
#include“My Lighting.cginc”
ENDCG
避免重复定义
你已经知道,包含文件本身也可以包含其他的文件。当你引入一个文件,而这个文件反过来也引入了相同的其他文件,这个时候就会导致代码重复。这样就会导致编译器报代码重复定义的错误。
为了避免这样的重复定义,传统的是使用定义检查来保护包含文件。这是一个预处理器检查,以查看是否做出了一定的定义。该定义只是一个与包含文件的名称对应的唯一标示符。你可以将它定义为任意东西,甚至没有。在我们的例子中,我们将使用标示符MY_LIGHTING_INCLUDED
#define MY_LIGHTING_INCLUDED
#include“UnityPBSLighting.cginc”
...
现在我们可以将我们的包含文件的整个内容放置到一个预处理器的 if 代码段里面。前提条件是MY_LIGHTING_INCLUDED还没有被定义过。
#if !defined(MY_LIGHTING_INCLUDED)
#define MY_LIGHTING_INCLUDED
#include "UnityPBSLighting.cginc"
…
#endif
通常,被保护起来的包含文件里面的内容是不缩进的。
第二个光照
我们的第2个光照将再次是一个方向光。
第2个通道Pass
Draw Call Batches
Frame Debugger
点光源
光照函数
光照的位置
光的衰减
光照范围
混合光照
Shader变体
使用关键字
聚光光源
除了方向光和点光源,unity 还支持聚光灯。聚光光源跟点光源类似,除了它们被限制在一个椎体内,而不是各个方向上发光。