It doesn’t quite work out-of-the-box, but it’s easy to fix.
To have crisp, scaleable images in your UI and be able to apply the same kinds of effects to them (outline, glow, underlay) as you might apply to your text, you might want to have SDF-based images in your UI. Like me, you might have tried using Text Mesh Pro’s shader before, saw it didn’t work, looked up a solution online, didn’t really find one, and then gave up. Using a SpriteRenderer seems to work but that doesn’t play nice with layouts and such. I finally sat down and figured it out, and it turns out it’s actually not that complicated.
General setup
You will need to author a texture as a Signed Distance Field. I won’t go into what SDF’s are, there are many good resources for that online. An easy way to author one in Photoshop is to make a shape and apply a Stroke style to it with a Fill Type of Gradient (from black to white). Make sure the Position is set to Center and the Style to Shape Burst. Also check that the Method is set to Classic. Harry Alisavakis has a great blog post about authoring SDF textures in Unity.

Next up you can create an Image in your UI like you normally would and assign your icon to it. Now we need to create a material for it. You can try assigning the TextMeshPro/Distance Field shader to it just to confirm that it indeed does not produce any visuals, then assign the material to the Image component.
Fixing the Distance Field shader
We need to make some tweaks to the standard Distance Field shader. Duplicate “Assets/TextMesh Pro/Shaders/TMP_SDF.shader“. Call it something else, for example “TMP_SDF_Icon.shader” and change the shader path to Distance Field (Icon) (the first line of code). Now there are two changes we need to do:
Firstly, we need to add [PerRendererData] above the _MainTex property. This is necessary for the Image component to be able to pass the assigned texture along to the shader. TextMeshPro itself handles this differently.
![[PerRendererData] is added above the _MainTex property at line 60.](https://usercontent.one/wp/blog.roytheunissen.com/wp-content/uploads/2025/10/image-1.png)
Secondly, we need to make sure that texcoord0.w has a value of 1. In TextMeshPro this seems to be passed along as the default value, but if you use an Image component this will remain at 0, causing the pixels to not be visible. You can add this at the top of the VertShader function:

Now assign your new shader to the material you created previously. It should now work!
Closing thoughts
It’s worth considering creating a custom text font for your icons instead, this would be more efficient rendering-wise. However, workflow-wise, being able to just use an Image component is very convenient. For prototypes or small projects that might be the preferable approach.
