我正在尝试使用GL_FRAMEBUFFER_SRGB将sRGB空间值写入帧缓冲区,但是我发现glEnable(GL_FRAMEBUFFER_SRGB)的调用仅适用于前/后缓冲区,不适用于从纹理创建的其他帧缓冲区。

我的管道是这样的:


首先是场景阶段,将场景渲染到GL_RGB10_A2缓冲区;
然后是渲染到GL_RGB8(0x8051)缓冲区的后期处理阶段,
最终渲染到Front / Back缓冲区的后处理链。


我尝试在每个阶段执行glEnable(GL_FRAMEBUFFER_SRGB)。由于所有渲染缓冲区均不是sRGB格式,因此下一阶段也不会自动进行任何sRGB到线性的转换,并且我也不会在着色器中进行任何转换,因此我应该期望最终结果会变得非常明亮,因为多个线性-到sRGB的转换。但它仅适用于渲染到Front / Back缓冲区的最后一个阶段,因此最终结果不会变得非常明亮。

我尝试了几种其他格式的渲染缓冲区(GL_RGB8,GL_RGBA8,GL_SRGB8_ALPHA8),但仍然无法正常工作。

我是否错过了规范中的某些内容?使用GTX750和Win7上的最新驱动程序。

最佳答案

首先OpenGL 4.6 Core Profile规范说的是(强调我的):


  第17.3.6.1节混合方程式
  
  如果启用了FRAMEBUFFER_SRGB,并且与目标缓冲区相对应的帧缓冲区附件的FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING的值为SRGB(请参阅第9.2.3节),则R,G和B目标颜色值(从定点转换为浮点后)被认为是针对sRGB颜色空间进行编码的,因此在将其用于混合之前必须进行线性化。每个R,G和B分量均以第8.24节中针对sRGB纹理分量所述的相同方式进行转换。
  
  如果禁用FRAMEBUFFER_SRGB或FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING的值不是SRGB,则不执行线性化。
  
  将所得的线性化R,G和B以及未修改的A值重新组合为混合计算中使用的目标颜色。表17.1提供了相应的每个组件
  
  17.3.7 sRGB转换(混合后发生)
  
  如果启用FRAMEBUFFER_SRGB且与目标缓冲区相对应的帧缓冲区附件的FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING的值为SRGB(请参阅第9.2.3节),则混合后的R,G和B值将通过计算转换为非线性sRGB色彩空间[cs = sRGB(cl)]其中cl是R,G或B元素,而cs是结果(有效转换为sRGB色彩空间)。
  
  如果禁用FRAMEBUFFER_SRGB或FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING的值不是SRGB,则cs = cl。 R,G和B的结果cs值以及未修改的A形成新的RGBA颜色值。


关于您的情况,有两件事对我而言很突出:


检查GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING的值
仅当启用混合后,该过程的一部分才会发生。


OpenGL的sRGB支持的主要目的是能够输出sRGB颜色,并使它们在线性空间中正确混合。

10-07 21:36