何时调用 glEnable(GL_FRAMEBUFFER_SRGB)? [英] When to call glEnable(GL_FRAMEBUFFER_SRGB)?

查看:28
本文介绍了何时调用 glEnable(GL_FRAMEBUFFER_SRGB)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个渲染系统,在该系统中我使用多采样渲染缓冲区绘制到 FBO,然后将其 blit 到另一个带有纹理的 FBO 以解析样本,以便在绘制到时读取纹理以执行后处理着色后台缓冲区(FBO 索引 0).

I have a rendering system where I draw to an FBO with a multisampled renderbuffer, then blit it to another FBO with a texture in order to resolve the samples in order to read off the texture to perform post-processing shading while drawing to the backbuffer (FBO index 0).

现在我想获得一些正确的 sRGB 输出......问题是程序的行为在我在 OS X 和 Windows 上运行它时相当不一致,这也取决于机器:在 Windows 上Intel HD 3000 它不会应用 sRGB 非线性,但在我的另一台带有 Nvidia GTX 670 的机器上它会应用.在 OS X 中的 Intel HD 3000 上,它也将应用它.

Now I'd like to get some correct sRGB output... The problem is the behavior of the program is rather inconsistent between when I run it on OS X and Windows and this also changes depending on the machine: On Windows with the Intel HD 3000 it will not apply the sRGB nonlinearity but on my other machine with a Nvidia GTX 670 it does. On the Intel HD 3000 in OS X it will also apply it.

所以这可能意味着我没有在程序的正确位置设置我的 GL_FRAMEBUFFER_SRGB 启用状态.但是,我似乎找不到任何实际告诉我何时应该启用它的教程,他们只提到它非常简单并且没有性能成本.

So this probably means that I'm not setting my GL_FRAMEBUFFER_SRGB enable state at the right points in the program. However I can't seem to find any tutorials that actually tell me when I ought to enable it, they only ever mention that it's dead easy and comes at no performance cost.

我目前没有加载任何纹理,所以我还没有需要处理它们的颜色的线性化.

I am currently not loading in any textures so I haven't had a need to deal with linearizing their colors yet.

为了强制程序不简单地吐出线性颜色值,我所尝试的只是注释掉我的 glDisable(GL_FRAMEBUFFER_SRGB) 行,这实际上意味着该设置已为整个管道,实际上我在每一帧上都冗余地强制它返回.

To force the program to not simply spit back out the linear color values, what I have tried is simply comment out my glDisable(GL_FRAMEBUFFER_SRGB) line, which effectively means this setting is enabled for the entire pipeline, and I actually redundantly force it back on every frame.

我不知道这是否正确.它确实对颜色应用了非线性,但我不知道这是否应用了两次(这会很糟糕).它可以在我渲染到我的第一个 FBO 时应用 gamma.当我将第一个 FBO 传送到第二个 FBO 时,它可以做到.为什么不?

I don't know if this is correct or not. It certainly does apply a nonlinearization to the colors but I can't tell if this is getting applied twice (which would be bad). It could apply the gamma as I render to my first FBO. It could do it when I blit the first FBO to the second FBO. Why not?

我已经拍摄了最后一帧的屏幕截图,并将原始像素颜色值与我在程序中设置的颜色进行了比较:

I've gone so far as to take screen shots of my final frame and compare raw pixel color values to the colors I set them to in the program:

我将输入颜色设置为 RGB(1,2,3),输出为 RGB(13,22,28).

I set the input color to RGB(1,2,3) and the output is RGB(13,22,28).

这在低端似乎有相当多的颜色压缩,这让我怀疑伽马是否被多次应用.

That seems like quite a lot of color compression at the low end and leads me to question if the gamma is getting applied multiple times.

我刚刚完成了 sRGB 方程,我可以验证转换似乎只应用一次,因为线性 1/255、2/255 和 3/255 确实映射到 sRGB 13/255、22/255 和 28/255 使用等式 1.055*C^(1/2.4)+0.055.鉴于这些低颜色值的扩展如此之大,如果多次应用 sRGB 颜色变换,那真的应该很明显.

I have just now gone through the sRGB equation and I can verify that the conversion seems to be only applied once as linear 1/255, 2/255, and 3/255 do indeed map to sRGB 13/255, 22/255, and 28/255 using the equation 1.055*C^(1/2.4)+0.055. Given that the expansion is so large for these low color values it really should be obvious if the sRGB color transform is getting applied more than once.

所以,我还没有确定正确的做法是什么.glEnable(GL_FRAMEBUFFER_SRGB) 是否仅适用于最终的帧缓冲区值,在这种情况下,我可以在 GL init 例程中设置它并在以后忘记它?

So, I still haven't determined what the right thing to do is. does glEnable(GL_FRAMEBUFFER_SRGB) only apply to the final framebuffer values, in which case I can just set this during my GL init routine and forget about it hereafter?

推荐答案

GL_FRAMEBUFFER_SRGB 启用时,所有写入带有 sRGB 图像格式 将假定输入颜色(正在写入的颜色)在线性颜色空间中.因此,它会将它们转换为 sRGB 色彩空间.

When GL_FRAMEBUFFER_SRGB is enabled, all writes to an image with an sRGB image format will assume that the input colors (the colors being written) are in a linear colorspace. Therefore, it will convert them to the sRGB colorspace.

sRGB 格式图像的任何写入都不应受到影响.因此,如果您正在写入浮点图像,则不会发生任何事情.因此,您应该能够打开它并保持这种状态;OpenGL 会知道您何时渲染到 sRGB 帧缓冲区.

Any writes to images that are not in the sRGB format should not be affected. So if you're writing to a floating-point image, nothing should happen. Thus, you should be able to just turn it on and leave it that way; OpenGL will know when you're rendering to an sRGB framebuffer.

通常,您希望尽可能长时间地在线性色彩空间中工作.只有在后期处理后的最终渲染才应涉及 sRGB 色彩空间.因此,您的多重采样帧缓冲区可能应该保持线性(尽管您应该为其颜色提供更高的分辨率以保持准确性.使用 GL_RGB10_A2GL_R11F_G11F_B10FGL_RGBA16F> 作为最后的手段).

In general, you want to work in a linear colorspace for as long as possible. Only your final render, after post-processing, should involve the sRGB colorspace. So your multisampled framebuffer should probably remain linear (though you should give it higher resolution for its colors to preserve accuracy. Use GL_RGB10_A2, GL_R11F_G11F_B10F, or GL_RGBA16F as a last resort).

至于这个:

在带有 Intel HD 3000 的 Windows 上,它不会应用 sRGB 非线性

On Windows with the Intel HD 3000 it will not apply the sRGB nonlinearity

这几乎可以肯定是由于英特尔在编写 OpenGL 驱动程序方面做得很烂.如果在您启用 GL_FRAMEBUFFER_SRGB 时它没有做正确的事情,那是因为英特尔,而不是您的代码.

That is almost certainly due to Intel sucking at writing OpenGL drivers. If it's not doing the right thing when you enable GL_FRAMEBUFFER_SRGB, that's because of Intel, not your code.

当然,也可能是 Intel 的驱动程序一开始没有为您提供 sRGB 图像(如果您要渲染到默认的帧缓冲区).

Of course, it may also be that Intel's drivers didn't give you an sRGB image to begin with (if you're rendering to the default framebuffer).

这篇关于何时调用 glEnable(GL_FRAMEBUFFER_SRGB)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