OpenGL光照之颜色

2023-05-16

OpenGL光照之颜色

  • 颜色
    • 什么是颜色
    • 如何表示物体颜色
  • 光照场景的搭建

颜色

什么是颜色

颜色是通过眼、脑和我们的生活经验所产生的一种对光的视觉效应,我们肉眼所见到的光线,是由频率范围很窄的电磁波产生的,不同频率的电磁波表现为不同的颜色,对色彩的辨认是肉眼受到电磁波辐射能刺激后所引起的一种视觉神经的感觉。

其实在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的(Reflected)颜色。

如何表示物体颜色

首先要知道,在实际模型中物体吸收了其中的大部分颜色,它仅反射了代表物体颜色的部分,被反射颜色的组合就是我们眼睛所感知到的颜色。

具体操作:
把光源的颜色与物体的颜色值相乘,所得到的就是这个物体所反射的颜色(也就是我们所感知到的颜色)

举个例子
光源——白光
物体——蓝色
物体反射颜色——蓝色

glm::vec3 lightColor(1.0f, 1.0f, 1.0f);//白色
glm::vec3 toyColor(0.0f, 1.0f, 0.0f);//蓝色
glm::vec3 result = lightColor * toyColor; // = (0.0f, 1.0f, 0.0f);//蓝色

再举个例子
光源——蓝光
物体——珊瑚红
物体反射颜色——深绿色

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);//深绿

光照场景的搭建

首先知道需要些什么

  • 光源
  • 物体
  • VAO,VBO

这里建议的做法是将光源与物体的顶点着色器与片段着色器分开来设置,这样容易独自改变而不会受其他因素影响。

光源的顶点着色器:

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

光源的片段着色器:

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.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);
}

物体的片段着色器

#version 330 core
out vec4 FragColor;
  
uniform vec3 objectColor;
uniform vec3 lightColor;

void main()
{
    FragColor = vec4(lightColor * objectColor, 1.0);
}

VAO,VBO
可以让这个灯和其它物体使用同一个VAO,但考虑到接下来会频繁地对顶点数据和属性指针做出修改,我们并不想让这些修改影响到光源(我们只关心光源的顶点位置),因此我们有必要为光源与物体分别创建VAO,由于VBO只是为了储存数据,只需要绑定VBO不用再次设置VBO的数据,这边绘制的都是一样的正方体,VBO可以共用
物体 cubeVAO+VBO

    unsigned int VBO, cubeVAO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &VBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindVertexArray(cubeVAO);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

光源 lightCubeVAO+VBO

 	unsigned int lightCubeVAO;
    glGenVertexArrays(1, &lightCubeVAO);
    glBindVertexArray(lightCubeVAO);

    // we only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need (it's already bound, but we do it again for educational purposes)
    glBindBuffer(GL_ARRAY_BUFFER, VBO);//这个可以不要

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

