-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Improved Text Rendering #10537
Improved Text Rendering #10537
Conversation
* Each glyph texture has a 1 pixel wide padding added along its edges. * Text node positions are rounded to the nearest physical pixel before rendering.
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.
This fixes a regression. I tried to run game_menu
on 0.11.0 and it seems to have crisp fonts, while on 0.12.0 it looks ugly. This PR makes the font as crisp as in 0.11.0
The difference is because the rounding changes in 0.12 caused the text's position to shift slightly so it was no longer pixel-aligned. |
Why is the padding change required? Does the rounding / pixel-grid fitting not fix this issue by itself? |
Pixel alignment makes things look more consistent and clean, while the padding change fixes how some of the glyphs are cut-off with hard edges. It's particularly clear if you compare the |
Does this interact with the |
Waiting until those two questions are answered before merging. |
.map(|window| window.scale_factor()) | ||
.unwrap_or(1.) | ||
* ui_scale.0) as f32; |
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.
This would have worked. tbh re-using the same bind name would also be fine.
let window = windows.get_single();
let window_scale = window.map_or(1., |w| w.resolution.scale_factor());
let scale_factor = (window_scale * ui_scale.0) as f32;
Okay, the implementation details of that feature are surprising to me but that all seems to make sense after staring at that PR a bit. The way that all works seems quite janky. It seems like this is a good fix for now. Thanks for looking into that. |
Text is looking really good now! |
# Objective The quality of Bevy's text rendering can vary wildly depending on the font, font size, pixel alignment and scale factor. But this situation can be improved dramatically with some small adjustments. ## Solution * Text node positions are rounded to the nearest physical pixel before rendering. * Each glyph texture has a 1-pixel wide transparent border added along its edges. This means font atlases will use more memory because of the extra pixel of padding for each glyph but it's more than worth it I think (although glyph size is increased by 2 pixels on both axes, the net increase is 1 pixel as the font texture atlas's padding has been removed). ## Results Screenshots are from the 'ui' example with a scale factor of 1.5. Things can get much uglier with the right font and worst scale factor<sup>tm</sup>. ### before <img width="300" alt="list-bad-text" src="https://github.com/bevyengine/bevy/assets/27962798/482b384d-8743-4bae-9a65-468ff1b4c301"> ### after <img width="300" alt="good_list_text" src="https://github.com/bevyengine/bevy/assets/27962798/34323b0a-f714-47ba-9728-a59804987bc8"> --- ## Changelog * Font texture atlases are no longer padded. * Each glyph texture has a 1-pixel wide padding added along its edges. * Text node positions are rounded to the nearest physical pixel before rendering.
# Objective The quality of Bevy's text rendering can vary wildly depending on the font, font size, pixel alignment and scale factor. But this situation can be improved dramatically with some small adjustments. ## Solution * Text node positions are rounded to the nearest physical pixel before rendering. * Each glyph texture has a 1-pixel wide transparent border added along its edges. This means font atlases will use more memory because of the extra pixel of padding for each glyph but it's more than worth it I think (although glyph size is increased by 2 pixels on both axes, the net increase is 1 pixel as the font texture atlas's padding has been removed). ## Results Screenshots are from the 'ui' example with a scale factor of 1.5. Things can get much uglier with the right font and worst scale factor<sup>tm</sup>. ### before <img width="300" alt="list-bad-text" src="https://github.com/bevyengine/bevy/assets/27962798/482b384d-8743-4bae-9a65-468ff1b4c301"> ### after <img width="300" alt="good_list_text" src="https://github.com/bevyengine/bevy/assets/27962798/34323b0a-f714-47ba-9728-a59804987bc8"> --- ## Changelog * Font texture atlases are no longer padded. * Each glyph texture has a 1-pixel wide padding added along its edges. * Text node positions are rounded to the nearest physical pixel before rendering.
Objective
The quality of Bevy's text rendering can vary wildly depending on the font, font size, pixel alignment and scale factor.
But this situation can be improved dramatically with some small adjustments.
Solution
This means font atlases will use more memory because of the extra pixel of padding for each glyph but it's more than worth it I think (although glyph size is increased by 2 pixels on both axes, the net increase is 1 pixel as the font texture atlas's padding has been removed).
Results
Screenshots are from the 'ui' example with a scale factor of 1.5.
Things can get much uglier with the right font and worst scale factortm.
before
after
Changelog