一、颜色的表示

颜色纺锤体(颜色锥体)

颜色的视觉模型:颜色三特性的空间表示

明度(亮度):垂直轴线表示黑白亮度变化

色调:水平圆周上的不同角度点,代表了不同色调的颜色

饱和度:从圆心向圆周过渡表示,同一色调下饱和度的提高。某个平面圆形上的色调饱和度不同,而明度(亮度)相同。

 CIE(Commission Internationale de L'Eclairage)色度图

CIE 1932色度图是用标称值表示的CIE色度图

其中,x表示红色分量,y表示绿色分量,E点代表白光,它的坐标是(0.33,0.33),边界上的数字表示光谱色的波长。

所欲单色光都位于舌形曲线上,这条曲线就是单色轨迹,曲线旁边标注的数字时单色(或称光谱色)光的波长值;而自然界中的各种实际颜色都位于这条闭合曲线内。

二、颜色模型

面向设备:RGB颜色模型、CMY颜色模型

面向用户:HSV颜色模型、HSL颜色模型

RGB颜色模型:

  • 采用三维直角坐标系R-Red G-Green B-Blue
  • 构成一个RGB颜色立方体
  • 通常使用于彩色光栅图形显示设备中
  • 真实感图形学中的主要颜色模型

CMY颜色模型

  • 以红、绿、蓝的补色青(Cyan)、品红(Magenta)、黄(Yellow)为原色构成的颜色模型
  • 常用于从白光中滤去某种颜色,又被成为减性原色系统,在白光中减去某种颜色来定义一种颜色
  • 用于印刷行业中

HSV(HSB)颜色模型

HSV(HSB)颜色模型:一个基于颜色六边形的六棱锥

  • H(Hue):色调,用角度度量,取值范围为0°~360° ,从红色开始按逆时针方向计算
  • S(Saturation):饱和度,表示颜色接近光谱色的程度.一种颜色,可以看成是某种光谱色不白色混合的结果.通常取值范围为0%~100%,值越大,颜色越饱和.光谱色的白光成分为0,饱和度达到最高.
  • V(Value或Brightness):明度,表示颜色明亮的程度.

HSL(HSI)颜色模型

  • H(Hue):色调,使用不水平轴之间的角度来表示,范围从0 o到360o ,从蓝色开始
  • S(Saturation):饱和度,说明颜色的相对浓度
  • L(Lightness)或者I(Intensity):亮度,在L=0处为黑色,在L=1处为白色,灰度沿着L轴分布

采用近似的圆柱坐标系S=1,L=0.5 纯色彩S=0 仅有灰度

 三、OpenGL颜色模型

两种颜色存储方式:

颜色值:像素点附加颜色信息之后,就必须为每一个像素点额外分配一个内存空间保存该点的颜色信息,对于RGB或者RGBA颜色模式,保存的数据直接代表其颜色值。

颜色索引:对于颜色索引模式,保存的是该颜色在颜色索引表中的位置,通过查颜色索引表对应到相应的颜色。颜色索引模式的优点是占用空间小,运行速度快,缺点是显示效果稍差。

随着硬件的提速升级,目前一般采用直接存储颜色值的方式。

RGB颜色模式

RGB模式中,RGB分别表示红绿蓝三色的分量,每个分量在0.0~1.0之间,通过设置RGB不同比例,可以获得任意颜色。

当我们想要获取一个橙色时,可以定义这样一个颜色向量

glm::vec3 coral(1.0f,0.5f,0.2f);

RGBA颜色模式:

RGB分别表示红绿蓝三色的分量,A(实际上是α系数,Alpha Coeefficient)表示颜色的透明度。

通过设置RGBA不同的值,可以获得任意的颜色。

在县市生活中,我们看到的物体的颜色其实是它所反射的颜色(不被物体吸收的颜色)。比如:当我们用白光照在一个蓝色的玩具上,这个蓝色的玩具会吸收白光中除了蓝色以外的所有子颜色,不被吸收的蓝色光被反射到我们眼中,让这个玩具看起来是蓝色的。

当我们把白色光源颜色与珊瑚色物体颜色值相乘,所得到的就是这个物体所反射的颜色。

LightIntensity*ObjectColor = Reflectcolor

(R,G,B)*(X,Y,Z)=(XR,YG,ZB);

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);

四、创建一个光照场景

我们使用之前创建的立方体箱子作为被投光对象,并用另一个立方体来代表光源。

顶点着色器

