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

Add sub-pixel glyph positioning support. #57877

Merged
merged 1 commit into from
Feb 15, 2022

Conversation

bruvzg
Copy link
Member

@bruvzg bruvzg commented Feb 9, 2022

Note: This has nothing to do with LCD sub-pixel rendering, it's a completely unrelated technique.

Instead of rasterizing each glyph vector outline once, it's rasterized multiple times, offset by a fraction of a pixel.

Pros:

  • Sharper and a bit more compact text.

Cons:

  • Up to 2x (or 4x) more memory used by font (and time spent rasterizing glyphs).

Rendering example (half and quarter modes looks almost identically, but there are slight differences visible on the second screenshot):
rendering

5x zoomed part of example (red arrow shows one of the differences between half and quarter modes).
zoom

Animated difference between half and quarter modes:
1

Related proposal - godotengine/godot-proposals#1258 (probably described issue is mostly caused by hinting not fully applied without sub-pixel positioning, but there's also LCD sub-pixel rendering discussion in the same proposal).

@AlexFolland
Copy link

Disclaimer: I am not a contributor to Godot (yet), so please don't consider this comment as authoritative in any way. I just want to leave my opinion as a Godot user who is subscribed to godotengine/godot-proposals#1258.

I applaud your effort in implementing something new, and especially the level of clarity and detail in your demonstration and explanation. This was very easy to understand and does add something to consider as an improvement to the engine.

That being said, this does not appeal to me personally. I wouldn't be enabling it in my projects because it introduces no visual improvement in my personal opinion while introducing a performance detriment.

Even if someone does understand it and see a benefit, it does not resolve the issue in godotengine/godot-proposals#1258, while simultaneously introducing additional complexity in configuration. Without the same level of clarity as is present here in this MR also present in the documentation, the related option may be difficult to understand for users.

My personal opinion is that LCD subpixel font rendering is the ultimate goal, and anything short of that does not solve the problem, as the text still looks relatively blurry.

@Calinou
Copy link
Member

Calinou commented Feb 9, 2022

Could you take a screenshot of the project manager and editor with and without this feature enabled (at 100% display scale)?

@bruvzg
Copy link
Member Author

bruvzg commented Feb 10, 2022

Could you take a screenshot of the project manager and editor with and without this feature enabled (at 100% display scale)?

Project Manager

Disabled:
pm_0
1/4:
pm_q
pm

Editor

Disabled:
ed_0
1/4:
ed_q
ed

I have added interface/editor/font_subpixel_positioning editor setting (disabled by default) to change it (can be changed without restarting).

Up to 2x (or 4x) more memory used by font

This might sound scary, but font cache is not large in the first place, for example real memory impact for the editor: with Chinese localization, and after browsing multiple help pages and scripts to rasterize as much glyph as possible additional 3 MB of RAM were used (2.4 → 5.6), with English localization it's about 0.75 MB increase. No performance impact is noticeable.

@bruvzg bruvzg marked this pull request as ready for review February 10, 2022 09:42
@bruvzg bruvzg requested review from a team as code owners February 10, 2022 09:42
@bruvzg bruvzg changed the title [WIP] Add sub-pixel glyph positioning support. Add sub-pixel glyph positioning support. Feb 10, 2022
@Calinou
Copy link
Member

Calinou commented Feb 10, 2022

On the feature itself: I believe this is useful, especially in games because using LCD antialiasing in games is challenging (since you need to know the background color for every area that displays text). In contrast, sub-pixel glyph positioning doesn't require custom blending functions or knowing the background color in advance.

Does this PR have a benefit when hinting is set to Light or Normal?

No performance impact is noticeable.

My only concern is that new glyphs may cause stuttering during gameplay, especially on mobile where fonts are often displayed at large sizes.

I suppose enabling ASCII prerendering by default would alleviate this.

@bruvzg
Copy link
Member Author

bruvzg commented Feb 10, 2022

Does this PR have a benefit when hinting is set to Light or Normal?

Hinting has a similar effect on the sub-pixel positioned font as it has on the normal font (not sure if it's better with or without hinting, I guess it's the matter of preferences).

My only concern is that new glyphs may cause stuttering during gameplay, especially on mobile where fonts are often displayed at large sizes.

It's always possible to pre-rendering glyphs (will rasterize all variants). With the large font sizes, it's probably less useful anyway.

Unlikely it will cause any issues with ASCII text, for fonts with large amount of glyph (like CJK) it probably can, since it already was an issue on mobile, but it's disabled by default.

@Calinou
Copy link
Member

Calinou commented Feb 10, 2022

but it's disabled by default.

It might be worth enabling this in the editor by default (either Half or Quarter), since I doubt most users will know how to improve font rendering in the editor. The performance impact is probably unnoticeable in the editor.

In projects, I'm not sure if this should be enabled by default. In projects, larger font sizes are generally used (at least 16), so the difference will be barely noticeable. If we also enable ASCII prerendering by default, performance should be fine during gameplay. On the other hand, if we leave this disabled by default, then very few people will bother checking the settings and enabling this feature. Sub-pixel glyph positioning isn't something most people are aware of… including me until yesterday 🙂

Edit: Since the benefits of sub-pixel glyph positioned are largely linked to the font size, maybe we could rework the settings as follows:

  • Automatically use the One Quarter option for fonts with size <= 161.
  • Automatically use the One Half option for fonts with size <= 201.
  • Don't use subpixel glyph positioning for fonts at larger sizes.
  • Add a boolean Use Subpixel Glyph Positioning project setting that can be used to disable the above behavior. This setting would be enabled by default, but it can be disabled for those who wish to maximize font rendering performance.

Footnotes

  1. This refers to the font size post-oversampling. For instance, if you use the 200% editor scale, fonts at size 14 will be rendered at size 28, so subpixel glyph positioning would be disabled for the editor font. 2

@bruvzg
Copy link
Member Author

bruvzg commented Feb 12, 2022

Added font size AUTO mode (1/4 for >= 16, 1/2 for >= 20), and set is default option.

Also added project settings for the default font config (positioning, hinting, aa):

Screenshot 2022-02-12 at 17 49 23

Copy link
Member

@mhilbrunner mhilbrunner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@@ -600,5 +600,8 @@
<member name="style_name" type="String" setter="set_font_style_name" getter="get_font_style_name" default="&quot;&quot;">
Font style name.
</member>
<member name="subpixel_positioning" type="int" setter="set_subpixel_positioning" getter="get_subpixel_positioning" enum="TextServer.SubpixelPositioning" default="1">
Font glyph sub-pixel positioning mode.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we document why you would use this? Basically that it trades performance for sharper rendering, especially for smaller font sizes, and may not have much effect for large font sizes.

We could also recommend the AUTO setting and point to the project setting.

@akien-mga akien-mga merged commit 760a95e into godotengine:master Feb 15, 2022
@akien-mga
Copy link
Member

Thanks!

@bruvzg bruvzg deleted the subpixel_gl_pos branch February 15, 2022 21:14
@Calinou
Copy link
Member

Calinou commented Feb 28, 2022

Now that an Auto option is available, we should probably see if there's a still point in exposing the editor setting. To me, it seems there's little reason to change it from the default, as the Auto setting makes a good job at only using subpixel positioning when it makes a noticeable difference.

@AlexFolland
Copy link

If you ever find yourself making a subjective argument for what value a setting should be set to, that's when you know the setting needs to be exposed, as others may disagree.

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

Successfully merging this pull request may close these issues.

5 participants