[openGL] 高级光照-Gamma矫正

目录

一 Gamma是什么?

二 感知光度和物理光度

2.1 与Gamma的关系

2.3 存在问题和弊端?

三 Gamma矫正(逆Gamma)

3.1 Gamma矫正的两种方法

3.2 sRGB空间

3.3 重复校正

3.3.1 在着色器中处理重复校正

3.3.2 在加载纹理时就重复校正

3.3.3 校正前后效果


 本章节Qt源码点击此处

一 Gamma是什么?

在了解Gamma之前我们应该先知道一种物理特性: 输出亮度 = 输入电压 的 2.2次方幂

  • 这是因为以前大多数的监视器是阴极射线显示器(CRT),这里后面我们就把显示器统称为监视器

这个经过2.2次方幂处理过后就相当于是一种压缩处理(可以理解为将图片变暗了至于为什么要这样处理将图片变暗,这将在后面进行说明,当然理解为压缩处理是不对的,但后面会修正。)\,每种显示设备的这个值都不一样,但是大多数都是2.2,这个2.2就叫做监视器的Gamma。

  • 经过Gamma处理过的颜色都会变暗,但只是中间的颜色,一定要理解的是,他并不会影响全暗(0),以及全亮(1)的光度。

输出亮度 = 输入电压 ^ 2.2

二 感知光度和物理光度

要知道的是无论是感知光度还是物理光度:两边的光度(最暗和最亮的)总是相同的

感知光度: 其实就是人对光的感觉

  • 因为我们人眼对比较暗的光是比较敏感的,而对亮光是不太敏感的,比如再黑暗中,稍微有点亮光我们就会感知出来,但是对于比较亮的环境中,即使增加光度
  • 这样理解:由于人眼感知对较暗的光比较敏感,所以就会给暗光分配更多的精度(暗光的变化随着值的增加不会变化的很快)。

物理光度:

  • 就是真实世界的光度,亮度的效果在0-1之间是线性增加的

在上面的图中,红色框代表的是人眼的感知光的变化,而下面的绿色框代表的是物理的真是光照。

2.1 与Gamma的关系

感知光度的形成:

对与我们输入给显示器也就是我们在程序或者应用中设置的颜色来讲,在传递给监视器后,监视器会根据自己的Gamma来进行处理,也就是对于我们设置的值0.5,他会进行Camma计算,变成0.5^2.2 = 0.218,这就会将光源变暗,从而从物理光照变成了人眼所感知的光照效果。

  • 也就是说我们本身设置的想要他显示物理真实光照,但实际上经过监视器Gamma处理后,他显示出来的光照被放暗了,
  • 颜色传递给监视器后经过监视器Gamma计算,将本该显示的物理光度(中间那条线性变化的值)压缩成凹下去的那条线的值,0.5^2.2 = 0.218。
  • 最上面凸出去的那条线暂时不用管,其实就是一个逆的Gamma操作。

2.3 存在问题和弊端?

这会导致什么问题呢? 如果我们传给监视器前的光照是基于线性空间的,也就是上图的白色虚线

那监视器的Gmama就会给他进行Gmama计算,让他变到下面红色实线(凹下去的那条线),这就导致了,中间的亮度会被变暗,

和上面的例子一样,我们观察白色虚线(线性空间 也就是我们想要设置的真实物理光度)上的0.5,他就会被压缩至0.218,从而变暗.

这种压缩只是一种幂次方比例上的压缩,只是以某种幂次方比例压缩了中间值(Gamma校验无论怎样都不会影响最小的和最大的亮度也就是0和1)

弊端:

由于所有中间的亮度都是在线性空间计算的(传递给监视器处理前) ,所以这几乎导致了我们现在所看到的光照都不在准确的(因为他会进行Gamma计算),不是真实的物理上的光度,这就会导致我们会看到物体的效果并不会很有层次感,也就是说我们会看到更多的较暗的光度,而丢失很多比较亮的光度。