使用顶点着色器来绘制箱子。与之前的顶点着色器相比,容器的顶点位置是保持不变的,因此顶点着色器中没有新的代码。

#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。

unsigned int lightVAO;
glGenVertexArray(1,&lightVAO);
glBindVertexArray(lightVAO);
//只需要绑定VBO不用再次设置VBO的数据,因为箱子的VBO数据中已经包含了正确的立方体顶点数据
glBindBuffer(GL_ARRAY_BUFFER,VBO);
//设置灯立方体的顶点属性(对我们来说仅仅只有位置数据)
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);
glEnableVertexAttribArray(0);

片段着色器

这个片段着色器从uniform变量中接受物体的颜色和光源的颜色。

#version 330 core
out vec4 FragColor;uniform vec3 objectColor;
uniform vec3 lightColor;void main()
{
FragColor = vec4(lightColor * objectColor,1.0);
}
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);//将向量的四个分量全部设置为1.0
}

当我们想要绘制我们的物体时,我们需要使用刚刚定义的着色器来绘制箱子。当我们想要绘制灯的时候,我们会使用灯的着色器。

为了显示真正的灯,我们将表示光源的立方体与光源绘制在相同的位置。

声明一个全局vec3变量来表示光源在场景的世界空间坐标中的位置。

glm::vec3 lightPos(1.2f,1.0f,2.0f);

把灯移动到这个位置,并将其缩小。

