接上节:
我们给物体定义了一个材质的属性,这里包含了 环境光照(Ambient Lighting),漫反射光照(Diffuse Lighting),镜面光照(Specular Lighting)和反光度(Shininess)。
struct Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
void main()
{
// 环境光
vec3 ambient = lightColor * material.ambient;
// 漫反射
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = lightColor * (diff * material.diffuse);
// 镜面光
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = lightColor * (spec * material.specular);
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
上面这段代码我们在上节已经详细讲过。我们看到整个光照都有作用在环境光,散射光,镜面光上,但是现实中这三个的影响肯定是不一样的,不全部都是作用最大的影响,我们可以把lightColor分出来:
struct Light
{
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
然后用光的影响分量去计算:
vec3 ambient = light.ambient * material.ambient;
vec3 diffuse = light.diffuse * (diff * material.diffuse);
vec3 specular = light.specular * (spec * material.specular);
光照贴图
物体在不同的部件上都有不同的材质属性,而不是一个材质可以表示的,所以扩展。引入漫反射贴图和镜面光贴图,这样可以更加精准的控制漫反射分量和镜面光分量。通俗点讲, 就是物体每个点上的镜面光照和漫反射的程度是不一样的,我们可以用贴图上的每个像素表示。
漫反射贴图:使用一张覆盖物体的图像,让我们可以逐片段索引独立的颜色值。这张图表现了物体所有漫反射颜色的纹理。
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
镜面光贴图:镜面光贴图上的每个像素都可以由一个颜色向量来表示。
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));