多光源
之前章节分享到了OpenGL中光照的知识,其中包括冯氏着色(Phong Shading)、材质(Material)、光照贴图(Lighting Map)以及不同种类的投光物(Light Caster)。该章节需要结合之前知识,创建一个包含六个光源的场景。分别是:定向光,四个点光源,一个手电筒
在场景中使用多个光源,需要把光照计算封装到GLSL函数中。
因为每种光源都需要一种不同的计算方法,封装后更好理解和使用。
补充:GLSL中的函数和C函数类似,它有一个函数名、一个返回值类型,如果函数不是在main函数之前声明的,我们还必须在代码文件顶部声明一个原型。我们对每个光照类型都创建一个不同的函数:定向光、点光源和聚光。
我们需要有一个单独的颜色向量代表片段的输出颜色。对于每一个光源,它对片段的贡献颜色将会加到片段的输出颜色向量上。所以场景中的每个光源都会计算它们各自对片段的影响,并结合为一个最终的输出颜色。大体的结构会像是这样:
out vec4 FragColor;
void main()
{
// 定义一个输出颜色值
vec3 output;
// 将定向光的贡献加到输出中
output += someFunctionToCalculateDirectionalLight();
// 对所有的点光源也做相同的事情
for(int i = 0; i < nr_of_point_lights; i++)
output += someFunctionToCalculatePointLight();
// 也加上其它的光源(比如聚光)
output += someFunctionToCalculateSpotLight();
FragColor = vec4(output, 1.0);
}
定向光
在片段着色器中定义一个函数用于计算定向光相应片段的贡献。首先,需要定义一个定向光最少需要的变量。把这些变量存储在一个DirLight的结构体中,并将其定义成一个uniform:
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform DirLight dirLight;
把uniform类型的dirLight传入下面的函数:
vec3 CalcDirLight