三 Gamma矫正(逆Gamma)

我们这里要先熟悉一下这两个概念

逆Gamma: 将线性的空间上供为上面凸出去的非线性空间

Gamma:将线性的空间下供为下面凹下去的非线性空间

简而言之就是给传入的值做一个1/2.2的幂次方计算,把这个值先变大,然后经过Gamma就会变回正常的线性空间的值。也就是真实的物理空间的值

  • 其实Gamma矫正很简单,如果我们本身不存在监视器Gamma这个处理过程,那我们根本无需处理任何东西和计算,得到的就是真实的物理上的光度
  • 但由于有了这个监视器Gamma导致我们看到的光度比实际物理上的光度暗了,那么很简单我们只需要给这个设定的值进行 逆运算,也就是说,你监视器会把我给定的值做做幂次方压缩导致我的线性空间变成了Camma空间(也就是红色实线凹下去的那条线),那我在给监视器之前我就给让我给定的这个值去做一个逆Gamma,也就是将这个线性空间变成上面的凸出去的那条线,这样再传递给监视器的时候,经过Gamma处理,他就还是正常的线性空间的值,显示出来的也就是真实的物理世界的值。

3.1 Gamma矫正的两种方法

  • 让着色器每次运行后自动进行Gamma,这样就不需要人为处理了
glEnable(GL_FRAMEBUFFER_SRGB);
  • 我们直接再发送到帧缓冲前,在每个相关像素着色器运行的最后应用gamma校正
void main()
{float gamma = 2.2;fragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));
}

值得注意的是:我们对于Gamma的校正一定要是在最后输出的时候再进行校正,而不要在中间计算的时候就进行校正,因为中间值的一些属性:比如两个光照和的相加,混合等处理是要在线性空间计算的,这要值得注意

3.2 sRGB空间

 监视器总是按照sRGB颜色空间的规则显示颜色,我们可以这样简单的理解:

  • sRGB空间 是一个包含了预设Gamma特性的标准化颜色空间,旨在确保跨设备颜色的一致性。
  • sRGB空间中的值: 我们可以这样理解他是将线性空间中的值进行逆Gamma处理后得到凸起的那条上供的非线性空间中的值。
  • 这种值我们就不能手动在对他进行Gamma校正了。

3.3 重复校正

  • 有的设计师在设计sRGB纹理图案时,会自动的将亮度提高,然后当他经过监视器的Gamma处理之后他就会变成正常的线性空间的颜色值。但此时使用着可能并不知道,手动又给他在最后输出给监视器之前进行了一次逆Gamma,这就导致最终输出在监视器上的亮度被放亮了。所以这就需要我们在进行Gamme校正之前判断。

3.3.1 在着色器中处理重复校正

float gamma = 2.2;
vec3 diffuseColor = pow(texture(diffuse, texCoords).rgb, vec3(gamma));
// 首先调整环境光照和漫反射光照的亮度    
shaderProgramObject.setUniformValue("light.ambient",   QVector3D(0.3f, 0.3f, 0.3f));
shaderProgramObject.setUniformValue("light.diffuse",   QVector3D(0.7f, 0.7f, 0.7f));// 将漫反射光照进行Gamma处理vec3 diffuseTexColor=vec3(texture(material.texture_diffuse1,TexCoords));float gamma = 2.2;diffuseTexColor = pow(diffuseTexColor,gamma);
  • 但是为每个sRGB空间的纹理这样设置是很烦人的,

3.3.2 在加载纹理时就重复校正

OpenGL给我们提供了另一个方案来解决我们的麻烦,这就是GL_SRGB和GL_SRGB_ALPHA内部纹理格式。

如果我们在OpenGL中创建了一个纹理,把它指定为以上两种sRGB纹理格式其中之一,OpenGL将自动把颜色校正到线性空间中,这样我们所使用的所有颜色值都是在线性空间中的了。我们可以这样把一个纹理指定为一个sRGB纹理:

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