设置渲染循环

		//[...]
 		// render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
  
        lightingShader.use();
        lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
        lightingShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
		//物体
        // view/projection transformations
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        glm::mat4 view = camera.GetViewMatrix();
        lightingShader.setMat4("projection", projection);
        lightingShader.setMat4("view", view);

        // world transformation
        glm::mat4 model = glm::mat4(1.0f);
        lightingShader.setMat4("model", model);

        // render the cube
        glBindVertexArray(cubeVAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);

		//光源
        lightCubeShader.use();
        lightCubeShader.setMat4("projection", projection);
        lightCubeShader.setMat4("view", view);
        model = glm::mat4(1.0f);
        model = glm::translate(model, lightPos);//glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
        model = glm::scale(model, glm::vec3(0.2f)); // 这边缩放以表示光源
        lightCubeShader.setMat4("model", model);

        glBindVertexArray(lightCubeVAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        //[....]

实现情况:
在这里插入图片描述
灯光为白色, 物体为珊瑚红色。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL光照之颜色 的相关文章

  • 操作符重载一些细节

    操作符重载一些注意事项 不能重载操作符只在类的成员函数中重载的操作符只在友元函数中重载的操作符补充 不能重载操作符 34 34 xff08 类成员访问运算符 xff09 34 34 xff08 类成员指针访问运算符 xff09 34 34
  • 容器学习历程——容器适配器

    容器适配器 stack 栈 xff09 queue 队列 xff09 priority queue 优先队列 xff09 stack 栈 xff09 FILO 先进后出 xff09 底层通过deque实现 span class token
  • 坐标位置实时显示

    MFC程序实时显示鼠标坐标位置 在MFC单文档中快速实现坐标点附上代码 xff1a span class token keyword void span span class token class name CVoronoi2View s
  • ABAQUS自定义载荷分布

    ABAQUS自定义载荷分布 用abaqus进行模拟足底压力时遇到了一个问题 xff0c 足底压力传感器测出来的数据每块区域的数值都不同 xff0c 如果对每块区域都一个个选中然后赋值那效率太低太低了 xff0c 若是直接选中某块区域 xff
  • 域控之DNS转发器

    系统环境 xff1a Windows Server 2012 R2 Datacenter 现象 xff1a 将域环境中的主机的DNS服务器地址指向网关时 xff0c 访问外网正常 xff1b 将DNS服务器地址指向指向域控后 xff0c 可
  • cmd 运行main函数

    C m a k e Cmake C m a k e 文件大多数由控制台程序运行 xff0c 由于
  • 入栈,出栈顺序

    入栈 xff0c 出栈顺序 在刚开始做到栈的出栈入栈时还是蛮有疑惑的 xff0c 搞不清楚出入栈的排序重新整理之后终于明白 xff0c 具体如下所示 xff1a 例如有一个为 A B C D E
  • MFC键盘交互

    MFC键盘交互 首先设置键盘按键消息响应 span class token keyword void span span class token class name CFeatureReuseView span span class to
  • 手撕字符串函数

    实现 s t r c p y strcpy s t r c p y 函数 span class token key span
  • 牛客编程输入输出

    牛客笔试编程输入输出 首先需要把该包含的头文件包含进来 结构类型类似于 span class token macro property span class token directive hash span span class toke
  • VS检查内存泄露的方法

    Visual Studio检查内存泄露方法 CrtDumpMemoryLeaks函数Visual Leak Detector xff08 VLD xff09 插件VS2015内存快照 CrtDumpMemoryLeaks函数 系统自带的 C
  • 计算机图形学中的渲染管线

    渲染管线 具体流程图顶点着色器光栅化片段着色器测试混合阶段 具体流程图 步骤 xff1a 1 首先输入了1 xff0c 2 xff0c 3 xff0c 4四个顶点的数据 2 Vertex Processing 经过变换 投影等操作 xff0
  • 计算机图形学中的几何

    计算机图形学中的几何 几何表示方法1 显示表示1 1 显示几何 Explicit Representations 2 隐式表示 几何表示方法 1 显示表示 理解为能够通过参数映射的方法来定义几何形状 xff0c 可以很轻易的采样到所有的点
  • 计算机图形学中的曲线曲面

    计算机图形学中的曲线曲面 1 曲线1 1 Bezier curves xff08 贝塞尔曲线 xff09 1 2 B spline B样条 1 3 NURBS 非均匀有理B样条 xff09 2 曲面2 1 Bezier Surfaces x
  • Docker停电事件未解之谜

    事件简介 xff1a 周末出现了一次偶然的停电事故 xff0c 供电恢复后 xff0c 按照惯例重启服务器 xff0c 并重新运行各项服务 然而 xff0c 一台Ubuntu 16 04服务器的Docker容器无法启动了 1 启动容器报错
  • 布尔运算(Boolean Operators)

    布尔操作 xff08 Boolean Operators xff09 1 构造实体几何 CSG 2 布尔操作类型3 布尔操作部分代码 1 构造实体几何 CSG 构造实体几何允许建模者通过使用布尔运算符组合更简单的对象来创建复杂的曲面或对象
  • 八叉树的相关内容

    根据点云数据构建八叉树 span class token macro property span class token directive hash span span class token directive keyword prag
  • VS+git+CMake实现代码运行

    git 43 CMake实现代码运行 1 获取 github 仓库中的代码2 CMake 基本步骤3 CMake 遇到问题1 没提供xxx cmake 在路径中 4 ALL BUILD ZERO CHECK INSTALL 1 获取 git
  • CPU和GPU及CUDA入门基础概念

    CPU与GPU 1 CPU与GPU的关系 smile 1 1 CPU与GPU各自特点 2 一些零碎的CUDA入门知识 blush 2 1 函数修饰符2 2 线程 线程快 线程格2 3 什么是核函数 smiley 2 4 常用的GPU内存函数
  • 原始三维格子点内部实现小范围格子重建

    在原始N M的数组A中 xff08 该数组可以理解为规则格子 xff0c 各维度的增量均为常数 xff09 内部构建一个比其小的数组B xff0c 要求数组B与A格子点重合 xff0c 如图所示 xff1a 对于三维空间的数组来讲 xff0

随机推荐

  • csdn Markdown样式

    CSDN markdown样式 1 文字样式2 段落格式3 图片样式4 公式样式5 分享一些表情 1 文字样式 x1f449 字体样式 span class token operator lt span font span class to
  • Java入门基础知识

    JAVA基础知识记录 1 基础内容2 相关知识链接 写在最前面 xff1a 之前自学Java用的是 Eclipse 1 基础内容 常量 final相当于c 43 43 中的const 数组 int number 61 new int 100
  • 最全计算机图形学面试资料整理

    计算机图形学面试资料整理 1 什么是渲染管线2 有那几个坐标系 xff08 空间 xff09 xff1f 如何在空间之间进行转换 xff1f 3 三个重要的空间变换矩阵4 视口变换是什么 xff1f 5 顶点缓冲对象 xff08 Verte
  • OpenGL状态机

    OpenGL状态机 1 什么是状态机 xff1f 2 OpenGL状态机 1 什么是状态机 xff1f 先来解释什么是 状态 State 现实事物是有不同状态的 xff0c 例如一个自动门 xff0c 就有 open 和 closed 两种
  • OpenGL窗口实现

    OpenGL窗口实现 1 渲染循环包括的代码 xff1a 2 完整代码及解释3 实现的结果 1 渲染循环包括的代码 xff1a span class token comment 渲染循环 span span class token keyw
  • ubuntu安装nvidia显卡驱动

    系统环境 ubuntu 16 04 一 设定ubuntu的root密码 1 ubuntu默认root密码 在安装ubuntu操作系统时 xff0c 需要配置用于登录系统的用户名和密码 xff0c 却没有提示配置root密码 ubuntu默认
  • OpenGL绘制三角形

    OpenGL绘制三角形 1 可编程渲染管线2 标准化设备坐标 Normalized Device Coordinates 3 三角形顶点数据输入4 顶点着色器 Vertex Shader 编译顶点着色器 5 片段着色器 Fragment S
  • 多个着色器与多个VAO,VBO绘制三角形

    多个着色器与多个VAO VBO绘制三角形 设置不同片段着色器绘制两个三角形设置多个不同片段着色器绘制三个三角形 写在最前面 xff1a 如果对一个三角形的绘制过程还不明白建议先去看看 x1f449 这篇文章 设置不同片段着色器绘制两个三角形
  • OpenGL可编程着色器

    OpenGL着色器 1 什么是着色器2 着色器语言 xff08 GLSL xff09 2 1 数据类型2 2 着色器的输入与输出 3 Uniform3 1 绘制一个插值渐变三角形3 2 插值渐变三角形实现代码 xff1a 4 我们自己的着色
  • OpenGL纹理贴图

    OpenGL纹理 1 基本概念2 纹理环绕方式3 纹理过滤3 1 GL NEAREST3 2 GL LINEAR3 3 多级渐远纹理 Mipmap 4 纹理加载与创建4 1 纹理加载4 2 纹理创建 4 3 纹理的使用 1 基本概念 纹理是
  • OpenGL纹理叠加

    OpenGL纹理叠加 1 纹理贴图的实现2 纹理单元 在 OpenGL纹理贴图的基础上继续深入学习纹理相关内容 xff0c 本篇文章的主要目的是为了实现OpenGL纹理叠加 xff0c 需要引入 纹理单元的相关概念 1 纹理贴图的实现 按照
  • OpenGL中的变换

    OpenGL中的变换 1 矩阵变换1 1 缩放1 2 平移1 3 旋转1 4 矩阵组合 2 案例实现2 1 缩放 xff1a 2 1 1 等比缩放2 1 2 不等比缩放2 1 3 镜像X方向2 1 4 镜像Y方向 2 2 平移2 2 1 动
  • OpenGL坐标变换

    OpenGL坐标变换 1 坐标系统间的变换1 1 局部空间1 2 世界空间1 3 观察空间裁剪空间1 4 屏幕空间1 5 变换矩阵的组合 2 实现3 渲染部分代码 1 坐标系统间的变换 在渲染管线中 xff0c 物体的顶点在最终转化为屏幕坐
  • OpenGL立方体纹理贴图

    OpenGL正方体纹理贴图 0 写在最前面1 正方体顶点属性构建2 绑定多个VAO VBO3 创建多个纹理4 渲染循环5 实现代码6 多个立方体纹理贴图 0 写在最前面 要实现本篇的内容 xff0c 建议先学习下以下内容 x1f449 多个
  • OpenGL摄像机(Look At矩阵)

    OpenGL摄像机 1 摄像机 观察空间2 Look At3 lookAt 矩阵案例 1 摄像机 观察空间 观察矩阵将所有的世界坐标变换为相对于摄像机位置与方向的观察坐标 当定义一个摄像机时需要它在世界空间中的位置 观察的方向 一个指向它右
  • OpenGL摄像机键盘交互

    摄像机交互 对于摄像机基础实现内容较为生疏的可以参考该文章 x1f449 摄像机lookAt矩阵实现 考虑键盘交互实现opengl摄像机绕着目标物体自由移动 xff0c 首先需要设置一个摄像机系统 xff0c 定义lookAt函数变量 gl
  • Docker迁移以及环境变量问题

    问题一描述 将docker容器通过docker export命令打包 xff0c 传输到另外的服务器 xff0c 再通过docker import命令导入后 xff0c 发现原来docker容器中的环境变量失效了 解决方案 1 无效方案 直
  • OpenGL鼠标视角交互

    OpenGL鼠标视角交互 1 欧拉角2 鼠标输入 1 欧拉角 欧拉角 Euler Angle 是可以表示3D空间中任何旋转的3个值 xff0c 一共有3种欧拉角 xff1a 俯仰角 Pitch 偏航角 Yaw 和滚转角 Roll xff0c
  • 二维数组快速排序sort

    二维数组快速排序sort 1 使用比较函数cmp2 使用lambda表达式 使用c 43 43 的快排函数需要包含头文件 include lt algorithm gt 1 使用比较函数cmp span class token macro
  • OpenGL光照之颜色

    OpenGL光照之颜色 颜色什么是颜色如何表示物体颜色 光照场景的搭建 颜色 什么是颜色 颜色是通过眼 脑和我们的生活经验所产生的一种对光的视觉效应 xff0c 我们肉眼所见到的光线 xff0c 是由频率范围很窄的电磁波产生的 xff0c