我有一个小样本es-300-fbo-srgb,应该展示如何在 opengl es3 中管理伽马校正。
基本上我有:
GL_SRGB8_ALPHA8
纹理_TEXTURE_DIFFUSE
- 一个带有另一个
GL_SRGB8_ALPHA8
纹理GL_COLOR_ATTACHMENT0
和一个GL_DEPTH_COMPONENT24
纹理的帧缓冲区GL_DEPTH_ATTACHMENT
- 我的默认 fbo 的后台缓冲区是
GL_LINEAR
GL_FRAMEBUFFER_SRGB
最初禁用。
现在,如果我回顾一下display
方法,这就是我要做的:
我
TEXTURE_DIFFUSE
在 sRGB fbo 上渲染纹理,由于源纹理位于 sRGB 空间中,我的片段着色器将自动读取线性值并将其写入 fbo。Fbo 现在应该包含线性值,虽然它是 sRGB,因为GL_FRAMEBUFFER_SRGB
被禁用,所以没有执行线性->sRGB 转换。我将 fbo 的内容 blit 到默认的 fbo 后台缓冲区(通过程序)。但是由于这个 fbo 的纹理具有 sRGB 分量,因此在读取的值上将执行错误的 gamma 操作,因为它们被假定在 sRGB 空间中,而实际上它们不是。
当我的显示器呈现默认 fbo 的内容时,它会执行第二次伽马操作
所以我的形象是,如果我是对的,那就是错误的两倍。
现在,如果glEnable(GL_FRAMEBUFFER_SRGB);
我得到
图像看起来已经被 sRGB 校正了太多次..
相反,如果我保留GL_FRAMEBUFFER_SRGB
禁用并更改GL_COLOR_ATTACHMENT0
我的 fbo 纹理的格式,我最终会得到正确的图像..
为什么我没有得到正确的图像glEnable(GL_FRAMEBUFFER_SRGB);
?