sRGB FBO渲染到纹理



在我的渲染器中,我在多采样FBO上生成一个抗锯齿场景,该场景被闪电传输到颜色附件为纹理的FBO。然后在渲染到帧缓冲区时读取纹理。

我想更新它,这样我就可以得到伽马校正的结果。使用sRGB帧缓冲区的好处是,通过将非线性sRGB值直接存储在帧缓冲区中,我可以获得更好的颜色精度。

我不确定的是我应该做什么改变才能得到这个,以及不同的设置改变了什么。

看起来扩展ARB_framebuffer_sRGB只是处理sRGB帧缓冲区的读取和混合操作。在我的情况下,我需要使用一个指定sRGB表示类型的纹理,这意味着我将使用扩展EXT_texture_sRGB。。。使用线性纹理格式将禁用sRGB转换。

编辑:但我刚刚看到这个:

3) 是否应支持sRGB帧缓冲区更新和混合是帧缓冲区的属性吗?

决议:是的。它应该是一些像素格式的功能(很可能只有RGB8和RGBA8),表示sRGB混合可以启用。

这允许实现简单地标记现有的RGB8和RGBA8像素格式,支持sRGB混合,然后只需为这样的格式。

现在我不太确定该为纹理的像素格式指定什么。

好吧,那么渲染缓冲区呢?framebuffer_sRGB文档没有提及任何关于renderbuffers的内容。有没有可能将glRenderbufferStorageMultisample与sRGB格式一起使用,这样我就可以获得支持sRGB存储的混合?

此外,在指定glTexImage2D的内部格式时,GL_SRGB_ALPHAGL_SRGB8_ALPHA8之间有什么区别?

我不确定的是我应该做什么改变才能得到这个

这是因为你的问题似乎不确定你想做什么

所有这些东西的关键是在任何时候都知道你的输入数据是什么,你的输出数据是什么

您的第一步是了解每个纹理中存储的内容。特定纹理存储线性数据还是sRGB颜色空间中的数据?如果它存储线性数据,则使用其中一种线性图像格式。如果它存储sRGB颜色空间数据,则使用sRGB图像格式之一。

这样可以确保在着色器中获取所需的数据。当需要将它们写入/混合到帧缓冲区时,您现在需要决定如何处理。

您的屏幕需要已预伽玛校正为显示设备伽玛的值。因此,如果提供线性值,则会得到不正确的颜色输出。

但是,有时,您希望写入中间值。例如,如果正在进行正向或延迟渲染,则将累积照明写入浮点缓冲区,然后使用HDR色调映射将其简化为[0,1]图像以进行显示。可以再次使用后处理技术。只有[0,1]的输出需要是sRGB颜色空间中的图像。

在写入要转换为sRGB的线性RGB值时,必须启用GL_FRAMEBUFFER_SRGB。这是一个特殊的启用(请注意,纹理无法关闭sRGB解码),因为有时,您希望写入已经在sRGB中的值。GUI界面小部件通常是这样的,它们是使用sRGB颜色空间中已经存在的颜色设计和构建的。

在我的系列教程中,我介绍了与编写gamma正确值和从纹理中读取值有关的问题。第一个解释了为什么gamma很重要,并在着色器中显式地进行gamma校正。第二个链接介绍了如何在纹理和帧缓冲区中使用sRGB图像。

好吧,那么渲染缓冲区呢?framebuffer_sRGB文档没有提及任何关于renderbuffers的内容。

为什么会这样?ARB_framebuffer_sRGB只对帧缓冲区和其中图像的性质感兴趣。它既不知道也不关心这些图像来自哪里。它不在乎它是在谈论默认的帧缓冲区、附加到FBO的纹理、附加到FB的渲染缓冲区,还是明天有人提出的全新东西。

扩展说明当目标图像在sRGB颜色空间中以及启用GL_FRAMEBUFFER_SRGB时会发生什么。这个图像来自哪里取决于你。

此外,在指定glTexImage2D的内部格式时,GL_SRGB_ALPHA和GL_SRGB8_ALPHA8之间有什么区别?

一个是大小。另一个不是。理论上,GL_SRGB_ALPHA可以为您提供实现所需的任何比特深度。它可以为每个组件提供2位。你给了实现自由选择它想要的东西。

在实践中,我怀疑你会发现不同。也就是说,总是尽可能使用大小的内部格式。明确你想要什么是好的,并防止实现做一些愚蠢的事情。OpenGL甚至有一些需要明确支持的大小格式。

最新更新