Search Unity

TextMesh Pro How to change underlayColor on TextMesh Pro without breaking batching?

Discussion in 'UGUI & TextMesh Pro' started by xVergilx, Jan 23, 2020.

  1. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Title.

    Since underlay color is only accessable by accessing fontMaterial, and it creates a different material instance each time, is there a different way to do it?
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Besides vertex color which is unique per text object since it is part of the geometry, all other visual treatment like Underlay Color are handled by the shader and set via material properties.

    Since batching is done per material, you need different materials to achieve different visual styles. Although each visual style requires a unique material (Material Preset), this is normally fine as even though a project may contain 100's of text objects on screen, most of those objects normally share material presets which would batch among themselves.

    The idea is to create (1) material preset for each unique visual style / varying material properties and to assign this common material preset to objects that require that visual style. Most of the time those material preset are created in the Editor and part of the project. However, sometimes materials need to be created at runtime but instead of changing the underlay color on lots of objects, you should create only one material instance with the desired property and then assign it to all text objects that require it.

    Instead of using the fontMaterial property which creates an instance of that material (just like accessing the material property of the renderer does) use the fontSharedMaterial property which doesn't create an instance. This will ensure batching occurs between all those materials and objects. So if your project has 4 unique visual styles then you should be getting 4 draw calls assuming you stay within the batching guidelines. Not the Canvas system handles batching differently so this may vary but creating and sharing those material presets in all cases is the way to go.
     
    xVergilx likes this.
  3. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    That's what I've thought at first. Maybe using multiple shared materials is the way to go.

    Problem with material presets is that I can't really determine which text should have which underlay material since colors are generated randomly in runtime.

    This gave me some ideas. Thanks :)
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    For coloring of the text, you should be using vertex color since that is part of the mesh and unique per text object and has not impact on materials.

    For other properties like Outline, Underlay, Glow colors, etc then you do have to alter / create different materials but like I said instead of creating a new material per text object, it would be to create only one instance of a new material and to then share it with objects that should have the same visual style / treatment.
     
    xVergilx likes this.
  5. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    For some reason with Unity 2019.2.21f1, if I assign fontSharedMaterial, some letters are shifted. E.g.
    upload_2020-3-18_17-28-25.png
    g becomes j for some reason.

    Tried upgrading to 2.1.0-preview 8, same results;

    Any ideas? @Stephan_B
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I would need some reproduction project / simple scene to look at.

    Is the behavior consistent with a different font?

    Does it happen to any text object?

    Just trying to see if we can narrow this down.
     
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Okay, I think I've figured out what went wrong. That's my fault;

    I have a shared material lookup that is based around colors, and different texts have different materials (which look really similarly, because one is used in main menu, and other one is used in game).

    But they share same identical color. Which completely messes up logic.

    Plus programming doesn't work like this. Duh.

    Sorry for bothering you. I should've noticed this prior.
     
  8. segant

    segant

    Joined:
    May 3, 2017
    Posts:
    196
    I think he will do shadergraph shaders to support srp. But don't know when he will :)
    As i know shadergraph doesn't support stencil buffer. So it depends on shadergraph team.
     
  9. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Do we have any plan to utilize materialpropertyBlock or materialpropertyDots feature to override color on those property?

    I think just making difference shadow and outline color/thickness/offset in the code should be efficiently handled by this feature
     
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    MaterialPropertyBlocks is not support by the Canvas system :( Otherwise I would have added support for this a while back.

    On a side note, the best way to handle this remains to create and use Material Presets where those property are predefine and then sharing / assigning those presets to the relevant text objects via the fontSharedMaterial property.

    You could also create a new material instance with the desired settings and then sharing / assigning this instance material to the text object via that same property. This would avoid having unique instances per text object thus further increasing the draw call count.
     
  11. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Those are what I have did but there are so many constraint, such as when we just want dynamic color text and want to change outline/underlay color to oppose the text color on the fly. Requiring to clone material preset that exactly the same parameter except color is tedious task. And when we have dynamic coloring (user picked) it was impossible make preset