-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Fix text distortion on mobile devices/browsers with glow
backend
#6893
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
Conversation
Preview available at https://egui-pr-preview.github.io/pr/6893-master |
Apparently on very old drivers (that I think are violating the GLES GLSL spec) |
The |
Why this is the right solution and why possible workarounds someone might think of to make mediump work better won't actually work:
Because of the logarithmic scaling of fp numbers, this applies at all scales, i.e. if you try to linearly chop up the space between -1.0 and +1.0, the finest number of chops you can get is around 4 thousand. If you try to do 8 thousand then half of the new chops will get rounded off to a chopping location you've already chopped at. From 0 to 1.0, you get half as many available chops: the next smallest number below 1.0 is ~0.9995, or more precisely it's 2047/2048. So scaling isn't a viable workaround. If UVs ever have to be represented in a range from 0 to 1, which they do during texture sampling, then any font glyph texture atlas cannot be bigger than 2048x2048 without it becoming impossible to address specific pixels within it. But it gets slightly worse than this. The coordinate of the first pixel of a texture is not at 0. It's at (0.5/texsize). This is because 0 corresponds to the halfway point between the first and last pixels in the texture, wrapping left. So the coordinate for the first pixel of a 2048x2048 texture, in fp16, will get rounded down by half a pixel!. So our ACTUAL pixel-addressable texture size limit with mediump is 1024x1024. Yikes!!! 1024x1024 textures could work, but it's awful! If you're rendering text at 32x32 pixels per glyph, for example, you run out of space in the glyph atlas after only a thousand-ish characters, and need to start doing context switches to switch to another atlas! With 4096x4096 textures, you get 16 thousand-ish characters for 32x32 pixel glyphs instead. And mobile devices are WAY more likely to run into bigger and more glyph atlasses, because they're generally higher dpi than desktops. And let's say I want to render a single giant letter on a 1080x1920 screen, vertically. With a 1024x1024 atlas, doing that is literally impossible. To clarify, all of this happens the moment the texture UV is converted into the 0.0~1.0 range to be fed into the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch!
But can't we just always use highp
, instead of having an #if defined
?
Also @Wumpf can we do the same on wgpu?
In theory, yes! But I poked around on Google and there were people running into problems on old GLES2 drivers, where they would throw a hard error if they did this without the |
That makes sense! Please add that explanation to the code as a comment, so we understand why the code is written as it is 🙏 |
Short explanation added as comments. // To avoid weird distortion issues when rendering text etc, we want highp if possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
glow
backend
Did not test on platforms other than my phone, but I can't imagine it causing problems. AFAIK if highp isn't supported then
precision highp float;
needs to still not cause the program to fail to link/compile or anything; it should just silently use some other precision.Before:

After:
