dede采集规则下载网站,数据分析师考试科目,兰州网站建设和维护工作,重庆seo网站设计目录
一 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是什么?
二 感知光度和物理光度
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 diffuseTexColorvec3(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纹理的话光照就会连续被衰弱两次,这样光照几乎就坏掉了。