Search

Advertising

Home Blog Game Development XNA Sprite Font Quality
XNA Sprite Font Quality Print E-mail
Written by Markus Ewald   
Thursday, December 09 2010 12:03

Screenshot of fonts in XNA 3.1, XNA 4.0 and the Nuclex font processor There has been a discussion on the XNA forums regarding a slight decrease in the visual quality of SpriteFonts from XNA 3.1 to XNA 4.0: XNA 4.0 renders SpriteFont differently (and not for the better).

There are two changes that might have impacted visual quality: XNA 4.0 uses premultiplied alpha everywhere (whereas XNA 3.1 processed the alpha channel as-is) and, as revealed by "Krome Studios", The FontDescriptionProcessor in XNA 4.0 generates a texture with DXT3 (a form of compression that limits each block of 4x4 pixels to contain only 4 different colors and reduces the alpha channel to 4 bits of precision or 16 levels, see Wikipedia).

Because I've written a custom FontDescriptionProcessor for XNA 4.0 which outputs compatible SpriteFonts but uses FreeType instead of Windows' GDI font API, I decided to do a little comparison.

Read on for the results!

XNA 3.1

I created a new project and made it draw some text on the screen. Here's what it looks like:

Screenshot of XNA 3.1 rendering some strings using two fonts

The bunch of letters is supposed to highlight issues with antialiasing of diagonal lines and kerning problems. Let's take a closer look at the W character:

Zoomed in screenshot of XNA 3.1 rendering some strings using two fonts

We see that the gradient created by antialiasing is a bit blocky - as if there were too few shades of gray to go through.

XNA 4.0

I repeated the same steps in XNA 4.0 and look what happened here:

Screenshot of XNA 4.0 rendering some strings using two fonts

At the first look, we may notice only a bit of graininess on the edges of some characters, but zooming in shows that there are really only 4 colors being used here black, very dark gray, gray and white:

Zoomed in screenshot of XNA 4.0 rendering some strings using two fonts

XNA 4.0 w/ Nuclex font processor

The initial XNA 1.0 release didn't have SpriteFonts. Back then, I provided Nuclex.Fonts to fill that gap. As XNA 1.0 Refresh, 2.0, 3.0, 3.1 and 4.0 came out, I updated my content pipeline DLL to write .xnb files in the same format as XNA's own SpriteFonts, allowing it to act as a transparent replacement.

It uses FreeType, an OpenSource font rendering library and doesn't do texture compression (so your fonts will consume more memory!). FreeType claims to support 256 levels of antialiasing, so let's see what we get:

Screenshot of XNA 4.0 rendering some strings using two fonts generated by the Nuclex font processor

Looks a bit smoother already, eh? Here's the zoomed-in version:

Zoomed in screenshot of XNA 4.0 rendering some strings using two fonts generated by the Nuclex font processor

Conclusion?

I have to admit that I don't really see that much of a difference. I will be using my custom font processor in my own games for a completely different reason: its default origin is at the text's baseline (that's the lower end of characters like abcd - other characters, eg. qpyj extend below the baseline) instead of the text's upper left corner. I find the baseline to be a much better point of reference.

If you've got good eyes or are concerned about the looks of your text for another reason, you can find my custom font processor in the binaries of my Nuclex Framework. Just add a reference to Nuclex.Fonts.Content.TrueTypeImporter.dll to your content project and select "Sprite Font - Nuclex Framework" instead of "Sprite Font Description - XNA Framework" as the "Content Processor" for your *.spritefont files (see the official docs for an illustrated how-to).

As I wrote above, using my font processor the vertical origin will be the baseline, so after switching, your fonts will jump upwards by a bit, which you will have to compensate. The font sizes of FreeType also don't accurately map to Windows GDI. Just adding 5 to the font size appears to produce the same size of the XNA font in most cases.

 

Comments  

 
+1 #1 scoy 2011-02-05 02:19
Thanks for the post. Hopefully this will push the XNA team to stop compressing their fonts, or at least make it optional.

The size difference is probably because XNA seems to think that monitors are 72dpi when in fact most are 96dpi. This causes XNA fonts to look larger than they should. I've found that if I scale the font size I want by 72/96 then they look right, ie if I want 30pt I enter 22.5 (30 * 72 / 96) into the .SpriteFont file and it matches.
Quote
 
 
+1 #2 Cygon 2011-02-05 09:00
I would be delighted if they could add a "Texture Format" property to their importer, switchable between "DxtCompressed" and "Color".

You're spot on about that DPI were causing the size difference, but I think your logic should be the other way around ;)

At 96 DPI, larger fonts should be generated so they appear at the same size on a display with tighter packed dots. My content processor was indeed set to 72 DPI and that caused the size difference to XNA (with my fonts processor ending up at 72/96 of the size the XNA content processor would generate)
Quote
 

Add comment


Security code
Refresh



Joomla Template by Joomlashack