model = glm::mat4();
model = glm::translate(model,lightPos);
model = glm::scale(model,glm::vec3(0.2f);

绘制灯立方体

lamShader.use();
//设置模型、视图、和投影矩阵uniform//绘制灯立方体对象
glBindVertexArrar(lightVAO);
glDrawArrays(GL_TRIANGLES,0,36);

在这里分享一个我新学到的技巧:

在一大段代码的开头加#pragma region *** ,结尾加#pragma endregion,然后在开头的#pragma region ***前面按一下tab,就可以把它们都收起来。

这里有对之前的代码进行整理

fragmentSource.txt

#version 330 corein vec2 TexCoord;
in vec4 vertexColor;// texture samplers
uniform sampler2D ourTexture;
uniform sampler2D ourFace;
uniform vec3 objColor;
uniform vec3 ambientColor;out vec4 FragColor;void main()
{// linearly interpolate between both textures (80% container, 20% awesomeface)//FragColor = mix(texture(ourTexture, TexCoord), texture(ourFace, TexCoord), 0.2);FragColor = vec4(objColor * ambientColor,1.0)*texture(ourTexture, TexCoord)* texture(ourFace, TexCoord);
}

vertexSource.txt

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;out vec2 TexCoord;
out vec4 vertexColor;
void main()
{gl_Position = projMat *  viewMat * modelMat * vec4(aPos, 1.0);vertexColor = vec4(aColor.x,aColor.y,aColor.z,1);TexCoord = aTexCoord;
}

main.cpp

#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include"Shader.h"
#include"Camera.h"#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT =600;#pragma region Camera Declare
Camera camera(glm::vec3(0, 0, 3.0f), glm::radians(-15.0f), glm::radians(180.0f), glm::vec3(0, 1.0f, 0));
#pragma endregion#pragma region Input Declare
float lastX;
float lastY;
bool firstMouse = true;void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){glfwSetWindowShouldClose(window, true);}if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS){camera.speedZ = 1.0f;}else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS){camera.speedZ = -1.0f;}else{camera.speedZ = 0;}
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse == true){lastX = xpos;lastY = ypos;firstMouse = false;}float deltaX, deltaY;deltaX = xpos - lastX;deltaY = ypos - lastY;lastX = xpos;lastY = ypos;camera.ProcessMouseMovement(deltaX, deltaY);}#pragma endregionunsigned int LoadImageToGPU(const char*filename, GLint internalformat, GLenum format, int textureSlot)
{unsigned int texBuffer;glGenTextures(1, &texBuffer);glActiveTexture(GL_TEXTURE0 + textureSlot);glBindTexture(GL_TEXTURE_2D, texBuffer);int width, height, nrChannels;stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.unsigned char *data = stbi_load(filename, &width, &height, &nrChannels, 0);if (data){glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);}else{std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);return texBuffer;
}
int main()
{#pragma region Open a window// glfw: initialize and configure// ------------------------------glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);glfwSetCursorPosCallback(window, mouse_callback);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);
#pragma endregion#pragma region Model Datafloat vertices[] = {-0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f,  0.5f,  0.5f, -0.5f,  0.5f,  0.5f, -0.5f,  -0.5f,  0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,  0.5f, 0.5f, -0.5f,  0.5f,  0.5f,  0.5f,  0.5f,  0.5f,  0.5f,  0.5f,  -0.5f,  0.5f,  0.5f, -0.5f, -0.5f,  0.5f, -0.5f,  0.5f,  0.5f, -0.5f,  0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,  0.5f, -0.5f,  0.5f,  0.5f, 0.5f,  0.5f,  0.5f,  0.5f,  0.5f, -0.5f,  0.5f, -0.5f, -0.5f,  0.5f, -0.5f, -0.5f,  0.5f, -0.5f,  0.5f,  0.5f,  0.5f,  0.5f,  -0.5f, -0.5f, -0.5f,0.5f, -0.5f, -0.5f, 0.5f, -0.5f,  0.5f, 0.5f, -0.5f,  0.5f, -0.5f, -0.5f,  0.5f,-0.5f, -0.5f, -0.5f,-0.5f,  0.5f, -0.5f,0.5f,  0.5f, -0.5f, 0.5f,  0.5f,  0.5f, 0.5f,  0.5f,  0.5f, -0.5f,  0.5f,  0.5f,-0.5f,  0.5f, -0.5f,};glm::vec3 cubePositions[] = {glm::vec3(0.0f,  0.0f,  0.0f),glm::vec3(2.0f,  5.0f, -15.0f),glm::vec3(-1.5f, -2.2f, -2.5f),glm::vec3(-3.8f, -2.0f, -12.3f),glm::vec3(2.4f, -0.4f, -3.5f),glm::vec3(-1.7f,  3.0f, -7.5f),glm::vec3(1.3f, -2.0f, -2.5f),glm::vec3(1.5f,  2.0f, -2.5f),glm::vec3(1.5f,  0.2f, -1.5f),glm::vec3(-1.3f,  1.0f, -1.5f)};
#pragma endregion#pragma region Init Shader PragramShader ourShader("VertexSource.txt", "fragmentSource.txt");
#pragma endregion#pragma region Init and Load Models to VAO,VBO unsigned int  VAO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);unsigned int VBO;glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// texture coord attributeglVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);
#pragma endregion#pragma region Init and Load Textureunsigned int texBufferA;texBufferA = LoadImageToGPU("container.jpg",GL_RGB,GL_RGB,0);unsigned int texBufferB;texBufferB = LoadImageToGPU("awesomeface.png",GL_RGBA, GL_RGBA, 1);
#pragma endregion// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)// -------------------------------------------------------------------------------------------#pragma region Prepare MVP matricesglm::mat4 modelMat;glm::mat4 viewMat;glm::mat4 projMat;projMat = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
#pragma endregion// render loop// -----------while (!glfwWindowShouldClose(window)){// inputprocessInput(window);// clear srceen glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!viewMat = camera.GetViewMatrix();for (unsigned int i = 0; i < 10; i++){//set Model MatrixmodelMat = glm::translate(glm::mat4(1.0f), cubePositions[i]);//set View and Project Matrices here//set Material->shader programourShader.use();//set Material->textures                                                                                             glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texBufferA);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texBufferB);//set material->uniformsglUniform1i(glGetUniformLocation(ourShader.ID, "ourTexture"), 0);glUniform1i(glGetUniformLocation(ourShader.ID, "ourFace"), 1);unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "modelMat");unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "viewMat");unsigned int projectLoc = glGetUniformLocation(ourShader.ID, "projMat");glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMat));glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(viewMat));glUniformMatrix4fv(projectLoc, 1, GL_FALSE, glm::value_ptr(projMat));glUniform3f(glGetUniformLocation(ourShader.ID, "objColor"), 1.0f, 0.5f, 0.31f);glUniform3f(glGetUniformLocation(ourShader.ID, "ambientColor"), 1.0f, 1.0f, 1.0f);// set ModelglBindVertexArray(VAO);//DrawcallglDrawArrays(GL_TRIANGLES, 0, 36);}//Clean up,prepare for next render loopglfwSwapBuffers(window);glfwPollEvents();camera.UpdataCameraPos();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return 0;
}

其他的camera类和Shader没有发生改变。

