本文同时发布在我的个人博客上:https://dragon_boy.gitee.io
颜色
在计算机中,颜色常常用代表RGB的三个数字表示,通过三种数字(0-1)的组合,我们可以表示几乎所有的颜色,比如,下面是一个珊瑚色的颜色向量:
glm::vec3 coral(1.0f, 0.5f, 0.31f);
在现实生活中,一个物体的颜色往往是它所反射光的颜色,而其它颜色的光都被它吸收了。当然这种规则也在图形学中被应用。比如我们定义了一束光的颜色,并定义了一个物体的颜色,我们想得到这个物体最终的颜色,做法是将前两个颜色向量相乘:
glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (1.0f, 0.5f, 0.31f);
这里我们定义的是白光,可以看到物体最终的颜色就是我们所定义的颜色。接着我们定义一束绿光:
glm::vec3 lightColor(0.0f, 1.0f, 0.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (0.0f, 0.5f, 0.0f);
可以看到物体最终的颜色只有G通道显示了,其它都被置为0。
上面这两个例子就很好的表明了物体显示颜色的原因,通过我们设置的对每个通道的影响来反射或吸收相应的光源的光,最终就得到物体显示的颜色。
光照场景
接下来我们模拟现实生活中的灯光。我们这里将光源当作一个立方体,和之前一样,为它单独创建顶点着色器和片元着色器,顶点着色器(我们只需要位置):
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
同样为灯光立方体创建VAO对象,我们已经将数值传入到VBO了,不必反复创建(也可以额外创建一个VBO专门管理灯光的数据):
unsigned int lightVAO;
glGenVertexArrays(1, &lightVAO);
glBindVertexArray(lightVAO);
//这里只需要绑定VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
修改原立方体的片元着色器,用灯光颜色和物体颜色来计算结果颜色:
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
void main()
{
FragColor = vec4(lightColor * objectColor, 1.0);
}
当然,要为这些uniform变量赋值:
lightingShader.use();
lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
lightingShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
接着设置灯光立方体的片元着色器:
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0); //白光
}
为了渲染灯光立方体,我们定义它的位置,并设置model矩阵,view和projection保持不变就行,最后在渲染循坏绘制灯光立方体。
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
//渲染循环中
...
model = glm::mat4(1.0f);
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f));
...
lightCubeShader.use();
...
glBindVertexArray(lightCubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
最终结果如下:
这里给出源码参考:Code。
最后,给出原文地址,请多多参考:https://learnopengl.com/Lighting/Colors。