[openGL] 高级光照-Gamma矫正与衰减

news2024/12/24 0:30:34

目录

一 衰减

二 衰减公式

三 使用场景

四 代码实现

4.1 部分代码

4.2 未校验的效果

4.3  Gamma校验后的效果

4.4 总结


本章节源码 点击此处

一 衰减

在之前平行光和投光物的部分中,了解了光源的衰减,对于平行光来说是不需要衰减的,并且在衰减时对是否衰减环境光也要做出判断,

  • 比如有多个光源时可能就需要来衰减环境光了,不然多个光源会对同一处的环境光进行叠加,导致场景过亮,这就需要人为来判断了

注意: 对于衰减我们这里要记得这一步

我们可以将环境光分量保持不变,让环境光照不会随着距离减少,但是如果我们使用多于一个的光源,所有的环境光分量将会开始叠加,所以在这种情况下我们也希望衰减环境光照。简单实验一下,看看什么才能在你的环境中效果最好。

二 衰减公式

  • 而在真实的物理世界中,光线的衰减减和光源的距离的平方成反比。
  • 但是这个衰减公式的衰减效果是很强烈的,光源可能只会照亮一小圈,看起来可能不是那么真实,当然我们依旧可以使用我们之前一种使用的衰减方程(它对衰减的控制更为准确)。但是这里只是为了说明衰减和Gamma之间的关系。

公式1:

float attenuation = 1.0 / (distance * distance);

  • 我们还可以使用下面这个公式,这个衰减效果是在距离在比较小的时候更加实用。当然这里不关系距离,只关心衰减公式和Gamma的关系

公式2:

float attenuation = 1.0 / distance;

三 使用场景

当我们在不进行Gamma校正的时候我们使用公式2看起来会更加真实

  • 因为我们不进行校正的时候,监视器本事就会进行一个2.2次方的衰弱,这看起来其实是和公式一的几乎相同的
  • 如果我们使用了公式1也就是线性衰减,但是没有进行Gamma校正,那么试想而知,这个衰减也太强烈了。被衰减方程处理过的光源将会变得非常暗。

当我们进行Gamma校正的时候公式1会得到更好的效果。

  • 因为Gamma校正后,本身就会对光源有一个增强效果,也就是之前说的逆Gamma(1.0/2,2),然后将,相当于这个校正把衰减公式给减弱了。
  • 你可以这样理解,原来的二次函数的衰减公式,被Gamma矫正之后,拉回到了一次线性的一次衰减公式。

总结: 这说明了什么,哪怕是衰减,也会被监视器Gamma影响他的值,也就是说所有的计算最好都是在颜色的线性空间中是最好的。

四 代码实现

4.1 部分代码

  • 首先准备两个纹理 一个是带Gamma校正的地面纹理,一个是不带的
m_NoGammaTex = new QOpenGLTexture(QImage(":/wood.png").mirrored());
m_planeNoGammaMesh = processMesh(planeVertices,6,m_NoGammaTex->textureId());
QImage wall = QImage(":/wood.png").convertToFormat(QImage::Format_RGB888);
m_planeTex = new QOpenGLTexture(QOpenGLTexture::Target2D);
glBindTexture(GL_TEXTURE_2D, m_planeTex->textureId());

glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, wall.width(), wall.height(),
             0, GL_RGB , GL_UNSIGNED_BYTE, wall.bits());
glGenerateMipmap(GL_TEXTURE_2D);

m_planeMesh=processMesh(planeVertices,6,m_planeTex->textureId());

  • 使用按钮控制Gamma属性
    if(blin == true)
        m_planeMesh->Draw(shaderProgramObject);
    else
        m_planeNoGammaMesh->Draw(shaderProgramObject);
  • 着色器中的代码实现
#version 330 core

struct Material {
    sampler2D texture_diffuse1;
    sampler2D texture_specular1;
    float shininess;
};