OpenGL学习之颜色相关推荐

  1. OpenGL学习之路17---- 镜面反射光

    代码放在github上 根据教程:ogldev一步步开始,记录学习历程 之前完成环境光和漫射光的学习.环境光的计算只由光强来决定,场景中所有位置是同一亮度:漫射光的计算由光强和光的方向一同决定,相关博 ...

  2. OpenGL学习笔记(一)绘制点线面及多面体

    OpenGL学习笔记(一)绘制点线面及多面体 绘制点线面 #include <iostream> #include <GL/GLUT.h> #define PI 3.14159 ...

  3. 【我的OpenGL学习进阶之旅】介绍一下 绘制图元

    目录 一.绘制图元 1.1 `glDrawArrays` 1.1.1 `glDrawArrays`API说明 1.1.2 `glDrawArrays`API示例 1.2 `glDrawElements ...

  4. OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7866 ...

  5. OpenGL学习(九)阴影映射(shadowMapping)

    目录 写在前面 阴影映射原理简介 封装 Camera 类 帧缓冲 阴影映射 准备工作 创建帧缓冲与深度纹理附件 从光源方向进行渲染 正常地渲染场景 如何查找bug(⚠重要) 多纹理传送 查看深度纹理数 ...

  6. OpenGL学习(十)天空盒

    目录 写在前面 天空盒简介 创建立方体贴图 渲染一个立方体 立方体贴图着色器 开始绘制天空盒 完整代码 着色器 c++ 写在前面 上一篇博客回顾:OpenGL学习(九)阴影映射(shadowMappi ...

  7. 【我的OpenGL学习进阶之旅】【持续更新】关于学习OpenGL的一些资料

    目录 一.相关书籍 OpenGL 方面 C方面 NDK 线性代数 二.相关博客 2.0 一些比较官方的链接 2.1 OpenGL着色器语言相关 2.2 [[yfan]](https://segment ...

  8. 8.OpenGL学习之颜色混合

    颜色混合 通常情况下OpenGL渲染时会把颜色值放在颜色缓冲区中.每个片段的深度值也是放在深度缓冲区中的.当深度测试被关闭(禁用)时,新的颜色值简单得覆盖颜色缓冲区中已经存在的其他值.当深度测试被打开 ...

  9. 拓幻图形学工程师教学手册(第一讲)|一字一字敲出OpenGL学习教程

    动机 首先申明,我是拓幻科技图形处理工程师,自己接触OpenGL,图形图像等方面也有六年多了,很多人其实并不了解这方面,也不了解如何系统地去学,我觉得基于我硕士时期的课程和经验给大家.这些资料和经验也 ...

  10. OpenGL学习之路(四)

    1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...

最新文章

  1. C言语教程第五章:函数(1)
  2. java小知识_java小知识点简单回顾
  3. python 三角函数
  4. DPM 2010(三)---Exchange2010单邮箱恢复
  5. 网络招聘“草莽时代”该结束了
  6. java程序设计题目_Java程序设计习题集(含答案).doc
  7. Redis中的I/O 多路复用(I/O Multiplexing)
  8. Linux文本查看命令之uniq
  9. android 内部共享存储,Android共享内部存储
  10. 【NOIP模拟】矩阵
  11. 为什么有时候代码会提示要去掉@override
  12. 程序人生:不知道我讲了什么的回应稿
  13. Linux 可执行文件结构与进程结构
  14. Postman测试Soap协议接口
  15. 影视搜索播放PHP源码_可对接资源网
  16. 2020机修钳工(中级)模拟考试及机修钳工(中级)作业模拟考试
  17. oracle循环数据字典,Oracle DUL工作原理和技术实现
  18. C语言训练-3426-小金追呀追不上妹子
  19. excel 查找图相框或文本框中的内容
  20. 单片机控制秒表C语言程序,89C51单片机秒表的设计(全文完整版)

热门文章

  1. python如何下载包_怎么在python中下载包
  2. T3及报税软件报表使用无线打印机打印凭证没反应
  3. PFPLD 人脸关键点检测
  4. ckPlayer播放器嵌入页面时报错CKobject is not defined解决方案
  5. 重庆天象网络科技:UI设计的图标概述,新手必看的设计基础
  6. 计算机硬盘搜索记录,怎么清除Win7搜索记录 Win7搜索历史记录删除教程
  7. Unrecogized font family ‘Ionicons’ 在ios上报错,android正常
  8. 如何长期且快乐的学习?
  9. 银河麒麟WPS表格打开TXT文件的方法
  10. 洛谷刷题笔记——P3953 [NOIP2017 提高组] 逛公园