相关疑难解决方法(0)

我是否需要在现代计算机/显示器上对最终颜色输出进行伽玛校正

我一直假设我的伽马校正管道应该如下:

  • 对于(GL_SRGB8_ALPHA8)中加载的所有纹理使用sRGB格式,因为所有艺术程序都会对其文件进行预伽玛校正.从GL_SRGB8_ALPHA8着色器中的纹理采样时,OpenGL将自动转换为线性空间.
  • 在线性空间中进行所有照明计算,后期处理等.
  • 写入将在屏幕上显示的最终颜色时转换回sRGB空间.

请注意,在我的情况下,最终的颜色写入涉及我从FBO(线性RGB纹理)写入后缓冲区.

我的假设受到挑战,好像我在最后阶段进行了伽马校正,我的颜色比它们应该更亮.我设立了由我的价值灯光绘制纯色{255,106,0},但是当我使我得到的{255,171,0}(由打印筛选和颜色采摘确定).而不是橙色我变黄了.如果我没有在最后一步Gamma校正我得到完全相同的{255,权值106,0}.

根据一些资源,现代液晶屏幕模仿CRT伽玛.他们总是吗?如果没有,我怎么知道我是否应该伽马正确?我在其他地方出错了吗?


编辑1

我现在已经注意到,即使我用光写的颜色是正确的,我使用纹理颜色的地方也不正确(但是如果没有伽马校正,我的预期会更暗).我不知道这种差异来自何处.


编辑2

在尝试GL_RGBA8我的纹理而不是之后GL_SRGB8_ALPHA8,即使在光照计算中使用纹理值(如果我将光的强度减半,输出颜色值减半),一切看起来都很完美.

我的代码不再考虑任何地方的伽玛校正,我的输出看起来正确.

这让我更加困惑,不再需要/使用伽玛校正?


编辑3 - 响应datenwolf的回答

经过一些实验后,我对这里的几点感到困惑.

1 - 大多数图像格式都是非线性存储的(在sRGB空间中)

我加载了一些图像(在我的例子中是.png和.bmp图像)并检查了原始二进制数据.在我看来,好像图像实际上是在RGB颜色空间中,就好像我将像素值与图像编辑程序与我在程序中得到的字节数组进行比较,它们完美匹配.由于我的图像编辑器给了我RGB值,这表示存储在RGB中的图像.

我正在使用stb_image.h/.c来加载我的图像并一直加载.png并且没有看到加载时伽玛校正图像的任何地方.我还在十六进制编辑器中检查了.bmps,并且磁盘上的值与它们匹配.

如果这些图像实际存储在线性RGB空间的磁盘上,我应该如何(以编程方式)知道何时指定图像是在sRGB空间中?是否有某种方法可以查询更具特色的图像加载器可能提供的内容?或者由图像创建者来保存他们的图像作为伽马校正(或不校正) - 意味着建立一个约定并遵循它给定一个项目.我问了几位艺术家,他们都不知道伽马校正是什么.

如果我指定我的图像是sRGB,它们太暗了,除非我最后进行伽马校正(如果监视器使用sRGB输出,这是可以理解的,但请参见第2点).

2 - "在大多数计算机上,有效扫描输出LUT是线性的!这意味着什么?"

我不确定我能在你的回复中找到这个想法的结果.

据我所知,经过实验,我测试了所有显示器的输出线性值.如果我绘制全屏四边形并在着色器中使用硬编码值对其进行着色而不进行伽马校正,则显示器会显示我指定的正确值.

我从你的回答和我的结果中引用的句子会让我相信现代监视器输出线性值(即不模仿CRT伽玛).

我们的应用程序的目标平台是PC.对于这个平台(不包括带有CRT或真正旧显示器的人),对#1做出任何响应都是合理的,然后对#2进行伽马校正(即不执行最终的RGB-> sRGB转换 - 手动或使用GL_FRAMEBUFFER_SRGB)?

如果是这样的话,那GL_FRAMEBUFFER_SRGB的平台是什么(或者今天有效使用它的平台),或者是使用线性RGB的监视器真的那么新(假设GL_FRAMEBUFFER_SRGB是2008年推出的那样)?

