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

Distance field fonts #504

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open

Distance field fonts #504

wants to merge 37 commits into from

Conversation

eugeneloza
Copy link
Member

Generates distance field image with padding of 6 pixels. Note that we do not use "normalized" distance field as the algorithm suggests because it'll increase the time and memory use for the texture generation plus complicate the code and it seems to be working without any issues if we do everything in a single pass.

Then attaches a special shader that properly renders every character from the distance field with tiny smoothing on the edge (similar to anti-aliasing).

eugeneloza and others added 30 commits June 6, 2023 11:09
@eugeneloza
Copy link
Member Author

Note that I've just tested and while it looks much better for magnification, it works worse than normal texture for minification:

2023-06-12-180820_1366x768_scrot

Hypothetically we might want to make it "smart"? E.g. we use "distance field" in case Scale >1.0 and use regular image texture in case Scale <= 1.0. However, this will double the memory use for the image, and will create some additional problems (e.g. there might be a visible "jump" in how the text looks when passing through 1.0 scale).

@eugeneloza
Copy link
Member Author

Another issue I've remembered: Good distance field textures seem to start getting generated from font size around 30. Below that - well, technically again in case of font size = 10 the distance field font looks worse than just scaled normal font:

2023-06-12-181350_1366x768_scrot

@eugeneloza
Copy link
Member Author

eugeneloza commented Jun 12, 2023

And one more note. While the two above may be just a good idea to notify the users that "use this only when upscaling fonts and be sure to still provide meaningful large font size at load", this one looks more like a bug for me:

The "bounding box" (or how this thing is called in UI) seems to be calculated incorrectly (actually height of the bounding box). That's because every glyph's width/height now receives 12 additional pixels each. Which results in incorrect text vertical alignment:

2023-06-12-181545_1366x768_scrot
2023-06-12-181546_1366x768_scrot

Copy link
Member

@michaliskambi michaliskambi left a comment

Choose a reason for hiding this comment

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

  1. We should make font with distance field have the same effective height? So that TCastleLabel effective height doesn't change when toggling distance fields on/off.

    (ref: Distance field fonts #504 (comment) )

  2. We need to have good quality when downscaling.

    • Research possibility of normalization -- can this make downscaling better?
    • Rejected because likely nonsense idea from Michalis: mipmaps for this (mipmaps would average colors and could make some go <0.5 and thus blank).
    • Fallback solution: Just have 2 textures, 1 for distance fields (upscaling) and 1 as for original algorithm (use when downscaling).

' gl_Position = vec4(vertex * 2.0 / viewport_size - vec2(1.0), 0.0, 1.0);' + LineEnding +
' tex_coord_frag = tex_coord;' + LineEnding +
'}' + LineEnding;
FS := 'varying vec2 tex_coord_frag;' + LineEnding +
Copy link
Member

Choose a reason for hiding this comment

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

Shader should respect define COLOR_UNIFORM, to have uniform color in GLSL, to react to TCastleLabel.Color.

' tex_coord_frag = tex_coord;' + LineEnding +
'}' + LineEnding;
FS := 'varying vec2 tex_coord_frag;' + LineEnding +
'uniform sampler2D image_texture;' + LineEnding +
Copy link
Member

Choose a reason for hiding this comment

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

Moreover, the shader code should be placed in a dedicated text file, processed just like existing image.fs.

Place it in

  • src/base_rendering/glsl/source/distance_field_font.fs
  • And for vertex shader, it seems you can just reuse it src/base_rendering/glsl/source/image.vs .

The subdirectory base_rendering is not the best for fonts, but this way the distance_field_font.fs will live alongside image.fs with which it should be synchronized.

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 this pull request may close these issues.

None yet

2 participants