Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sRGBA gamma aware texture sampler #166

Closed
emilk opened this issue Jan 11, 2021 · 13 comments · Fixed by #305
Closed

sRGBA gamma aware texture sampler #166

emilk opened this issue Jan 11, 2021 · 13 comments · Fixed by #305

Comments

@emilk
Copy link
Sponsor Contributor

emilk commented Jan 11, 2021

It would be great if miniquad could support the GL_SRGB8_ALPHA8 texture format. This enables sRGBA gamma-aware texture sampler, which is the only way to get colors rights with bilinear filtering (and mipmaps).

WebGL1 only supports it with the EXT_sRGB extension. WebGL2 supports GL_SRGB8_ALPHA8 by default.

@not-fl3
Copy link
Owner

not-fl3 commented Jan 11, 2021

The problem with EXT_sRGB: it is out of "safe webgl1 extensions" list: https://jdashg.github.io/misc/webgl/webgl-feature-levels.html
So I do not really see how to implement this without reducing supported browsers range.

Lets keep it open though and collect some ideas.

@nokola
Copy link
Contributor

nokola commented Jan 12, 2021

Browser compatibility for EXT_sRGB is pretty good - pretty much every browser out there. Given that Edge is now using the Chrome engine, I expect it will be supported for Edge as well:

https://developer.mozilla.org/en-US/docs/Web/API/EXT_sRGB
image

Few ways we could support it:

  1. by naming the option GL_SRGB8_ALPHA8_CHECK_COMPAT with some comment/explanation that it may not work on some browsers on WebGL1 (basically try using it and ignore errors, given the very high compatibility)
  2. Have some platformCapabilities.supports_linear_color() call in the library

What problems, if any are there with the approaches above?

@not-fl3
Copy link
Owner

not-fl3 commented Jan 13, 2021

Surprisingly, but people still use edge. Last bug report from the edge user was just couple of month ago.

I like the idea of a special texture format that will be SRGB on most platforms, but for some corner case will fall back to plain RGB and colors would be a bit off. However I would try to somehow avoid inconsistency across browsers.
On the other hand - it is only the edge and non-chromium edge is going to disappear soon..

Maybe it is worth sarcrificing a little bit of performance and doing SRGB covnersion on the shader side with RGB textures?

@emilk
Copy link
Sponsor Contributor Author

emilk commented Jan 13, 2021

but for some corner case will fall back to plain RGB and colors would be a bit off

They will actually be a lot off if the shader expects colors in linear space, but gets them in gamma space. One would need to write a separate pipeline for the fallback case, which would be annoying.

Maybe it is worth sarcrificing a little bit of performance and doing SRGB covnersion on the shader side with RGB textures?

sRGBA-aware texture sampling is not only for performance, it is also for quality. A classic RGBA sampler will do bilinear blending in gamma-space, producing the wrong colors when interpolating. An sRGBA aware sampler will do the blending in the correct (linear) space. This is very hard to work around in the shader unless the shader does manual four-tap sampling and interpolation, but then it need to know the resolution of the texture etc. And with mipmaps it gets much worse.


Anyway, an sRGBA-aware texture sampler proposed by this issue is probably not that important to most people - the erroneous colors of the current default sampler is only visible when magnifying textures (e.g. when using a coarse texture as gradient). I don't think miniquad should commit to it unless we feel confident it is supported everywhere, or it will become a huge hassle just for a small benefit for a few graphic nerds like me :)

@not-fl3
Copy link
Owner

not-fl3 commented Jan 13, 2021

They will actually be a lot off if the shader expects colors in linear space, but gets them in gamma space. One would need to write a separate pipeline for the fallback case, which would be annoying.

But apparently this would be the case only for the very old edge version, so rendering at least something usable would be better than just a panic, isnt it?

However I am not yet sold on that idea, I personally believe that we should guarantee that OpenGL/Metal subset we use will works exactly the same way on all miniquad-supported platforms. And if there is no way to emulate/workaround some certain issue - it is better to not use that feature at all.

@nokola
Copy link
Contributor

nokola commented Jan 13, 2021

Old Edge

Microsoft is dropping support for the old Edge in 2 months, on March 9, 2021:
https://docs.microsoft.com/en-us/deployedge/microsoft-edge-sysupdate-access-old-edge
https://www.theverge.com/2020/8/17/21372487/microsoft-internet-explorer-11-support-end-365-legacy-edge

This means there will be full browser compatibility for supported browsers by the browser vendor. What do you think of officially dropping support for the Old Edge in miniquad?

sRGBA-aware texture sampler proposed by this issue is probably not that important to most people - the erroneous colors of the current default sampler is only visible when magnifying textures

