在我的渲染器中,我在多重采样的FBO上生成一个消除锯齿的场景,该场景被blit到FBO,其颜色附件是纹理.然后在渲染到帧缓冲区期间读取纹理.
我想更新它,以便我得到伽马校正结果.使用sRGB帧缓冲区的好处是,通过将非线性sRGB值直接存储在帧缓冲区中,它可以让我有更好的色彩精度.
我不确定的是我应该做些什么改变才能得到这个,以及不同设置会改变什么.
它看起来像扩展ARB_framebuffer_sRGB只是处理与sRGB帧缓冲区的读取和混合操作.在我的情况,我需要使用一个纹理指定的sRGB表示类型,这意味着我可以用扩展EXT_texture_sRGB ...使用线性纹理格式将禁用sRGB的翻译.
编辑:但我刚看到这个:
3)支持sRGB帧缓冲更新和混合的能力是否应该是帧缓冲的属性?
决议:是的.它应该是一些像素格式(很可能只是RGB8和RGBA8)的功能,可以启用sRGB混合.
这允许实现简单地将现有的RGB8和RGBA8像素格式标记为支持sRGB混合,然后仅为这些格式提供sRGB更新和混合的功能.
现在我不太确定要为纹理的像素格式指定什么.
好的,那渲染缓冲区怎么样?ARB_framebuffer_sRGB doc没有提及有关renderbuffers的任何内容.是否可以使用glRenderbufferStorageMultisamplesRGB格式,因此我可以启用sRGB存储混合?
另外,在指定内部格式时GL_SRGB_ALPHA和之间有什么区别?GL_SRGB8_ALPHA8glTexImage2D
我不确定的是我应该做些什么改变才能得到这个
那是因为你的问题似乎不确定你要做什么.
所有这些东西的关键是始终知道输入数据是什么以及输出数据是什么.
您的第一步是了解每个纹理中存储的内容.特定纹理是否存储sRGB色彩空间中的线性数据或数据?如果它存储线性数据,则使用其中一种线性图像格式.如果它存储sRGB色彩空间数据,则使用其中一种sRGB图像格式.
这可确保您在着色器中获取所需的数据.当需要将它们写入/混合到帧缓冲区时,您现在需要决定如何处理它.
您的屏幕需要经过预伽马校正的值到显示设备的伽玛值.因此,如果提供线性值,则会得到不正确的颜色输出.
但是,有时,您希望写入中间值.例如,如果您正在进行前向或延迟渲染,则会将累积的光照写入浮点缓冲区,然后使用HDR色调映射将其粗体显示为[0,1]图像.可以再次使用后处理技术.只有[0,1]的输出需要是sRGB色彩空间中的图像.
在sRGB中写入您想要的内容时,必须启用GL_FRAMEBUFFER_SRGB.这是一个特殊的启用(请注意,纹理没有办法关闭sRGB解码),因为有时候,你想要写入已经存在于sRGB中的值.这通常是GUI界面小部件的情况,这些小部件是使用sRGB颜色空间中已有的颜色设计和构建的.
我将介绍与编写伽马校正值有关的问题,并在我的教程系列中从纹理中读取它们.第一个解释了为什么伽玛是重要的并且在着色器中明确地进行伽马校正.第二个链接介绍了如何在纹理和帧缓冲区中使用sRGB图像.
好的,那渲染缓冲区怎么样?ARB_framebuffer_sRGB doc没有提及有关renderbuffers的任何内容.
为什么会这样呢?ARB_framebuffer_sRGB只对帧缓冲区及其中图像的性质感兴趣.它既不知道也不关心那些图像来自何处.它并不关心它是否正在谈论默认的帧缓冲,附加到FBO的纹理,附加到FBO的渲染缓冲区,或明天会有人提出的新东西.
扩展说明目标图像在sRGB颜色空间中以及何时启用时发生的情况GL_FRAMEBUFFER_SRGB.图像的来源取决于您.
另外,在指定glTexImage2D的内部格式时,GL_SRGB_ALPHA和GL_SRGB8_ALPHA8之间有什么区别?
一个是大小的.另一个不是.理论上,GL_SRGB_ALPHA可以给你任何想要实现的深度.它可以为每个组件提供2位.你给予实现自由选择它想要的东西.
在实践中,我怀疑你会找到差异.话虽如此,总是尽可能使用大小的内部格式.最好具体说明你想要什么,并防止实现做一些愚蠢的事情.OpenGL甚至有一些大小的格式,需要明确支持.