struct Light {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform Light light;


uniform Material material;
out vec4 FragColor;

in vec2 TexCoords;
in vec3 Normal;
in vec3 FragPos;

uniform vec3 viewPos;

uniform bool Gamma;

// 首先需要的是法向量 然后是顶点向量 以及光照向量 和视野向量 以及光照颜色
vec3 BlinnPhong(vec3 normal,vec3 fragPos,vec3 lightPos,vec3 lightColor)
{
    // 先进行计算漫反射 漫反射不存在BlinPhong的问题 和原来的计算方式保持一致
    // 光照的方向向量
    vec3 lightDir = normalize(lightPos - fragPos);
    // dot 用来计算两个向量之间的点积(夹角的cos值)
    float  diff = max(dot(lightDir,normal),0.0);
    vec3  diffuse = lightColor * diff;

    // 计算环境光照
    // 计算反射角 (入射角向量 乘以 法线向量) 参数不能互调
    vec3 reflectDir = reflect(-lightDir,normal);
    // 计算观察向量
    vec3 viewDir = normalize(viewPos - fragPos);
    // 计算半程向量
    vec3 hDir = normalize(viewDir + lightDir);
    // 计算镜面光
    float spec;
    spec = pow(max(dot(viewDir,lightDir),0.0f),64.0);
    vec3 specular = spec * lightColor;
    // 开始计算衰减
    // 获取光源距离
    float distance = length(lightPos - fragPos);

    // 计算衰减
    float attenuation = 1.0 / (Gamma ? distance * distance : distance);

    diffuse *= attenuation;
    specular *= attenuation;
    return diffuse + specular;
}


void main() {
    // 拿到漫反射纹理颜色
    vec3 diffuseTexColor = vec3(texture(material.texture_diffuse1,TexCoords));

    // 环境光
    vec3 ambient = light.ambient;

    // if(Gamma == true)
    // {
    //     diffuseTexColor = pow(diffuseTexColor,vec3(1.0 / 2.2));
    // }

    vec3 norm = normalize(Normal);

    vec3 result;
    for(int i = -2; i < 2; ++i){
        vec3 lightColor=(2-i)*vec3(0.25);
        result += BlinnPhong(norm,FragPos,light.position+i*vec3(2,0.0,0.0),lightColor);
    }

    if(Gamma)
        ambient = pow(ambient,vec3(2.2));
    result += ambient;
    result*=diffuseTexColor*result;
    if(Gamma) result = pow(result, vec3(1.0/2.2));
    if(gl_FrontFacing==false)
        FragColor = vec4(result, 1.0);
}
  • 上面的for循环实际是是模拟了光源位置基于x轴的变化,用这种变化,模拟出从让光源沿着x轴移动。

4.2 未校验的效果

4.3  Gamma校验后的效果

4.4 总结

未校验:

  • 对于经过Gamma校验后中间色调(尤其是暗部)实际显示出来的亮度低于它们应有的线性亮度。

校验后:

