2

在我的渲染器中,我在多重采样的 FBO 上生成了一个抗锯齿场景,该场景被 blitted 到一个颜色附件是纹理的 FBO。然后在渲染到帧缓冲区期间读取纹理。

我想更新它,以便获得伽马正确的结果。使用 sRGB 帧缓冲区的好处是,它允许我通过将非线性 sRGB 值直接存储在帧缓冲区中来获得更好的颜色精度。

我不确定的是我应该做哪些改变来获得这个,以及不同的设置会改变什么。

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

编辑:但我刚看到这个:

3) 支持 sRGB 帧缓冲区更新和混合的能力应该是帧缓冲区的一个属性吗?

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

这允许实现简单地将现有的 RGB8 和 RGBA8 像素格式标记为支持 sRGB 混合,然后只为此类格式提供 sRGB 更新和混合功能。

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

好的,那么渲染缓冲区呢?ARB_framebuffer_sRGB 文档没有提到任何关于渲染缓冲区的内容。是否可以使用glRenderbufferStorageMultisamplesRGB 格式,所以我可以获得启用 sRGB 存储的混合?

GL_SRGB_ALPHA另外,指定内部格式和GL_SRGB8_ALPHA8指定内部格式有什么区别glTexImage2D

4

1 回答 1

7

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

那是因为您的问题似乎不确定您要做什么。

所有这些东西的关键是始终知道您的输入数据是什么以及您的输出数据是什么。

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

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

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

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

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

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

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

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

扩展说明当目标图像在 sRGB 颜色空间中以及何时启用时会发生什么GL_FRAMEBUFFER_SRGB。该图像的来源取决于您。

另外,在为 glTexImage2D 指定内部格式时,GL_SRGB_ALPHA 和 GL_SRGB8_ALPHA8 有什么区别?

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

在实践中,我怀疑你会发现不同之处。话虽如此,总是尽可能使用大小的内部格式。最好具体说明您想要什么,并防止实现做一些愚蠢的事情。OpenGL 甚至有一些需要明确支持的大小格式,如所述

于 2012-02-26T22:46:45.207 回答