3.3.3 校正前后效果

  • 未处理重复校正前的效果:我们会发现这个亮度很高,这是因为漫反射纹理的颜色空间已经在sRGB中空间(说明他已经进行了逆Gamma处理)了,但是我们在着色器的最后又进行了一次逆Gamma处理,两次的逆Gamma处理就会导致亮度异常大。

  • 处理后的效果: 我们要注意 漫反射纹理已经在sRGB空间中了,我们在着色器最后又给他逆Gamma那肯定会异常亮
  • 并且我们要保证中间的光照计算要在线性空间中,所以我们需要在获取到漫反射纹理后,对他进行Gamma处理,把他变到线性空间中,这样保证了他后续的计算不会出问题,然后在再着色器最后输出时进行一次逆Gamma处理这样就能得到正确的颜色了。

值得注意的:

  • 不是所有的纹理都是在sRGB空间中的所有我们如果要把纹理指定为sRGB纹理时一定要注意
  • 一般像漫反射光照这种为物体上色的纹理几乎都是在sRGB空间中的
  • 但是像镜面光贴图和法线贴图几乎都在线性空间中,所以如果你把它们也配置为sRGB纹理的话,光照就会连续被衰弱两次,这样光照几乎就坏掉了

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

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

相关文章

第3关 - GoC模拟题3

GoC测试模拟题(2017.4.18)第1题:棱形(lx) 题目描述 棱形是四条边相等的四边形,但角度不确定。请编程画出如下图的边长为50,内角分别是45度和135度的棱形。 说明: 上图中红色数字是标明尺寸的,不需要画出。 输入格式…

SAM2695 法国追梦DREAM 音频DSP芯片

法国追梦/DERAM SAM5504/5704/5716/5808音频DSP芯片,开发板,方案 可用于电子鼓、电子琴、电吉他、效果器、均衡器、啸叫抑制器等电声产品领域 提供服务 全系列芯片: SAM2634 SAM2695 SAM5504B SAM5704B SAM5708B SAM5808B SAM5716B SAM5916B…

2024年五一杯数学建模C题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间:2024…

GPT国内能用吗

2022年11月,Open AI发布ChatGPT,ChatGPT展现了大型语模型在自然语言处理方面的惊人进步,其生成文本的流畅度和连贯性令人印象深刻,为AI应用打开了新的可能性。 ChatGPT的出现推动了AI技术在各个领域的应用,例如&#x…

postman汉化

一、postman历史版本下载:Postman 10.24.16 Download for Windows / Old Versions / FileHorse.comhttps://www.filehorse.com/download-postman/old-versions/ 二、汉化包下载: Releases hlmd/Postman-cn GitHubPostman汉化中文版. Contribute to h…

【详细】OSPF vs RIP

目录 内部网关协议IGP 按照算法原理分 按照适用范围分 两者优缺点比较 RIP协议 RIP的两个版本区别 RIPv2认证功能 RIP协议优缺点 RIP协议路由环路发生原理及处理方式 造成路由环路的原因: 路由环路的危害 路由环路解决方法​编辑 OSPF协议 Router-ID&a…

分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据…

为什么用云渲染农场?3D云渲染农场助力影视动画行业发展

​计算机图形技术的进步使得3D渲染成为多个产业发展的重要推动力。设计师和艺术家利用这项技术将创意实现,创造出震撼的视觉作品。但是,高质量的渲染需要大量的计算资源。云渲染农场通过提供这些资源,有效提高了渲染的速度和效率,…

8.Jetson AGX Orin Ubuntu20.04 gRPC编译安装

Jetson AGX Orin Ubuntu20.04 gRPC编译安装 一、CMake版本检查 grpc编译cmake要求最低版本为3.15。首先,cmake -version 查看当前cmake版本,如果低于3.15,按照以下步骤进行安装。 1.1 卸载已经安装的旧版的CMake sudo apt-get autoremove…

