c++ - OpenGL: Gamma 校正后的图像看起来不是线性的

标签 c++ opengl glsl gamma srgb

我正在使用 OpenGL 进行渲染,当我将线性值写入默认帧缓冲区(没有任何 Gamma 校正)时,它们在我的显示器上显示为线性。这违背了我认为我对 Gamma 校正的了解(如此处解释:http://gamedevelopment.tutsplus.com/articles/gamma-correction-and-why-it-matters--gamedev-14466)。如果没有 Gamma 校正,我会看到我的显示器非线性地变暗中间范围的颜色。

但这是我实际看到的;首先我没有进行 Gamma 校正,然后进行 Gamma 校正: enter image description here

这是我的没有 Gamma 校正的片段着色器(在全屏四边形上绘制到默认帧缓冲区)。这导致左侧的线性图像:

out vec4 fsOut0;

void main( void )
{
    // split the screen into 10 discrete color bands
    float yResolution = 768.0;
    int intVal = int(gl_FragCoord.y / yResolution * 10.0);
    fsOut0.rgb = vec3( float(intVal) / 10.0 );

    fsOut0.a = 1.0;
}

这是添加了 Gamma 校正的着色器(从线性空间到 sRGB)。这导致右边的图像比线性图像更亮:

out vec4 fsOut0;

void main( void )
{
    // split the screen into 10 discrete color bands
    float yResolution = 768.0;
    int intVal = int(gl_FragCoord.y / yResolution * 10.0);
    fsOut0.rgb = vec3( float(intVal) / 10.0 );

    // gamma correction
    fsOut0.rgb = pow( fsOut0.rgb, vec3(1.0/2.2) );

    fsOut0.a = 1.0;
}

我只是通过观察来验证颜色是否是线性的,并使用 Photoshop 中的颜色选择器并查看色带之间 RGB 值的差异。对于线性外观图像,每种颜色之间的差异(大部分)是恒定的。

我也曾尝试请求支持 sRGB 的默认帧缓冲区。在这种情况下,写入没有 Gamma 校正的线性值看起来像第二张图像(非线性)。

我做错了什么?或者可能是我的两台显示器都校准错误并且 Photoshop 没有在线性空间中选择颜色?或者我的“非线性”图像实际上是正确的线性结果,但在我看来它似乎不是线性的?

我的问题有点重复:Do I need to gamma correct the final color output on a modern computer/monitor 不幸的是,接受的答案非常困惑,我能够遵循的部分似乎是矛盾的,或者至少没有为知识不如回答者的人完全解释。

最佳答案

嗯,你的左图和右图都符合预期。他们非常好,是的,我知道我的东西。

只是我们的眼睛也不是很线性,所以例如线性强度(发光强度)的 1/5 被认为是“白色亮度的一半”。这是您在右侧看到的,在校正后的图像中,靠近底部。

这就是首先存在 Gamma 的原因 - 通过模仿眼睛的 react 来帮助编码。 IOW, Gamma 使非线性斜坡看起来是线性的。

然而,物理上线性的斜坡(如右图)因此与被视为线性的完全相反。请记住,现实世界具有相当大的动态范围(在发光强度方面),我们的眼睛正在对此进行补偿。这让您感到困惑,但与许多其他人不同的是,您实际上得到了正确的数字。

关于c++ - OpenGL: Gamma 校正后的图像看起来不是线性的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29160601/

相关文章:

c++ - GL_QUADS 的 Opengl 纹理映射,得到奇怪的结果

c++ - 调用 QGLWidget::setFormat = 无绘图

c - 使用 glPrimitiveRestartIndex() 进行曲面 segmentation ?

c++ - 模型、 View 和投影矩阵不适用于 opengl glsl

c++ - 将 std::string_view 与需要以空字符结尾的字符串的 api 一起使用

c++ - 阿拉伯文本的 BSTR 到 CString 转换

c++ - 在远程桌面中创建 DirectX 设备失败

c++ - 基类更改后重新编译

c++ - 向不可变纹理存储提供数据

javascript - Three.js顶点着色器: update attributes and how to save a value for the next processing round