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
base: master
Are you sure you want to change the base?
Distance field fonts #504
Conversation
…r rendering distance field
…variable 'Bitmap'
… use if every request (twice per glyph)), rename internal fields
Note that I've just tested and while it looks much better for magnification, it works worse than normal texture for minification: Hypothetically we might want to make it "smart"? E.g. we use "distance field" in case |
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: |
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.
-
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.
-
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 + |
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.
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 + |
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.
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.
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).