  • 图像的整体亮度相比于未校正时会显得更亮,尤其是在中间色调和暗部区域

可能你会敏锐的发现,为什么上面的图片未校验的反而更亮呢? 试想一下我们未校验使用的纹理是不是没有经过处理,也就是说他的纹理颜色是位于sRGB空间中的,而我们并没有对他进行压缩(或者说逆Gamma处理),所以它输出的肯定会更亮,如果尝试在渲染时对(校正和不校正)使用同一个纹理,那么Gamma校验后的效果肯定定更亮。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1607889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中霖教育:二建考试中六个专业分别有什么特点?

建筑实务 《建筑实务》技术部分多以选择题为主&#xff0c;主要是对各种数据的考查;管理部分以案例题为主&#xff0c;旨在考查大家的综合能力&#xff0c;也是分值占比比较多的部分。进度控制的网络图和流水施工每年必考其一;质量管理主要结合技术部分命题;安全管理和合同管理…

正式发布的Spring AI,能让Java喝上AI赛道的汤吗

作者:鱼仔 博客首页: https://codeease.top 公众号:Java鱼仔 前言 最近几年AI发展实在太快了&#xff0c;仿佛只要半年没关注&#xff0c;一个新的大模型所产生的效果就能超越你的想象。Java在AI这条路上一直没什么好的发展&#xff0c;不过Spring最近出来了一个新的模块叫做S…

高可用集群——keepalived

目录 1 高可用的概念 2 心跳监测与漂移 IP 地址 3 Keepalived服务介绍 4 Keepalived故障切换转移原理介绍 5 Keepalived 实现 Nginx 的高可用集群 5.1 项目背景 5.2 项目环境 5.3 项目部署 5.3.1 web01\web02配置&#xff1a; 5.3.2nginx负载均衡配置 5.3.3 主调度服…

全开源小狐狸Ai系统 小狐狸ai付费创作系统 ChatGPT智能机器人2.7.6免授权版

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.4、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态thinkPHP&#xff0c;开启ssl证书 具有文章改写、广告营销文案、编程…

商务品牌解决方案企业网站模板 Bootstrap5

目录 一.前言 二.展示 三.下载链接 一.前言 这个网站包含以下内容&#xff1a; 导航栏&#xff1a;主页&#xff08;Home&#xff09;、关于&#xff08;About&#xff09;、服务&#xff08;Services&#xff09;、博客&#xff08;Blog&#xff09;等页面链接。主页部分…

基于Java+SpringBoot+Vue前后端分离仓库管理系统

基于JavaSpringBootVue前后端分离仓库管理系统 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#…

【机器学习】《机器学习建模基础》笔记

文章目录 单元0 前言单元1 数学建模与机器学习学习目标&#xff08;一&#xff09;什么是模型&#xff08;二&#xff09;数学模型的分类&#xff08;三&#xff09;数学建模的一般步骤&#xff08;四&#xff09;机器学习的概念 【我选择这本书的理由】 这本书比较简单&#x…

Java八股文4

Linux篇 1.free命令-查看内存状态 free命令用于显示内存状态&#xff0c;它可以提供关于系统内存使用情况的详细信息。这个命令会显示出内存的使用情况&#xff0c;包括实体内存、虚拟的交换文件内存、共享内存区段&#xff0c;以及系统核心使用的缓冲区等。 其中&#xff0c;参…

无源光网络(PON)技术的革命:PON模块的全面解析

PON&#xff08;Passive Optical Network&#xff0c;无源光网络&#xff09;模块是一种高性能的光模块&#xff0c;用于PON系统中&#xff0c;符合ITU-T G.984.2标准和多源协议&#xff08;MSA&#xff09;。它通过不同的波长在OLT&#xff08;光线路终端&#xff09;和ONT&am…

《中学科技》是什么级别的刊物?如何投稿?

《中学科技》是什么级别的刊物&#xff1f;如何投稿&#xff1f; 《中学科技》创刊于1976年&#xff0c;由上海世纪出版&#xff08;集团&#xff09;有限公司主管&#xff0c;上海科技教育出版社有限公司主办的省级学术期刊&#xff0c;《中学科技》以传播科技知识、启迪智慧…

2024-9.python文件操作

文件操作 引言 到目前为止&#xff0c;我们做的一切操作&#xff0c;都是在内存里进行的&#xff0c;这样会有什么问题吗&#xff1f;如果一旦断电或发生意外关机了&#xff0c;那么你辛勤的工作成果将瞬间消失。是不是感觉事还挺大的呢&#xff1f;现在你是否感觉你的编程技…

集合-CollectionListSet

Collection体系的特点、使用场景总结 如果希望元素可以重复&#xff0c;又有索引&#xff0c;索引查询要快? 用ArrayList集合, 基于数组的。(用的最多) 如果希望元素可以重复&#xff0c;又有索引&#xff0c;增删首尾操作快? 用LinkedList集合, 基于链表的。 如果希望增…

64B/66B编码 自定义PHY层设计

一、前言 之前的一篇文章讲解了64B/66B的基本原理&#xff0c;本篇在基于64B/66B GT Transceiver的基础之上设计自定义PHY。基本框图如下。 二、GT Mdule GT Module就按照4个GT CHannel共享一个GT COMMON进行设置&#xff0c;如下图。要将例子工程中的GT COMMON取出&#xff…

win10 鼠标箭头自己乱动解决方案

我这里只说我碰到的然后我的解决方案&#xff0c;不一定对其他问题有效&#xff1b; 1. 首先拔掉鼠标线查看鼠标箭头是否仍然在乱动&#xff0c;如果是则非鼠标问题&#xff0c;如果不再乱动则是鼠标的问题&#xff1b;验证非鼠标问题&#xff1b; 2. 因为鼠标乱动跟鼠标无关…

Transformer杀疯了!王炸成果荣登Nature,实现无限上下文长度

继DeepMind的新设计MoD大幅提升了 Transformer 效率后&#xff0c;谷歌又双叒开始爆改了&#xff01; 与之前荣登Nature子刊的life2vec不同&#xff0c;谷歌的新成果Infini-attention机制&#xff08;无限注意力&#xff09;将压缩内存引入到传统的注意机制中&#xff0c;并在…

python--4函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归、递归练习

学习目标&#xff1a; 函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归、 递归练习 学习内容&#xff1a; 函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归、 递归练习 …

CSS中position属性总结

CSS中position属性的总结 如果我的文章看不懂&#xff0c;不要犹豫&#xff0c;请直接看阮一峰大佬写的文章 https://www.ruanyifeng.com/blog/2019/11/css-position.html 1 干嘛用的 用来定位HTML元素位置的&#xff0c;通过top、bottom、right、left定位元素 分别有这些值&a…

3D模型格式转换工具HOOPS Exchange:3D CAD数据的快速导入与导出

在当今的工程设计领域中&#xff0c;快速且可靠地处理3D CAD数据是至关重要的。HOOPS Exchange SDK通过提供一组C软件库&#xff0c;为开发团队提供了实现这一目标的有效工具。 什么是HOOPS Exchange&#xff1f; HOOPS Exchange是一组C软件库&#xff0c;旨在为开发团队提供…

DNS服务器的管理与配置

目录 一、相关知识 域名空间 DNS服务器分类 域名解析过程 资源记录 二、安装DNS服务 安装bind软件包 DNS服务的启动与停止 配置主要名称服务器 主配置文件 从例子学起&#xff1a; &#xff08;1&#xff09;建立主配置文件named.conf &#xff08;2&#xff09;…

OpenHarmony网络协议通信c-ares [交叉编译]异步解析器库

简介 c-ares是异步解析器库&#xff0c;适用于需要无阻塞地执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。 下载安装 直接在OpenHarmony-SIG仓中搜索c-ares并下载。 使用说明 以OpenHarmony 3.1 Beta的rk3568版本为例 将下载的c-ares库代码存在以下路径&#xff1a;…