-

我和我学校的其他一些图形开发人员谈过,并且从它的声音来看,他们都没有考虑伽马校正,他们没有注意到任何不正确的事情(有些人甚至都没有意识到).一个开发人员特别说他在考虑伽玛时得到了不正确的结果,因此他决定不担心伽玛.鉴于我在线/看到我的项目时出现的信息存在冲突,我不确定在我的目标平台项目中该怎么做.


编辑4 - 响应datenwolf的更新答案

确实是的.如果在信号链中的某处应用了非线性变换,但是所有像素值都未从图像中修改为显示,则该非线性已经预先应用于图像的像素值.这意味着,图像已经处于非线性色彩空间中.

如果我正在检查显示器上的图像,您的回答对我来说是有意义的.可以肯定我是清楚的,当我说我正在研究该图像的字节数组,我的意思是我正在研究在内存中数值的纹理,而不是屏幕上的图像输出(我没有为点#做2) .对我来说,唯一可以看到你说的是真实的方式就是图像编辑器给我的sRGB空间值.

另请注意,我确实尝试检查显示器上的输出,以及修改纹理颜色(例如,除以一半或加倍),输出显示正确(使用我在下面描述的方法测量).

你是如何测量信号响应的? …

opengl graphics rendering gamma

21
推荐指数
1
解决办法
5967
查看次数

Gamma校正看起来没有正确校正,这是线性的吗?

我想对我的OpenGL光源实现伽马校正,但是应用了伽马校正后,我的结果看起来根本不是线性的.

我还发现OpenGL:Gamma校正的图像看起来不是线性的,这与我的问题非常相似,但还没有得到答案,也没有讨论实际的漫射光.

作为一个例子,我在线性空间中定义了以下4种浅色:

glm::vec3 lightColors[] = {
    glm::vec3(0.25),
    glm::vec3(0.50),
    glm::vec3(0.75),
    glm::vec3(1.00)
};
Run Code Online (Sandbox Code Playgroud)

将每个光源分开,并将基本线性衰减应用于漫射照明方程式,得到以下结果:

错误的伽马

这是片段着色器:

void main()
{           
    vec3 lighting = vec3(0.0);
    for(int i = 0; i < 4; ++i)
        lighting += Diffuse(normalize(fs_in.Normal), fs_in.FragPos, lightPositions[i], lightColors[i]);
    // lighting = pow(lighting, vec3(1.0/2.2));
    FragColor = vec4(lighting, 1.0f);
}
Run Code Online (Sandbox Code Playgroud)

我不仅几乎看不到伽马校正灯的亮度差异,衰减也会因伽马校正而失真.就我的理解而言,所有计算(包括衰减)都是在线性空间中完成的,并且通过校正伽玛,监视器应该正确地显示它(因为它再次将其校正为输出).仅根据灯光颜色,最右边的圆圈应该是左圆圈的4倍,亮度是第二个圆圈的两倍,实际上并非如此.

只是因为我不够灵敏,无法察觉到正确的亮度差异或者是错误的吗?

我试过的其他东西只是将精确的光色输出到默认的帧缓冲区而没有和使用伽马校正.

伽玛输出

左是未校正的,右边是伽马校正; 红色数字表示Photoshop的颜色选择器的RGB强度.我知道Photoshop RGB值不代表最终输出图像(因为Photoshop不会将RGB值读取为监视器输出).直觉上左图像似乎更好,但根据RGB强度值,我说最右边的图像确实是由我的片段着色器正确地进行了伽马校正; 因为这些强度中的每一个都会通过监视器并以正确的强度进入我的眼睛.例如,作为0.88伽马校正的0.75强度变为0.88 ^ 2.2 = 0.75作为监视器的输出.

正确的形象是否确实正确?而且,与其他图像相比,实际照明怎么样?

c++ opengl lighting gamma glsl

3
推荐指数
1
解决办法
797
查看次数

标签 统计

gamma ×2

opengl ×2

c++ ×1

glsl ×1

graphics ×1

lighting ×1

rendering ×1