OpenGL sRGB & assets

Now, when sRGB is optionally enabled for OpenGL rendering, how to deal with assets in sRGB format?

Assets are currently always converted in sRGB format by test_asset_builder.cpp, right?
But at runtime game enables sRGB only when GPU driver supports it. When it doesn't support the texture format will be GL_BGRA8, so texture is expected to be in linear space. Because currently it is always sRGB. That will lead to incorrect rendering.

How to deal with that? Duplicate texture assets (one in linear, one in sRGB)?
Or maybe because asset source is always linear space (bmp files) it is simpler to have asset textures always in linear space (always use GL_BGRA8 and not GL_SRGB8_ALPHA8) and do sRGB correction only for blending and framebuffer display?
It is extraordinarily rare these days to have a GPU that does not suppose sRGB, so the real answer is probably "don't worry about that". But if you want to handle it, the best way is to convert to or from sRGB in the loader.

The benefit of converting from sRGB is that it doesn't penalize you in your high-performance case. But the benefit of converting to sRGB is that it doesn't penalize you in your low-performance case.

Which you pick depends on whose experience you're prioritizing :)

- Casey
I see. Right, only ES profile and very old (or very wierd) GPU's doesn't support sRGB textures: http://opengl.gpuinfo.org/gl_list...onunsupported=GL_EXT_texture_sRGB

Edited by Mārtiņš Možeiko on
I should also say I don't know about mobile - it may be that sRGB isn't common there, I have no experience with it. But it usually isn't an issue there because you're shipping a separate package for the mobile version anyway, so if sRGB is not common, then your mobile package just doesn't use them.

I'd also point out that really saying "sRGB" isn't the right thing here. It's really the premultiplied alpha that's the part you care about. This whole situation would largely be irrelevant for 2D art composition style rendering like we do if it weren't for the premulitplied alpha part of things. Because we use premulitplied alpha to ensure that bilinear blends are correct, we end up having to have the alpha be in sRGB space, which in turn leads to worse blending artifacts if it is interpreted linearly because things are different transparencies than they should have been.

- Casey
On Android GL_EXT_sRGB (for texture, framebuffer and renderbuffer object) is supported for ~36% devices: http://opengles.gpuinfo.org/gles_extensions.php

Display framebuffer sRGB is very rare, EGL_KHR_gl_colorspace is at 0.14% http://opengles.gpuinfo.org/gles_egl_extensions.php
Only latest Tegra supports it: http://opengles.gpuinfo.org/gles_...glextension=EGL_KHR_gl_colorspace

No idea about iOS devices.

Edited by Mārtiņš Možeiko on
That is very good to know!

For Handmade Hero, we could easily decide to just not do sRGB at all, because it doesn't really matter much for 2D composition stuff that isn't doing a lot of HDR lighting, etc. So maybe that is a good decision to support more platforms for people, who knows.

Like I was saying, though, it is usually not a big deal to just ship two art packages, one for mobile and one for PC, so at that point it's probably fine to just say we'll ship an sRGB for PC and a non-sRGB for mobile (regarding the alpha channel).

- Casey
According to https://developer.android.com/about/dashboards/index.html


[table]
[tr]
[td]OpenGL ES Version[/td][td]Distribution[/td]
[/tr]
[tr]
[td]2.0[/td][td]53.2%[/td]
[/tr]
[tr]
[td]3.0[/td][td]39.7%[/td]
[/tr]
[tr]
[td]3.1[/td][td]7.1%[/td]
[/tr]
[/table]

and Opengl ES 3+ Includes EXT_sRGB, that is for texture encoding. Casey's solution (different asset pack) seems a good one. But you could hope that programmed obsolescence will do the work and support only OGLES3+ :P

Regarding framebuffer, in libLepre I check if it's available and if not I do the conversion manually, but it seems that it could be better to always do it manually, because driver ones are too much different and unpredictable.
Instead of doing conversion manually you could create framebuffer with sRGB renderbuffer. Then do all rendering to this framebuffer, and at the end blit it to display framebuffer. If you are depending on GL ES 3.x which supports sRGB textures, then it automatically supports sRGB texture and sRGB renderbuffers for framebuffer attachments.
Hmm,I've never tried that. It could be faster than using f16 framebuffer like now. Maybe useful on mobile or slow GPUs. I'll have to benchmark that! Thanks!