What is the recommended solution for adding outlines or shadows to bitmap fonts (font assets created using the Hinted Raster setting)?
I made a custom shader to do this in the meantime, but my shader skills are lacking. The shader uses a total of 5 passes to render the text 5 times with different offsets applied to the first 4 passes. Obviously this is not good for performance, and it’s very limited in terms of customization.
Attached is an image of what I’m working with below. I would love to see support for outlines and shadows in the material settings for the default bitmap font shader!
The ability to dynamically style the text in TextMesh Pro is a bi-product of the use of Signed Distance Field and associated shaders. When using SDF Font Assets, adding outline / shadows is pretty efficient.
Adding shadow and outline to bitmap fonts is much more complex and not currently supported as it is not very efficient.
Unfortunately I can’t use SDF in this case because I need a crisp 12pt font and Hinted Raster seems to be the only way to achieve that.
I was using Unity’s Outline component with the UGUI Text component before I switched to TMP. I need to replace it with something.
PS. TMP has been a lifesaver on many levels, especially with the fallback system for localization. Excited to make use of the native Unity integration.
To anyone who stumbles into this thread and wants to use the shader: Here it is. Be warned it is a terrible hack job. If you improve it, please share.
Same problem here, we have to use Hinted Raster param to have a good looking pixel art font with TM Pro. Why don’t you make a shader to have some parameters with Bitmap Fonts (like outline, underlay…) ? I understand it’s not “very efficient” but when it’s the only solution…
Thanks rempelj for your shader, I will try it on my project.
The ability to dynamically add an Outline and Shadow (underlay) using the shader in TMP is a by product of using Signed Distance Field (SDF). This is why this functionality is not available on the bitmap shaders.
Ok, but it is possible to have outlines and shadows by customizing the TMP_Bitmap shader, so why not adding them ? I’m not good at all when it comes to write shaders so I would love to have this included in TextMesh Pro. I love it so much, I really miss it on my pixel art fonts.
PS : I’m really upset to see that I’m paying a subscription for Unity every month and the answer is always “we won’t do anything”, even when it’s a critical bug for us (it’s not the first time I experience that).
Other than a shader it is also possible to get the same outline look using a mesh effect where you add additional vertices with the vertex color set to black.
The old Unity text component supported mesh effects, but Textmesh Pro doesn’t support them out of the box.
This project is attempting to enable mesh effects with TextMesh Pro. It works, but it’s a bit buggy and breaks in certain situations. The project comes with an example mesh effect that creates an outline using the method I mentioned above.
The developer is responsive. If more people ping them, maybe they will get around to fixing the remaining issues.
when i try to use their unitypackage, it says type or namespace ‘UIEffect’ could not be found. Any idea why? It seems like it doesn’t exist in Unity2019.3.0f6, is it a custom class?
Although I don’t have a solution to propose at this time, I wanted to reply to let you all know that I am reading all these posts / threads and keep tracking of all these feature requests.
I extracted the atlas and used Photopea.com (online Photoshop) to create a special variation of the atlas with the following rules:
Red = Font Face (default)
Green = Outline
Blue = Drop Shadow
Background is fully black, uses R/G/B in custom shader as alpha.
I’ve attached a PNG & PSD of this.
The shader then uses 1 texture read to handle the default face/outline/drop shadow. You use the Outline/Shadow color picker alpha to turn on/off the feature. You can also use a Face texture for things such as gradient etc.
Also looking for a better solution to this. This is specifically useful for pixel art games.
I’ve been using a custom solution where I edit the atlas to add outlines of different colors and a custom shader that repaints the texture based on the new atlas colors. But this feels clunky and it shouldn’t be this much of a hassle to add a custom shader to TMPro
I believe this still is the “best” approach, as doesn’t require extra render passes.
I’d say that applying a 1 pixel offset/stroke is well within the capabilities of TextMeshPro.
We probably don’t even need an RGB texture, as we could use specific grayscale ranges to encode the zones:
font face(255), outline(+128), drop shadow (+64). Of course it has to be an 8bit grayscale image.
The “lazy” (but more versatile) way would be to just use more passes. Again, TMPro could do this natively, baking the contour in the atlas, without requiring us to use a 3rd party program.
In both cases these would be useful examples that could be included in the Samples package of TMPro.
With so many pixel art/mobile/retro style games, would make sense to have this natively integrated.
…unless there’s another more straightforward way to do this that I’m missing…
The shader is still pretty messy, but I can give a general overview of how it works.
First of all, we need to extract the text atlas, and pass it into our shader (PS. make sure the Texture2D node does NOT have a reference of “_MainTex”. I was burned by that for a while).
The only gotcha, is that the shader needs to get the atlas passed to it to know what to outline. Unfortunately, I don’t think there’s any magic reference to pass the atlas through like “_FontAtlas” as far as I know (like there is for “_MainTex”)
So we just treat it as a 2d texture instead.
When we apply our shader, we have to pass in that font’s atlas:
There’s also a few other things i have set here, like the outline color, and the font override color.
So the whole “font atlas” thing means that it’s still a little more tedious than it should be, but i think this solution beats having to extract the font into another editor/program and mess with it there first. It would be a much simpler solution if somehow TMP passed the atlas as part of the _MainTex property, but oh well.