In my opinion, it's very important for visuals, even if people don't realize. The sRGB can produce many unpleasant artifacts in 2D even sprite rendering without resizing - halos around color, unintended "drop shadow" or "outline" effect for sprites.

Here's example from Unity, Linear on top, sRGB compression on bottom. with sRGB we can see serious halos/color issue.
https://docs.unity3d.com/Manual/LinearRendering-LinearOrGammaWorkflow.html
image

For the sizing, there can be serious issue with textures. Some examples to see the texture quality degradation, resized to make 2x smaller:
http://www.ericbrasseur.org/gamma.html?i=1
image

sRGB blending/sizing calculations are always wrong (incidental problem in decades in industry), so when I think of linear vs sRGB I consider "linear" as bug-fix.

However I am not yet sold on that idea, I personally believe that we should guarantee that OpenGL/Metal subset we use will works exactly the same way on all miniquad-supported platforms. And if there is no way to emulate/workaround some certain issue - it is better to not use that feature at all.

I agree with the goal - it will make miniquad simpler. Perhaps we can keep this goal and have linear by dropping support for Old Edge?

@emilk
Copy link
Sponsor Contributor Author

emilk commented Jan 13, 2021

There is a separate issue of how to composite sprites/textures in linear space. The WebGL framebuffer does all blending in the incorrect gamma space (even WebGL2) so the only solution to get that correct is to render-to-texture. It is a bit infuriating how bad WebGL is :)

@nokola
Copy link
Contributor

nokola commented Jan 13, 2021

There is a separate issue of how to composite sprites/textures in linear space.

Thanks for clarifying! Just to clarify as well - my second set of pictures is for sizing (similar to the issue you mentioned), not blending. I didn't know WebGL2 blends in sRGB, thanks for the info!

@not-fl3
Copy link
Owner

not-fl3 commented Jan 13, 2021

Following up the discussions, we have 3 options:

  • not supporting srgb at all. This way the colors management would be the problem, but it will be consistent on all the problems.
  • drop old edge support. Will need some research to ensure that something like old safari really do support srgb, but this way the behavior will be consistent on all (reduced) supported platforms.
  • make srgb_compat texture format, working as SRGB on pretty much everyting except the edge (also needs tests on old ios safari), but leading to a warning in console and broken colors on the edge.

Opinions?
Would srgb_compat fix the problem for egui, @emilk?

@emilk
Copy link
Sponsor Contributor Author

emilk commented Jan 13, 2021

I think adding a new srgb_compat format could be a good place to start as an experiment. Maybe it could be an experimental opt-in feature that only work on some platforms. Then we can try it out and see if it works, and where it works.


To use miniquad as a fully compliant backend for egui (what egui_glium does now) it would also need to support sRGB correct blending, which means the GL_FRAMEBUFFER_SRGB extension/feature. GL_FRAMEBUFFER_SRGB seems impossible in WebGL1, but from egui:s point of view that's fine (egui_web has the same color problem), but at least for native I'd like to have the colors perfectly right (as they are in egui_glium). Beyond that egui_glium also supports changing mouse cursor icons, which is something I'd be reluctant to give up.

In any case, I don't really have much time to work a switch from glium right now anyway. I mostly created this issue because I think sRGB correct colors is something a lot of projects would like to have.

@not-fl3
Copy link
Owner

not-fl3 commented Jan 13, 2021

But GL_FRAMEBUFFER_SRGB do not really work correctly even on webgl 2 or I am wrong here? (I am looking at this stackoverflow answer, did not researched this myself https://stackoverflow.com/a/51034463)
It looks like we cant do much about webgl's srgb problems?

@emilk
Copy link
Sponsor Contributor Author

emilk commented Jan 13, 2021

I still have a thin hope that GL_FRAMEBUFFER_SRGB may work in WebGL2 when using a texture as a render target, but I haven't tried it yet. I have verified that it does not work with the backbuffer.

But GL_FRAMEBUFFER_SRGB does work for e.g. my mac, so it would still be good to have as a feature in miniquad. The problem then becomes that one would need different shaders on different platforms (some would have shaders output in gamma space, some in linear space), but at least it would be possible to get fully sRGB correct blending on some platforms.

@nokola
Copy link
Contributor

nokola commented May 27, 2021

Update: Old edge (Edge Legacy) market share is now 0.25%, and Microsoft has stopped support since March 2021
https://gs.statcounter.com/
Based on the very low market share, I think it's OK to not support it in miniquad as well. This makes option 2 discussed above very viable:

drop old edge support. Will need some research to ensure that something like old safari really do support srgb, but this way the behavior will be consistent on all (reduced) supported platforms.

What is other's opinion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants