总结一句话,就是将之前的纯色,转换成读取贴图中的颜色来替代
漫反射贴图
struct Material {
sampler2D diffuse;
vec3 specular;
float shininess;
};
...
in vec2 TexCoords;
注意我们将在片段着色器中再次需要纹理坐标,所以我们声明一个额外的输入变量。接下来我们只需要从纹理中 采样片段 的漫反射颜色值即可:
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
将环境光得材质颜色设置为漫反射材质颜色同样的值
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
更新顶点着色器
lightingShader.setInt("material.diffuse", 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);
绑定箱子的纹理到这个纹理单元
lightingShader.setInt("material.diffuse", 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);
镜面光贴图
用来显示反光
镜面高光的强度可以通过图像每个像素的亮度来获取。镜面光贴图上的每个像素都可以由一个颜色向量来表示,比如说黑色代表颜色向量vec3(0.0),灰色代表颜色向量vec3(0.5)。在片段着色器中,我们接下来会取样对应的颜色值并将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮。
使用 Photoshop或Gimp 之类的工具,将漫反射纹理转换为镜面光纹理还是比较容易的,只需要剪切掉一些部分,将图像转换为黑白的,并增加亮度/对比度就好了。
采样镜面光贴图
lightingShader.setInt("material.specular", 1);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);
接下来更新片段着色器的材质属性,让其接受一个sampler2D而不是vec3作为镜面光分量:
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
最后我们希望采样镜面光贴图,来获取片段所对应的镜面光强度:
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));
FragColor = vec4(ambient + diffuse + specular, 1.0);