04-12-2022 04:33 PM
I am implementing OpenXR support (native, C++) and I have an issue with creating/using swapchains.
Doesn't matter if the swapchain is created with GL_SRGB8_ALPHA8 or GL_RGBA8, the results are almost always washed out/brighter. The only case it works fine is with OpenGL, using GL_SRGB8_ALPHA8 and NOT enabling GL_FRAMEBUFFER_SRGB. I do not convert manually in the shader. In this particular case, the image should be darker but it works as expected. All three other cases (GL_RGBA8, disabled GL_FRAMEBUFFER_SRGB, GL_RGBA8, enabled GL_FRAMEBUFFER_SRGB (although it makes little sense), GL_SRGB8_ALPHA8 enabled GL_FRAMEBUFFER_SRGB) give washed out, brighter image.
That was for OpenGL, PC. For OpenGLES, Quest, I can't get a properly working case at all. There is no way to enable/disable GL_FRAMEBUFFER_SRGB as it should work out of the box, so there are just two cases: GL_RGBA8 and GL_SRGB8_ALPHA8. Both give washed out, brighter image.
Seems like the results are always treated as being in RGB and are converted to sRGB when displaying?
To be on the same page here with a simple formula: sRGB = pow(RGB, 1.0 / 2.2) (brights up) and the other way around RGB = pow(sRGB, 2.2) (dims down).
This would explain why the only time it works is rendering to sRGB but as fragment shader operates in RGB, provides results in RGB and without GL_FRAMEBUFFER_SRGB enabled, is stored as it is.
I did a quick test by converting colours from sRGB to RGB (shader, clearing) and then it works fine but that's like hacking to get the right results.
I've seen a post with the same issue from a while ago. Also, I had a similar problem with Oculus SDK but decided to go with GL_SRGB8_ALPHA8 and disabled GL_FRAMEBUFFER_SRGB (and also I've seen a post somewhere else about it). With VRAPI I just used GL_SRGB8_ALPHA8 and it worked.
Tried a sample from Oculus OpenXR Mobile SDK (38.0), slightly modified to just show the renderable layer cleared to a certain colour. On Quest gives the same result no matter which format I choose. It's always brighter.
In that sample, I added one layer to be rendered on top of that with the same colour. The texture is filled directly, skipping any auto conversions. If the swapchain is created as GL_SRGB8_ALPHA8, results are as expected, if the swapchain is created as GL_RGBA8, results are brighter which is also expected.
Seems like somewhere inside, when swapchains are sent to display, they are always processed as the values inside were stored as RGB?
What am I missing? Maybe I do something wrong or don't understand something?
04-13-2022 04:05 AM
Ah, one thing I got wrong. You can disable converting to SRGB when writing on Quest (the same way as on PC). It works then, but it is still a hack. Or workaround, not a proper solution.
Full workaround:
Use GL_SRGB8_ALPHA8 and when binding buffer to write, use glDisable(GL_FRAMEBUFFER_SRGB);
11-22-2022 07:59 PM
Any thing new about this problem...