1

I have a small sample, es-300-fbo-srgb, supposed to showing how to manage gamma correction in opengl es3.

Essentially I have:

  • a GL_SRGB8_ALPHA8 texture TEXTURE_DIFFUSE
  • a framebuffer with another GL_SRGB8_ALPHA8 texture on GL_COLOR_ATTACHMENT0 and a GL_DEPTH_COMPONENT24 texture on GL_DEPTH_ATTACHMENT
  • the back buffer of my default fbo is GL_LINEAR
  • GL_FRAMEBUFFER_SRGB initially disabled.

I get this

instead of this

Now, if I recap the display metho, this is what I do:

  • I render the TEXTURE_DIFFUSE texture on the sRGB fbo and since the source texture is in sRGB space, my fragment shader will read automatically a linear value and write it to the fbo. Fbo should contain now linear values, although it is sRGB, because GL_FRAMEBUFFER_SRGB is disabled, so no linear->sRGB conversion is executed.

  • I blit the content of the fbo to the default fbo back buffer (through a program). But since the texture of this fbo has the sRGB component, on the read values a wrong gamma operation will be performed because they are assumed in sRGB space when they are not.

  • a second gamma operation is performed by my monitor when it renders the content of the default fbo

So my image is, if I am right, twice as wrong..

Now, if I glEnable(GL_FRAMEBUFFER_SRGB); I get instead this

The image looks like it have been too many times sRGB corrected..

If I, instead, leave the GL_FRAMEBUFFER_SRGB disabled and change the format of the GL_COLOR_ATTACHMENT0 texture of my fbo, I get finally the right image..

Why do I not get the correct image with glEnable(GL_FRAMEBUFFER_SRGB);?

genpfault
  • 51,148
  • 11
  • 85
  • 139
elect
  • 6,765
  • 10
  • 53
  • 119

1 Answers1

0

I think you are basically right: you get the net effect of two decoding conversions where one (the one in your monitor) would be enough. I suppose that either your driver or your code breaks something so OpenGL doesn't 'connect the dots' properly; perhaps this answer helps you:

When to call glEnable(GL_FRAMEBUFFER_SRGB)?

Community
  • 1
  • 1
Simon Thum
  • 576
  • 4
  • 15
  • The default fbo is `GL_LINEAR` by default. In the meanwhile, I solved by enabling `GL_FRAMEBUFFER_SRGB` at the [first passage](https://github.com/elect86/jogl-samples/blob/master/jogl-samples/src/tests/es_300/Es_300_fbo_srgb.java#L349) and disabling it at the [second one](https://github.com/elect86/jogl-samples/blob/master/jogl-samples/src/tests/es_300/Es_300_fbo_srgb.java#L376) but I can't explain why it works.. – elect Feb 09 '16 at 13:26
  • Good it works now! I meant to say that GL_LINEAR is not opposite to GL_FRAMEBUFFER_SRGB or any other lightness encoding constant as GL_LINEA,R TTBOMK, determines interpolation. It sounds like a complement but it isn't, and should not be relevant here. – Simon Thum Feb 09 '16 at 16:59
  • I remember they are, look [here](https://www.opengl.org/wiki/GLAPI/glGetFramebufferAttachmentParameter) "If _pname​_ is `GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING`, _param​_ will contain the encoding of components of the specified attachment, one of `GL_LINEAR` or `GL_SRGB` for linear or sRGB-encoded components, respectively. – elect Feb 09 '16 at 18:39
  • I see it's been reused for that. Good to know, thanks! – Simon Thum Feb 11 '16 at 12:05