LearnOpenGL学习笔记—光照04:Lighting Maps
0 前言
本节笔记对应官网学习内容:光照贴图
在光照01中我们初识了颜色的概念,试着做了一下环境光
在光照02中我们学习了一下Phong光照模型与Blinn-Phong光照模型
在光照03中我们初识了材质的概念并封装了对应的类
尽管在上一节中,我们讨论了让每个物体都拥有自己独特的材质从而对光照做出不同的反应的方法。
这样能够很容易在一个光照的场景中给每个物体一个独特的外观,但是这仍不能对一个物体的视觉输出提供足够多的灵活性。
在上一节中,我们将整个物体的材质定义为一个整体,但现实世界中的物体通常并不只包含有一种材质,而是由多种材质所组成。
一辆汽车:它的外壳非常有光泽,车窗会部分反射周围的环境,轮胎不会那么有光泽,所以它没有镜面高光,轮毂非常闪亮。
汽车同样会有漫反射和环境光颜色,它们在整个物体上也不会是一样的,汽车有着许多种不同的环境光/漫反射颜色。
总之,这样的物体在不同的部件上都有不同的材质属性。
所以,上一节中的那个材质系统是肯定不够的,它只是一个最简单的模型,所以我们需要拓展之前的系统,引入漫反射和镜面光贴图(Map)。
这允许我们对物体的漫反射分量(以及间接地对环境光分量,它们几乎总是一样的)和镜面光分量有着更精确的控制。
1 diffuse+ambient
我们希望通过某种方式对物体的每个片段单独设置漫反射颜色,这很像在之前教程中详细讨论过的纹理贴图。
我们对同样的原理(使用一张覆盖物体的图像)使用不同的名字,让我们能够逐片段索引其独立的颜色值。
在光照场景中,它通常叫做一个漫反射贴图(Diffuse Map),它是一个表现了物体所有的漫反射颜色的纹理图像。
为了使用漫反射贴图,我们来改改shader的代码
在片元着色器中
in vec2 TexCoord;
struct Material {
vec3 ambient;
sampler2D diffuse;
vec3 specular;
float shininess;
};
......
vec3 diffuse = texture(material.diffuse,TexCoord).rgb;
在顶点着色器中
out vec2 TexCoord;
......
void main(){
......
TexCoord=aTexCoord;
......
}
在main中设置顶点属性时
// 位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 颜色属性
//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
//glEnableVertexAttribArray(1);
// 法向量属性
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
// 贴图uv属性
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(3);
我们加上对应的漫反射纹理坐标,并且把之前有关笑脸木箱的代码去掉
float vertices[] = {
//position //normal //TexCoord
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-15.0f, -4.0f, -15.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
15.0f, -4.0f, -15.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
15.0f, -4.0f, 15.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
15.0f, -4.0f, 15.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-15.0f, -4.0f, 15.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-15.0f, -4.0f, -15.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
material.h文件中
unsigned int diffuse;
......
Material(Shader* _shader, unsigned int _diffuse, glm::vec3 _specular, glm::vec3 _ambient, float _shininess);
material.cpp中_diffuse也改成unsigned int
并且导入material
#pragma region Init Material
Material* myMaterial = new Material(myShader,
LoadImageToGPU("container.jpg", GL_RGB, GL_RGB, 0),
glm::vec3 (0.5f, 0.5f, 0.5f),
glm::vec3 (1.0f, 0.5f, 0.31f),
150.0f);
#pragma endregion
为了设置uniform,我们在shader.h设置一个方法
void SetUniform1i(const char* paraNameString, int slot);
在cpp中写出对应的构造
void Shader::SetUniform1i(const char