Skip to content

Use sRGBA unaware textures, and let the GPU interpolate in sRGB space. #5839

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

karhu
Copy link
Contributor

@karhu karhu commented Mar 21, 2025

This is one potential fix to the issues we are seeing around GPU texture interpolation of semi-transparent values:

With this change:
image
Without:
image

More

Note that this intentionally switches texture interpolation from linear to gamma. On one hand this makes interpolation more consistent with how it is done everywhere else in egui (vertex blending, and cpu computations). On the other hand it breaks a current assumption (see the screenshot from the rendering demo app).

image

If linear texture interpolation is not necessary, I think this is our best option, and I want to put it forward for discussion. See below for alternatives.

Alternatives that allow for linear blending:

  • Use sRGB aware textures, store sRGB values, but do not premultiply the stored values.
    • This will open us up to interpolation artifacts due to interpolating in non-premultiplied spaces (i.e color bleeding) and is hence undesirable.
  • Use sRGB unaware textures, store linear RGB values, but still premultiply them.
    • We will loose the precision gains that gamma encoding in u8 gives us. Still, if linear texture interpolation is strictly desired, this is our best option, perhaps in combination with a higher precision linear texture format.

Missing:

  • If these changes are acceptable I'll update the PR with matching changes to the glow backend.
  • I have followed the instructions in the PR template

Related:

@karhu karhu requested a review from Wumpf as a code owner March 21, 2025 11:49
@karhu karhu marked this pull request as draft March 21, 2025 11:50
Copy link

Preview available at https://egui-pr-preview.github.io/pr/5839-bugfix-srgb-interpolate-textures
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

@emilk
Copy link
Owner

emilk commented Mar 21, 2025

Interesting! I would love to see if this does anything for text sharpness

@emilk emilk added the visuals Renderings / graphics releated label Mar 21, 2025
@karhu
Copy link
Contributor Author

karhu commented Mar 21, 2025

Yes, I saw your other PR on that topic and at some point was also experimenting with changes to the encoding there, but then figured to keep the two separate. I consider this here more a correctness fix, enabling proper calibration (your CL) afterwards.

@Wumpf
Copy link
Collaborator

Wumpf commented Mar 21, 2025

Unfortunately don't have time right now and in the coming days to delve deeper into this but it seems to me more and more that we want to be content aware:
For "general rendering" the usual expectation is that srgb conversions are a pure encoding artifact, therefore all of blending, interpolation and premultiplication (well that's just blending) should happen in linear space. And that's also what all modern graphics APIs do with their "srgb" post-fixed formats - they do conversions strictly on read & write, and any math done with the color happens on the linear side which is a very intentional choice. However, it seems that for some select operations we want to do part or all of it in gamma space or at least as-if in gamma.
In other words, I'm very very nervous about forcing this "gamma space math" upon all texture and rendering. I'd still hope we could get rid of the hack of using non-srgb-converting output textures (which pretty much force gamma-space blending) in the first place, but I need to ponder this a bit more.

@Wumpf
Copy link
Collaborator

Wumpf commented Mar 21, 2025

this one might have been posted somewhere already probably, but love this take 😄 (as a bit of counterpoint to what I wrote above)
https://erikmcclure.com/blog/everyone-does-srgb-wrong-because/

But one can hardly blame you, because everyone is doing it wrong. CSS does it wrong because SVG does it wrong because Photoshop does it wrong because everyone else does it wrong. It’s all wrong.

... but in the end that's what is causing the ringing as also shown there so there's that :/

@karhu
Copy link
Contributor Author

karhu commented Mar 21, 2025

No need to rush from my side :) And don't get me wrong, even though that might not be obvious from my last couple comments here, coming from 3D rendering, ideologically I'm very much in the "math in linear space" camp 😅.

My main priority here is to fix obvious rendering artifacts, and if I'm pushing for "math in gamma space", then it's because:

  • eGUI currently seems to mostly operate in gamma space (textures being the one exception), and I was hoping sticking with it would be the path of least resistance.
  • eGUI being a UI library, and being consistent with CSS has some value here.

Regarding the ringing we see here: It's not because we do either gamma or linear interpolation. It's because we do linear interpolation wrong 🙈 We rely on the automatic GPU conversion upon read/write, which assumes non-premultiplied values, which, well, is not the case :P

@karhu
Copy link
Contributor Author

karhu commented Mar 21, 2025

PS: I'm also wondering if we should treat "image textures" and "font/shape atlas textures" separately. Image textures contain colors, with all the headache that entails. The atlas textures (which could actually be cut down in size to 1/4) contain "pixel coverage", which we might or might not want to treat differently, see: for example https://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing.html

@emilk emilk added the egui-wgpu label Apr 8, 2025
@emilk emilk added this to egui Apr 8, 2025
@emilk
Copy link
Owner

emilk commented Apr 22, 2025

PS: I'm also wondering if we should treat "image textures" and "font/shape atlas textures" separately.

With the new parley work, the font atlas texture will be full color (in order to support color emojis): #5784

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
egui-wgpu visuals Renderings / graphics releated
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Ringing around pre-rasterized circles.
3 participants