Search Unity

Question TMPro: Same text looks fine on UI but blurry in 3D

Discussion in 'UGUI & TextMesh Pro' started by Alan47, Mar 17, 2021.

  1. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    I'm currently implementing a trading-card game on on Unity 2020.2.6f1. Card text legibility is very important for this genre. I'd like my cards to be 3D objects so I can move them around in the world. I'm currently struggling with the following issue:

    upload_2021-3-17_19-45-56.png

    Both texts use the same font asset. The left one is a 3D text attached to the 3D card object, the text on the right I've hand-placed as a UI object that just happens to be in that location (i.e. it's for demonstration purposes only, I can't actually use that). The screenshot has been upsampled in Unity's game view by a factor of 3.4 to make the problem more apparent. Here's what it looks like at 1:1 ratio:

    upload_2021-3-17_19-48-16.png

    As you can see, the UI text is much more legible and a lot sharper than the 3D text (however, I wouldn't mind achiving an even sharper version if possible).

    Here are my font settings:

    upload_2021-3-17_19-53-59.png


    Is there anything I can do to improve the readability of the 3D version? Aside from making it bigger / zooming in with the camera, of course.
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    The issue is likely related to object scaling.

    Can you post an image showing the RectTransform values of that text object?

    Can you also post an image showing the text component inspector?

    Also add an image of the material inspector of that text object with the debug section of the material inspector expanded.

    P.S. The text should be rendering as nicely in 3D or 2D. We just need to figure out what specially here is causing the issue.
     
  3. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    @Stephan_B Thank you for your quick response! I'm relieved that this isn't the expected result. I read in your other posts that transform values can be an issue and I did play around with them (making the rect transform bigger and font size smaller and vice versa) but it didn't seem to do much. I watched your tutorial on font asset generation and followed your advice. The result of that is pretty much what I've shown in the opening post.

    Here is the full prefab (I fit as many settings on it as I could):

    upload_2021-3-17_22-8-2.png

    The prefab itself (which is the parent of the text object) has always a scale of 1.0/1.0/1.0, and this won't change in-game.

    Here are the shader settings - they're pretty much all at default:

    upload_2021-3-17_22-13-20.png

    Based on your post, I guess that the ratio between rect transform size and font size is somehow off the mark?
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    In order for the text to render correctly. The scale of the text object should be uniform. Ie. X, Y, Z all using the same value. Right now you have (0.12, 0.12, 1). See if setting everything to (0.12, 0.12, 0.12) makes any difference.

    Next, see if replacing the shader which is "TextMeshPro/Distance Field" by the Mobile SSD version results in the text rendering more clearly. The SSD variants of the shaders are contained in the latest TMP Essential Resources and have the suffix SSD at the end of their name. You will want to use the "TextMeshPro/Mobile/Distance Field SSD"
     
  5. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    @Stephan_B Sorry for the late response, I can currently only work on this project in the evening / late night hours.

    I've applied your suggestions with the uniform scaling and the mobile distance field SSD. Here's what it looks like in the editor:

    upload_2021-3-18_19-49-29.png

    Totally fine and crisp, but that has been the case before as well (also I'm on a 4k monitor, that helps too. The game is designed for 1920x1080).

    As for the game view...

    upload_2021-3-18_19-50-5.png
    (1:1 ratio, no game view scaling applied)

    Nothing changed here unfortunately. Both cards are 3D objects with 3D text, they're at the same scale, the top one is just closer to the camera.

    Noteworthy facts:
    - both 3D card objects are parents of the scene root, so no parent transforms are messing with the scalings.
    - I've made sure that post processing isn't doing anything funny by disabling the global volume (the scene is the default scene from the URP template). It didn't have any visible effect on the text.

    So... overall unfortunately no real progress. It just occurred to me - does it make a difference for the text rending which pipeline I'm using? I'm on URP, targeting WebGL. The in-game screenshots are taken in the editor game view.

    Is there anything else I can try?
     

    Attached Files:

  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    The SSD shaders should have made the text render clearly.

    Can you provide a simple reproduction project for me to look at? Easiest way might be for you to submit a bug report with the project and steps.
     
  7. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    @Stephan_B I've submitted a Unity bug report via the editor's bug reporting tool. Sadly it didn't give me a link to the report otherwise I could post it here... The title starts with "TextMeshPro" and it was submitted as an "editor problem", I hope that's sufficient information for you to find it.

    Luckily, 99% of the work on this project has been done in code, so I could just rip that out.

    I'm sorry for the trouble, I really hope it's not something stupid on my part that I just missed. Thank you again for your support!
     
  8. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    When submitting a bug via the Bug Reporter, Unity usually sends you an email that contains the Case # within a few minutes. Once you get that case, just edit your previous post or just post it here.
     
  9. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    Thank you for providing the repro project.

    It looks like the behavior is simply due to Anti-Aliasing on the Camera where FXAA is causing this blurriness. Setting Anti-Aliasing to None or SMAA should result in the text rendering nicely.
     
    Underwaternya likes this.
  11. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi Stephan, piggy-backing on this thread as you've mentioned the SSD shaders here. I'm hoping @Alan47 won't mind.

    I was having a problem with the SDF shaders on an overlay canvas getting blurry when changing the game view resolution in the editor to lower resolutions. I tried the SSD shaders which fixed the problem, but noticed that the SSD shaders add a little bit of unnecessary brightness to pixels just above and below characters, while also introducing some additional unwanted artifacts outside of the characters.

    With large point sizes, this is practically unnoticeable, but at small point sizes, this makes the text a little bit "fuzzier" (for example on a screen space overlay canvas set to scale with screen size, with reference width @3840x2160, and text pt size of 20, using noto sans). When changing the game view resolution down to 1366x768 or 1280x720, you can notice it ever so slightly, and it becomes more obvious when zooming the game view.

    I know I'm being nitpicky here, but is there anything that can be done to the SSD shaders to prevent those small artifacts? Otherwise, the workaround of using non-SSD shaders and doing a ForceMeshUpdate() on every single text component when changing resolutions is doable, but kind of a hassle.
     
  12. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    I think those artifacts might be related to material property values being too large relative to the ratio of sampling point size to padding where at small point size you end up with bilinear filtering reading in the adjacent pixel in the texture.

    I would suggest re-testing this with a font asset with larger sampling point size to padding ratio to see if you observe the same behavior.
     
  13. Alan47

    Alan47

    Joined:
    Mar 5, 2011
    Posts:
    163
    Oh. My. Goodness. Thank you, that did the trick! In defense of my honour, that setting came from the default scene, I didn't put that in there :oops:
     
  14. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    Glad we figured it out and thank you for providing the repro project as this made it easy to find.
     
  15. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    I just tried a wide variety of sampling point size to padding ratios, from anywhere 10% to 100% at different point sizes, but it doesn't change how the Distance Field SSD shader adds a few pixels in comparison to the default Distance Field shader.

    However, when a material is set to Distance Field SSD, adjusting the Dilate property on the material to slight values (-0.05) below 0 does indeed bring the Distance Field SSD shader to be almost exactly the same (loses 2% of brightness) as the Distance Field shader with Dilate set to 0, so yay!

    Now I don't have to call ForceMeshUpdate() everytime the resolution changes by using the SSD shaders without any real compromise in quality. Thanks!
     
    Last edited: Mar 20, 2021
  16. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    I would love to take a closer look at this. Any change you can provide a simple repro project / scene exhibiting this behavior?
     
  17. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Sure, I uploaded a simple project with some lorem ipsum text.

    Open the Sample Scene, then notice there are two UI TextMeshProUI components: DistanceField and DistanceField SSD.

    They have different materials, but at start both are using the Distance Field shader.

    Zoom in the Game View using the Scale slider, even to maximum of 5x. The canvas is set to match height fully with "Scale With Screen Size" with reference resolution at 4k.

    You can change the DistanceFieldSSD component's material to the Distance Field SSD shader, and by undoing and redoing again and again (switching shaders), notice how the bottom component's text gets brighter and a few pixels are brightened/strengthened around the edges of each character, when using the SSD shader. This happens at all resolutions, but is especially noticeable at lower pc monitor resolutions like 1366x768 or 1280x720.

    In addition, if you leave the DistanceFieldSSD component to have the SSD shader, set the Game View to 4K with game view Scale 1x, dirty both text components so that there is a ForceMeshUpdate(), then switch Game View from 4K to WXGA (1366x768) at Scale 1x or 1280x720 at Scale 1x, you can see clearly how the Distance Field shader stays blurry while the SSD shader adjusts to be clear.

    Setting the Dilate of the SSD material to -0.05 brings it roughly in line with the look of the non-SSD material, but at a very slight cost of brightness (I used the color picker to test).
     

    Attached Files:

  18. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,596
    Thank you for providing the project for me to look at.

    The rendering differences between the baseline SDF and SSD variants is pretty subtle as seen below.

    These are captures of the Game view at 1x (no scaling) at 3840 x 2160. Game view scaling is not accurate and should never be used for these types of comparisons. The images are then imported in Photoshop where I zoom in so we can see the actual pixels without any filtering / scaling applied.

    upload_2021-3-21_16-48-54.png
    Baseline SDF at 1500%

    upload_2021-3-21_16-49-52.png
    SDF SSD at 1500%

    Same text but at 1280 x 720.

    upload_2021-3-21_16-53-51.png
    Baseline SDF at 2000%

    upload_2021-3-21_16-54-9.png
    SDF SSD at 2000%

    With the baseline shaders, scaling information has to be passed to the shader in the geometry. Baseline shaders are more accurate but requires this scaling information be updated any time the scale of the text object changes which includes resolution changes which is why in some cases, it remains fuzzy or overly sharp until the text object is updated.

    SSD Shader on the other hand, do not require scaling information be passed to the shader as they use Screen Space Derivate. This has a higher performance overhead as the screen space derivative has to be computed per pixel in the fragment shader whereas in the case of the baseline shader, it is handled in the vertex shader.

    There are subtle differences between these two types of shaders which are easier to observe at lower resolution. However, a big part of that is amplified by the fact there are very few pixels to work with.

    Adjusting Sharpness located in the debug section of the material inspector will affect the result but keep in mind that what seems sharper to you may not to someone else as people evaluate text readability differently which is also greatly affected by monitor settings / gamma, etc.
     
    Korindian likes this.
  19. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Yes, after reading your changelogs and some earlier forum posts, I understood that the SSD shaders would solve the problem of resolution changes needing the materials to provide updated scaling information.

    I agree that the differences are very very subtle, almost unnoticeable at 1x Game View @ 1280x720, but I was trying to get the most crispy clear small fonts as possible and so was paying very close attention. I was only zooming in the Game View to get an understanding of why I was seeing slight differences between the shaders at the pixel level, such as the extra pixels to the right of the last "s" of "shaders" in your screenshot.

    I was using Dilate to compensate for the changes, which affected the brightness, and didn't even know there was a "Sharpness" setting to play around with that doesn't affect brightness, so that solved yet another problem!

    Everything you posted above would be great information to have in any future docs for TextCore or Text Mesh Pro.

    As I mentioned earlier, I'm quite happy with the SSD shaders, as it means less work for me to have to update text components on resolution changes. Thank you for providing them, and thank you for being extremely responsive on the forums!
     
    Last edited: Mar 22, 2021
    Stephan_B likes this.
  20. wagenheimer

    wagenheimer

    Joined:
    Jun 1, 2018
    Posts:
    323
    I'm facing a similar issue where the text in my 3D scene is being affected by the "Anti Aliasing" feature, which I cannot disable. I'm wondering if there's an alternative approach to ensure that the TextMeshPro text on the World Canvas remains clear and sharp, even when FXAA Antialiasing is being utilized?

    Scene View
    upload_2023-3-29_16-58-47.png

    Game View

    upload_2023-3-29_16-59-6.png