光照贴图

光照贴图Lighting Maps

光照贴图分为漫反射贴图(Diffuse texture)和镜面贴图(Specular texture)两类。下面一一介绍

漫反射贴图

我们希望通过某种方式对每个原始像素独立设置diffuse颜色。通过使用一张图片覆盖住物体,我们就可以为每个原始像素索引独立颜色值。在光照场景中,通过纹理来呈现一个物体的diffuse颜色,这个做法被称做漫反射贴图(Diffuse texture)

实现细节

声明一个material结构体,包含一个采样器sampler2D diffuse

struct Material
{

sampler2D diffuse; //diffuse采样器
vec3 specular;
float shininess;

};

...

in vec2 TexCoords;


在片段着色器中我们将会再次需要纹理坐标,所以我们声明一个额外输入变量。然后我们简单地从纹理采样,来获得原始像素的diffuse颜色值:
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

同样,把ambient材质的颜色设置为diffuse材质的颜色:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

在绘制物体之前,我们希望首选纹理单元被赋为material.diffuse这个uniform采样器,并绑定箱子的纹理到这个纹理单元:
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.diffuse"), 0);

...

glActiveTexture(GL_TEXTURE0);

glBindTexture(GL_TEXTURE_2D, diffuseMap);


绘制效果:

光照贴图_第1张图片

镜面贴图

由于我们的物体是个箱子,大部分是木头,我们知道木头是不应该有镜面高光的。我们通过把物体设置specular材质设置为vec3(0.0f)来修正它。但是这样意味着铁边会不再显示镜面高光,我们知道钢铁是会显示一些镜面高光的。我们会想要控制物体部分地显示镜面高光,它带有修改了的亮度。
我们同样用一个纹理贴图,来获得镜面高光。这意味着我们需要生成一个黑白(或者你喜欢的颜色)纹理来定义specular亮度,把它应用到物体的每个部分。
一个specular贴图和其他纹理一样,所以代码和diffuse贴图的代码也相似
更新片段着色器材质属性,接受一个sampler2D作为这个specular部分的类型

struct Material{

sampler2D diffuse;
sampler2D specular;
float shininess;

};


在渲染前让我们把它绑定到合适的纹理单元:
glUniform1i(glGetUniformLocation(lightingShader.Program, "material.specular"), 1);

...

glActiveTexture(GL_TEXTURE1);

glBindTexture(GL_TEXTURE_2D, specularMap);


最后通过采样这个specular贴图,来获取原始像素相应的specular亮度:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

vec3 specular = light.specular * spec *

vec3(texture(material.specular, TexCoords));
color = vec4(ambient + diffuse + specular, 1.0f);


通过使用一个specular贴图我们可以定义极为精细的细节,物体的这个部分会获得闪亮的属性.
可以清晰地看到箱子的材质现在非常类似真实的铁边的木头箱子了

效果如下:

光照贴图_第2张图片

http://learnopengl-cn.readthedocs.io/zh/latest/02%20Lighting/04%20Lighting%20maps/

你可能感兴趣的:(光照贴图)