简体   繁体   English

什么时候调用glEnable(GL_FRAMEBUFFER_SRGB)?

[英]When to call glEnable(GL_FRAMEBUFFER_SRGB)?

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). 我有一个渲染系统,我用一个多重采样渲染缓冲区绘制到FBO,然后将其blit到另一个带有纹理的FBO,以便解析样本,以便在绘制到后缓冲区时读取纹理以执行后处理着色( FBO指数0)。

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. 现在我想获得一些正确的sRGB输出......问题是当我在OS X和Windows上运行它时,程序的行为相当不一致,这也会因机器而异:在具有Intel HD的Windows上3000它不会应用sRGB非线性,但在我的其他机器上使用Nvidia GTX 670。 On the Intel HD 3000 in OS X it will also apply it. 在OS X中的Intel HD 3000上,它也将应用它。

So this probably means that I'm not setting my GL_FRAMEBUFFER_SRGB enable state at the right points in the program. 所以这可能意味着我没有在程序的正确位置设置我的GL_FRAMEBUFFER_SRGB启用状态。 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. 我目前没有加载任何纹理,所以我还没有需要处理线性化他们的颜色。

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. 为了强制程序不要简单地吐出线性颜色值,我试过的只是注释掉我的glDisable(GL_FRAMEBUFFER_SRGB)行,这实际上意味着为整个管道启用了这个设置,我实际上是冗余强制它重新启动每一帧。

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. 当我渲染给我的第一个FBO时,它可以应用伽玛。 It could do it when I blit the first FBO to the second FBO. 当我把第一个FBO送到第二个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: 我已经走到了最后一帧的屏幕截图,并将原始像素颜色值与我在程序中设置的颜色进行比较:

I set the input color to RGB(1,2,3) and the output is RGB(13,22,28). 我将输入颜色设置为RGB(1,2,3),输出为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. 这似乎是低端的相当多的色彩压缩,并让我质疑伽玛是否被多次应用。

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 . 我刚刚通过了sRGB方程式,我可以验证转换似乎只应用一次,因为线性1/255,2 / 255和3/255确实映射到sRGB 13 / 255,22 / 255, 28/255使用公式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. 鉴于这些低颜色值的扩展是如此之大,如果sRGB颜色变换被多次应用,那么它应该是显而易见的。

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? glEnable(GL_FRAMEBUFFER_SRGB)只适用于最终的帧缓冲区值,在这种情况下,我可以在GL初始化例程中设置它并在此后忘记它吗?

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. 启用GL_FRAMEBUFFER_SRGB ,对具有sRGB图像格式的图像的所有写入都将假定输入颜色(正在写入的颜色)位于线性颜色空间中。 Therefore, it will convert them to the sRGB colorspace. 因此,它会将它们转换为sRGB色彩空间。

Any writes to images that are not in the sRGB format should not be affected. 不是 sRGB格式的图像的任何写入都不应受到影响。 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. OpenGL将知道您何时渲染到sRGB帧缓冲区。

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. 在后处理之后,只有最终渲染应该涉及sRGB色彩空间。 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). 因此,您的多重采样帧缓冲区应该保持线性(尽管您应该为其颜色提供更高的分辨率以保持准确性。使用GL_RGB10_A2GL_R11F_G11F_B10FGL_RGBA16F作为最后的手段)。

As for this: 至于这个:

On Windows with the Intel HD 3000 it will not apply the sRGB nonlinearity 在具有Intel HD 3000的Windows上,它不会应用sRGB非线性

That is almost certainly due to Intel sucking at writing OpenGL drivers. 这几乎可以肯定是因为英特尔嘲笑编写OpenGL驱动程序。 If it's not doing the right thing when you enable GL_FRAMEBUFFER_SRGB , that's because of Intel, not your code. 如果在启用GL_FRAMEBUFFER_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). 当然,也可能是因为英特尔的驱动程序没有给你一个sRGB图像(如果你渲染到默认的帧缓冲区)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM