我需要在片段着色器中进行输出伽玛校正吗?

Do I need output gamma correction in a fragment shader?

当我在片段着色器的 main() 函数中通过 fragColor 输出 颜色时,颜色分量强度是解释为线性 RGB 还是 sRGB ?或者换句话说,我是否必须在我的着色器中执行伽玛校正,或者这已经被处理了吗?

如果没有通用答案但取决于某些 OpenGL 属性:我该如何设置 属性?

为避免误解:各自的颜色完全由程序生成,没有纹理等(可能需要输入伽玛校正)。

每个片段着色器输出都被路由到帧缓冲区中的特定图像 (based on glDrawBuffers state)。该图像具有格式。该格式定义了相应输出的默认色彩空间解释。

因此,如果您将值写入线性 RGB 格式的图像,系统会将此值解释为线性 RGB 值。如果您在 an sRGB format 中向图像写入值,则系统会将此值解释为 已经 在 sRGB 色彩空间中。所以不会进行转换;它将被写入纹理 as-is。如果混合处于活动状态,您写入的 sRGB 值将与图像中的 sRGB 值在 sRGB 色彩空间中混合。

现在,在写入 sRGB 色彩空间图像时,您通常不希望出现这种情况。如果您有一个线性 RGB 值,您希望系统将该值转换为 sRGB 色彩空间(而不是假装它已经是)。同样重要的是,当混合处于活动状态时,您希望将 sRGB 图像中的值转换为线性 RGB,然后与片段着色器写入的线性值混合,最后转换回 sRGB。否则,混合会产生精度可疑的结果。

为了实现这一切,您 must glEnable(GL_FRAMEBUFFER_SRGB)。启用此功能后,写入色彩空间为 sRGB 的任何图像的任何片段着色器输出都会发生色彩空间转换。

默认情况下禁用此值。

因此,如果您想写入线性 RGB 值并将它们转换为 sRGB 以供显示,则您必须:

  1. 确保您写入的帧缓冲区图像使用 sRGB 色彩空间。对于 FBO,这是微不足道的。但是,如果您正在写入默认帧缓冲区,那么您必须使用 OpenGL 初始化代码来解决这个问题。

  2. 如果您希望使用色彩空间转换,请启用 GL_FRAMEBUFFER_SRGB