Font Blurry Causing Frustration

Godot Version

Steam 4.3

Question

I am attempting to build a pixel card game, where the cards are represented as such (also attempted this without the control node involved):

Node2D
|- Control
   |-TextureRect [CardImage]
   |-Label [CardName]
   |-Label [Attack]
   |-Label [Defense]

I will admit this is my first foray into Godot, and I think its a silly problem to have, but I downloaded a google font (PixelifySans.ttf) and I can’t seem to get the text unblurred in game. It doesn’t look blurry in the editor, only while the game is running. I assume this has something to do with scaling, but I used the recommended 2D project settings from the docs. Here is a list of all the things I have done in my research to fix this

  1. In font import settings enabled:
  • Generate MipMaps
  • Multichannel Signed
  1. In advanced font import settings disabled subpixel positioning

  2. My Project settings>Window>Stretch is as follows (according to the docs)
    Mode = viewport
    Aspect = expand
    Scale = 1
    Scale Mode = integer

  3. I also allow high dpi and have my viewport width and height at 640 and 360 respectively\

  4. I have used font sizes that should work for this font (tried 8px, 280px) as well as some odd numbered ones. The best I can get is the font looks clear with no blur, but is missing pixels in the actual letters

I have been doing hours of research and testing, and all in the name of getting text to display without a blur, is this normal? If so, why? I noticed it on the default font too which seems odd. Any help is appreciated!

1 Like

Just set the font size bigger in each label and not just scale. Fonts are usually dynamically drawn. So if they have a small font size then scaling it will be pixelated and blurry as it attempts render it readable at such a small size. Larger font size means more base pixels.

I guess you mention that already, missing pixels sounds strange to me unless your viewport size is also low res?

Viewport size is 640, 360 as is talked about in the docs for supporting multiple resolutions, I scale to full screen because that is how I want the game to be played (and I do that how the docs say to). Unless I missed a step (which is why I listed my config) how am I not supposed to scale? I don’t want a game with black bars or that’s in a tiny window, if that’s the case I’ll just go to another engine, but I don’t believe that has to be the case based on what I’ve read

For reference the font is supposed to be pretty small, it’s going on a card after all, that’s why I listed 8px as one of the sizes ive tried, that’s the size it should be

As for the image you sent, I forgot to mention it but I have also tried nearest in the filter, nothing has made this text readable

Did you adjust the filter settings for both the project and the canvas item?

Just tried it, did not seem to make a difference, here’s a snip of what it looks like

I took a deeper look the font itself os not pixel perfect even though it looks pixilated. I got a pretty clean look by setting the font size to 360 (a multiple of the resolution) and scaling it down by a power of 2.

You are not going to be able to get it to fit right without allowing some blur.

I think you would be better off finding a bitmap font rather then one that is dynamically rendered.

Okay, thanks for your help!! I thought bitmap was worse for dealing with scaling since the cards will be scaled up and down with viewport size, as well as when you hover over the card for better visibility. I will look into changing the font though. Once again thank you!

The font type should not matter so much as long as your remain pretty meticulous about quantizing your scaling. Godot allows floating point scaling in 2d but this will get you into trouble if your goal is to have perfect pixels at low viewport resolution.

Scale itself for canvas items should not interpolate smoothly with fractional floating point values in a pixel perfect game, unless you are okay with that double pixel, missing pixel, behavior when the pixel is halfway between two render fragments. It should snap to multiples of the resolution.

Im going to be 100% honest here, I really only understand about a quarter of that. I have swapped to a bitmap font (or at least it should be) and I’m still getting the same problem. I really didn’t think it would be this difficult to make a simple card lol. I was able to fix it by just making the viewport 1920x1080 (the resolution of my monitor) but as far as I understand this means I wont be supporting lower or higher resolutions well correct?

Well i would work on understanding what i said before.

What you are trying to do can be done. You just need to realize that canvas items have an arbitrary size/scale that is independent of the viewport resolution. The underlying canvas item has a raw size that is translated into the viewport by its scale.

Increasing the viewport resolution just masks the pixel rounding issue. To me is perfectly fine, but is not “pixel perfect” :shushing_face:.

A square, sprite, canvas item that is 2x2 pixels at 1.0 scale will be 2x2 pixels in the viewport. If the scale becomes 1.1 the canvas item becomes 2.2x2.2 pixels in the viewport, but is just still 2x2 pixel sprite underneath. The viewport cant draw fractional pixels and may represent it as 2x2 2x3 3x2 or 3x3 pixels depending on rounding errors when it draws the canvas item to the image buffer.

A scale of 1.5 makes the 2x2 a 3x3 and will be stable. The next stable scale is 2.0 for an even number pixel width. Stable scales for even width sprites is 1.0, 1.5, 2.0, 2.5, … etc.

If you start with an odd 3x3 square at 1.0 scale the first stable scale is 2.0 and second is 3.0 and so on, because the intermediary steps are irrational: 3x3 → 4x4 is a scale of 1.33333… repeating. 3x3 → 5x5 scale of 1.666666… repeating.

The approximation of a irrational numbers will make the pixel ( in 3x3 → 4x4) 3.999999998x3.999999998 pixels in the viewport which could lead to wonky rendering.

Now when it comes to fonts, the font size determines the pixel count of the canvas item and the scale changes how it is translated to the viewport.

If you are animating a canvas items scale, you need to step the scale at the stable scale steps.



8000x433 • 0.125 = 1000x54.125

I could play with the size and scale to get it into a whole numbers. But the font wants to draw soft edges.

1 Like

I had blurry bitmap font issues. I found that I HAD to set the font to 9px (regardless whether that made sense or not) and I had to use increments of 9px for any other sizes, or the text got blurry.

In one of your screenshots it looks like your card was being resized. This would likely affect your font no matter what settings or work arounds you find. But I am guessing here.

This makes sense and tells me I was on the right track, however I am a bit confused on how to make sure I scale by a “whole step” (1, 1.5, 2, etc) while using scale to render the whole viewport bigger, I assume there’s some math involved.

Just spitting some of my numbers out, with an initial resolution/size of 640, 360, to get to my monitor size, it has to be scaled by 3.0 (640x3=1920, 360x3=1080) and given this is a “whole step” I think I’m a bit confused why this doesn’t scale well, since it was blurry from the start and not only when mouse over scaling up for better viewing. The initial card size is 67x100 so it should just be 201x300 and the font size (no matter what value I set it too, 8px, 9px, 10px, etc) is still blurry. The only time I’ve managed to get it not blurry is when it’s a large value that is way too big to be displayed on a card.