【408直通车】C+Python赋能数据结构:从底层原理到高级应用的蜕变之路——线性表

本专栏旨在通过使用C语言和Python分别实现各种考研常见数据结构,从底层原理和应用两个角度深入探索数据结构。通过深入理解数据结构的底层原理和掌握Python的高级特性,读者将能够全面掌握数据结构的知识,并且学会如何在实际应用中灵活运用。 …

网工交换技术基础——VLAN原理

1、VLAN的概念: VLAN(Virtual LAN),翻译成中文是“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。 2、VLAN的主要作用&#xf…

假期必备!一款超级强大的视频终端下载工具,简洁又强大,24.5K star【文末送福利】

马上要五一了,假期想必少不了娱乐看电影电视剧,之前介绍了 Gopeed 这个支持全平台的下载神器。 今天再给大家介绍一个超级棒的命令行下载神器项目:Lux。 项目简介 Lux是一款用 Go 语言开发的视频下载库和 ClI 工具,拥有简洁的命…

【已解决】CondaError: Downloaded bytes did not match Content-Length

😎 作者介绍:我是程序员行者孙,一个热爱分享技术的制能工人。计算机本硕,人工制能研究生。公众号:AI Sun,视频号:AI-行者Sun 🎈 本文专栏:本文收录于《AI实战中的各种bug…

springboot 人大金仓 kingbase-备份还原,命令中带密码,支持window和linux

命令带密码参考 Java代码实现国产人大金仓数据库备份还原需求-CSDN博客文章浏览阅读818次,点赞16次,收藏12次。本人在一次项目中,遇到了需要在系统管理中提供给用户备份还原系统数据的功能,由于项目特殊性,项目底层数…

vue实现文字转语音的组件,class类封装,实现项目介绍文字播放(2024-04-17)

1、项目界面截图 2、封装class类方法(实例化调用) // 语音播报的函数 export default class SpeakVoice {constructor(vm, config) {let that thisthat._vm vmthat.config {text: 春江潮水连海平,海上明月共潮生。滟滟随波千万里&#xf…

开展在即!中银富登邀您共赴雄安2024数字城市展览会(雄安建博会)

中银富登村镇银行:雄安新区金融创新的领航者 在即将举办的2024雄安数字城市建设展览会上,中银富登村镇银行将以其在金融创新和普惠金融服务领域的卓越表现,成为展会的一大亮点。作为雄安新区首家全国性银行业金融机构总部,中银富…

DolphinScheduler 调度工作流报错 Host key verification failed.

文章目录 出现问题错误原因及解决方法1.SSH 免密登录配置失败、失效2.不存在该租户 建议 出现问题 在执行调度任务时,失败了,查看日志发现错误 —— Host key verification failed. 错误原因及解决方法 1.SSH 免密登录配置失败、失效 这种情况就检查…

黄仁勋最新访谈:GPU性能的革命性提升与AI未来

近期,英伟达CEO黄仁勋与美国CNBC知名主持人、股评人吉姆克莱默(Jim Cramer)在《Mad Money》节目中展开了一场关于技术未来和人工智能的对话。访谈里,黄仁勋不仅提到了英伟达在过去八年中将AI算力性能提高1000倍,还预言…

程序中调用DB存储过程记得异常处理时尝试回滚可能存在的事务

程序中调用DB过程要注意这种情况: 有些存储过程需要执行比较久,在数据库中直接跑本身没有出错,但从程序中调用该存储过程会由于超时进入程序异常处理,这时数据库后台依然在跑着该存储过程,如果该存储过程中有启用事务…

Linux:如何删除指定时间之前修改的文件

1、与文件有关的时间 在说明如何删除符合这种要求的文件之前,先来看看与文件有关的有哪些时间 简名全名中文名含义atimeaccess time访问时间文件中的数据最后被访问的时间mtimemodify time修改时间文件中的数据最后被修改的时间ctime change time变化时间文件的元…