Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

TextMesh Pro How to: Apply TMP Shaders to a Sprite with SDF gradients built in?

Discussion in 'UGUI & TextMesh Pro' started by april_4_short, Jul 29, 2021.

  1. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    If I've managed to make a shape/vector piece of artwork, and apply an SDF 'blur' to it with Photoshop, and imported it as a Sprite into Unity, is there a way to apply TMP shaders to it?
     
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Although looking at a texture that contains SDF data appears as a "Blur" that is not the case. Textures that contains SDF data are usually 8 bit or 16 bit alpha where the alpha value represent the distance from a given pixel to the nearest feature / edge. See the following article / blog post which provides a nice overview of the above.

    In regards to using custom shapes / vector artwork to be eventually rendered using the TMP shaders, here is my recommendations.

    The simplest way is to create a custom font (.ttf) file that contains all the desired shapes. There are several free web tools that can be used to take .png images or .svg data to include in a custom font. One of the web sites that I use is Icomoon.io.

    On this site / app, you can import your artwork, assign a Unicode point to each character and then create a custom font that includes these shapes. Once you have this custom font you can create a font asset just like you do with any other font files. Since by default these custom shapes will be placed in the "Private Use Area" of the Unicode which is \uE000 to \uF8FF, you will need to either use a custom hex range in the Font Asset Creator or if you assigned specific Unicode to each of these shapes, again manually pick the custom character range to include in the font asset.

    Once you have a font asset created from this custom font file, you can use it like any other font asset.

    P.S. I have to jump into a call but I have made posts about this previously on the forum here. A quick search on Icomoon or something should reveal those posts. Some of these includes how to use several shapes to create a composite shape which is pretty cool in terms of use case.
     
    april_4_short likes this.
  3. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Hey hey hey Master Stephan,

    Your font building suggestions I'm already doing, results soon.

    Have also been researching how to make the SDF blur in Photoshop, and want to do some odd shapes with it, that way, and then attempt to make a dynamic, spline based means of making new ones.

    Sorry to trouble you more, again... is it possible to add a TMP shader to a Sprite?
     
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Faking SDF data by using a blur in Photoshop is unlikely to yield the results you seek.

    Having said that and for testing purposes you can change the shader used by any given sprite asset by selecting the sprite asset and then double clicking on the Default Material and then changing the shader used by that material. This will enable you to test if applying a blur in Photoshop will yield the desired effect.

    If the above works, I can then explore ways to perhaps make that workflow easier including the ability to use different materials with sprite assets.
     
  5. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    There seems to be issues with the shader and UVs. It's searching, I think, for info you have in the way you make the Textures, and not finding equivalent in the Sprite.
     
  6. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    I've done quite a bit of research into how to do this, and can get quite interesting and ideal results, doing what I want, which is changing the rate of gradient. I'm using the word blur simply because it's the easiest word to say it, but it is, as you rightly point out, a perfect gradient that defines edges, which is SDF...a signed distance field, etc.

    Why I'm using Photoshop is simple: I want to change the rates of that gradient to get some interesting falloff effects. Until I've got it working, you'll just have to trust that I know what I'm doing. But I'm by no means the first to figure out how to create SDF gradients with Photoshop, just the first to plan to change the rate of that gradient to do specific things, namely to make super cool looking buttons.

    Yes, those things could be done with maths in the shader. But the maths is beyond me, and the size of these "blurs" is quite large (and soft) so otherwise prohibitively expensive to do with TMP Font Creator, and jiggling maths is more difficult for me than rapidly iterating on 'blur' gradients and their falloffs, saving and then reloading them in Unity... iterate... etc.
     
  7. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    488
    Sorry for necroing this thread, but I'm attempting something similar right now.
    I've downloaded a SDF sprite sheet for testing purposes (source here), created a SpriteAsset from it, and applied a new Material using TextMeshPro/Distance Field (Surface) shader to the Sprite Asset.
    This seems to work overall visually, but modifying values in the material's inspector throws a NullReferenceException each GUI tick:
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. TMPro.TextMeshPro.GenerateTextMesh () (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TMPro_Private.cs:1943)
    3. TMPro.TextMeshPro.OnPreRenderObject () (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TMPro_Private.cs:1562)
    4. TMPro.TextMeshPro.Rebuild (UnityEngine.UI.CanvasUpdate update) (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TextMeshPro.cs:280)
    5. TMPro.TMP_UpdateManager.DoRebuilds () (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TMP_UpdateManager.cs:177)
    6. UnityEngine.Canvas.SendWillRenderCanvases () (at <373946aef99e4cf29a4263b23aa7a8c1>:0)
    Right now this also means I'd have to make a new material for each sprite sheet I include since the Atlas needs to be manually set, which is a bit of a clutter problem.
     
  8. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    53
    Sorry for necroimg this thread too but it is very top ranking in Google. You can already make SDF shapes yourself by using photoshop's precise glow layer effect on a white image, then create a material and set this image as a font atlas, then add it to a quad or sprite renderer. Check this tweet for details how to implement it, as it isn't hard and these TMPro shaders are holy grail themselves.
    https://twitter.com/petersvp/status/1617095132314210306
     
  9. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    472
    How do you apply the TMP shaders/materials to the Sprites, or the "as a font atlas" part of the process?