计算机图形学(OPENGL):颜色

本文同时发布在我的个人博客上: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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。