Author Topic: Pixel Art Fonts With TMPro (Solved)  (Read 6890 times)

doomcake

  • Newbie
  • *
  • Posts: 6
Pixel Art Fonts With TMPro (Solved)
« on: December 15, 2016, 08:48:17 PM »
Hi there!

Ok. I'll start off with some context. I've been having trouble figuring out how to make fonts snap to a pixel grid with TM Pro. My game is a pixel art style game, as I'm sure you've guessed. And here is what pixel 'snapping' looks like in the game zoomed way in:



The red lines are the 1 pixel by 1 pixel grid. To get the pixel art look, I'm scaling my art up by 3. Meaning, for each pixel that is imported into the engine, it actually renders 3 pixels. This gives this look:



Each big square is one pixel in Photoshop.

Ok, so here is the issue I'm tackling:



I can't seem to come up with a way to make the font line up with the pixel grid as you can see from above image. This font was scaled by hand and positioned using a script that snaps a transform to the grid. So, as long as the font has the correct size and spacing, it should fit to the pixel grid, right?

Now, I understand that the beauty of dynamic fonts is that they can resize and look great. And, it's true, this font actually does look good at different sizes when there are no other assets to compare to. Unfortunately, as soon as the font is backdropped by actually pixel snapped assets, it looks terrible. So, I'd love to know, has anyone figured out a way to use TM Pro so that the fonts can snap to a pixel grid and look crisp and clean. Is there a magic setting? Or font size? Anyone else had this issue?

Any help would be really amazing!

Thank so much!
« Last Edit: December 18, 2016, 12:24:40 PM by doomcake »

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Pixel Art Fonts With TMPro
« Reply #1 on: December 16, 2016, 04:24:19 AM »
When a TTF is designed as a bitmap font, it has a specific font size that it's designed for. Typically very small, like 5 or so. When creating a TextMesh Pro font asset, use that size instead of auto sizing. Otherwise you'll get misalignment. If there's no documentation with the font that tells you the target size, you'll have to experiment. Start with the width, in design pixels, of characters in example text.

As you don't need room for gradients, you can also set the padding to 1. As a result, you only need a small texture. You also have to set the font render mode to Raster Hinted. This ensures that the character pixels are aligned with the texels. You also get a point-filtered texture, and a default bitmap shader material.

When using the text, use the object's font size to scale the bitmap font to match your pixel size. Typically multiples of the font size used to generate the asset. That should enable you to get a perfect match.
« Last Edit: December 16, 2016, 04:28:15 AM by Jasper Flick »

doomcake

  • Newbie
  • *
  • Posts: 6
Re: Pixel Art Fonts With TMPro
« Reply #2 on: December 16, 2016, 04:34:18 PM »
Hey Jasper! Thanks for responding.

Following your instructions has gotten me super close to what I'm looking for but with some small issues.



The photo above is where I've gotten to. At a glance, it actually looks quite close to what would be acceptable. If you look closer, though, specifically, the pixels of the N, you see that some of the pixels are stretched.

Here are the settings that I've input based on your post.







And how the pixel grid fits onto the letter N:



As well, is there anything you think I should do special for the spacing in between letters?

Thanks again for the help!

doomcake

  • Newbie
  • *
  • Posts: 6
Re: Pixel Art Fonts With TMPro
« Reply #3 on: December 16, 2016, 05:43:12 PM »
So, after some playing around, I've managed to get 'pixel perfect' snapping or at least damn close to it:



Looking at the pixel grid, it's quite close!



I'm honestly not sure why it's looking the way it is. I've really just been playing around. Here are my settings:







I would love it if someone out there could explain why this works. Font size is 16 in the asset creator and font settings, yet 30 font size on the text object looks the best? Huh? Sorry for being obtuse, but I really don't understand this. Another interesting thing to note is that whenever I increased the font size in the asset creator the font got more accurate to the pixel grid. Strange!

Thoughts?

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Pixel Art Fonts With TMPro
« Reply #4 on: December 17, 2016, 12:55:51 PM »
Increasing the sample font size effectively makes each pixel less relevant. This decreases the visible pixel misalignment. But of course it should just work with the desired pixels.

I see from the screenshot that you're using the silkscreen font. I grabbed that and had a look. Turns out that it's designed for font size 8. So use that size when generating the font, not 16. That allows you to decrease the texture size to 64 by 64.

When using the same font size used to generate a font asset, one Unity world unit will cover ten font pixels. So font pixels of a text object set to font size 8, using silkscreen imported at size 8, will cover 0.1 unit. Set the object's font size to 80, and one font pixel will cover one unit. If you want them to cover 3 units each, set the font size to 240.

Alternatively, set the scale of the font asset to 80 or 240. Then you can set the font size in the text objects to 1. That might be convenient, if you want to use double-size text somewhere. Then you can just use font sizes 1 and 2 in the game objects, instead of 80 or 240 and 160 or 480.

If you align your text objects correctly, you should now get grid-aligned text. You can get more feedback about line and character placement by adding the TMP_TextInfoDebugTool script to your text object.

Another thing to keep in mind is that the bitmap shader does pixel-snapping of vertices as well. This can cause issues when your camera is not properly pixel-aligned itself. Font pixels that get misaligned will end up squashed or stretched, at the display-pixel level.
« Last Edit: December 17, 2016, 01:03:07 PM by Jasper Flick »

doomcake

  • Newbie
  • *
  • Posts: 6
Re: Pixel Art Fonts With TMPro
« Reply #5 on: December 17, 2016, 06:05:03 PM »
Almost there, Jasper!

The font is now snapping really well. Take a look:











As you can see, I didn't set my font sizes to what you suggested. The reason being the my pixel per unit scale for my game is actually 16, not 10. Seems to work, though.. Thoughts?

Also, you mentioned that the bitmap shader would stretch and squash the font as the camera or font moved. That does in fact happen. So, what I'm wondering is, am I doing something wrong with the camera positioning, or should I not use the bitmap shader?

Here is my cam ortho size math: (resolutionHeight*0.5f)*(1.0f/16.0f)

For the position of the camera, I'm just snapping it to a grid based on pixel size.

Lastly, should I use 'Othrographic Mode?' I noticed it in the TextMeshPro inspector..

So far, the only remaining issue is the squash/stretch while using the bitmap shader.

Really appreciate your help on this!

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Pixel Art Fonts With TMPro
« Reply #6 on: December 18, 2016, 05:45:18 AM »
Orthographic mode shuts off perspective correction, but this is only an issue for the SDF shaders, not the bitmap shaders. Having said that, it also scales up the text x10, so one texel covers one unit when using a font size equal to the import font size. So that's more convenient.

The deformation is most likely due to misalignment. You can disable pixel snapping in the shader, but then you'll get blurry text, as the texels still will not be aligned with the display pixels. You really have to make sure that they match.

Is there a good reason to use 16 pixels per unit? It is more straightforward to use 1 pixel per unit.

For example, I used 1 pixel/unit.

Imported font is unchanged.

Used a text object with font size set to 8, the same used to generate the font asset. Set the text object to orthographic as well.

Used a preview display of 640x480. Set the camera orthographic size to 80. This will map each unit to exactly 3x3 pixels.

Created a mock-up grid with some cubes. Made sure everything is positioned using integer coordinates, including the camera.

Here's the result.

[ Guests cannot view attachments ]

Note that I used an explicit preview size in Unity. It doesn't work as well with arbitrary window sizes, which can have odd pixel counts. At least, that's the case for me on a retina Mac.
« Last Edit: January 17, 2017, 12:10:20 PM by Jasper Flick »

doomcake

  • Newbie
  • *
  • Posts: 6
Re: Pixel Art Fonts With TMPro
« Reply #7 on: December 18, 2016, 12:23:24 PM »
Success!

Took your advice about changing to a pixel scale of 1 PPU. I had it at 16 PPU because of Unity physics but realized that I'm not really using the physics at all, so what's the point. And it makes much more sense to work at a pixel scale with a pixel style game. That being said, changing the PPU didn't solve my deformation issue! The real problem was that I had a half pixel offset being applied on my camera's position. Like you said, the camera wasn't positioned correctly. Taking out the offset fixed the issue. Ugh. Silly me.

Now, everything looks great! Check it out:





And for anyone else who has any issues, here are my final settings for TM assets just in case you need reference:

Text Asset:




Asset Creator:


Jasper, thanks very much for your help and patience! You are awesome. I'll make sure to give TMP a good review!

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Pixel Art Fonts With TMPro (Solved)
« Reply #8 on: December 18, 2016, 01:16:32 PM »
Good to hear that you got it working! Looking great.

In case you do need physics at some point, you can adjust physics settings like gravity and penetration to work with any scale.
« Last Edit: December 18, 2016, 01:18:29 PM by Jasper Flick »

doomcake

  • Newbie
  • *
  • Posts: 6
Re: Pixel Art Fonts With TMPro (Solved)
« Reply #9 on: December 18, 2016, 01:21:44 PM »
Ah, you're right! Thanks again! :D