Author Topic: Underlay Applied to All Text Mesh Pro Instances  (Read 4162 times)

abobick

  • Newbie
  • *
  • Posts: 6
Underlay Applied to All Text Mesh Pro Instances
« on: September 01, 2015, 02:31:46 PM »
I tried searching for a similar topic but couldn't find one, so I'll ask it here.  I enabled underlay effect for one instance of UI, but when I created another instance of text Mesh pro, its underlay settings are feeding from the first one.  Is this the intended behaviour?

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5362
Re: Underlay Applied to All Text Mesh Pro Instances
« Reply #1 on: September 01, 2015, 02:50:59 PM »
I tried searching for a similar topic but couldn't find one, so I'll ask it here.  I enabled underlay effect for one instance of UI, but when I created another instance of text Mesh pro, its underlay settings are feeding from the first one.  Is this the intended behaviour?

This is standard behavior in Unity and there are a few posts already covering this but most refer to other material properties like faceColor or Outline, etc... So here's the explanation.

All objects which share the same material will see changes to that material reflected on all objects using this material. Each object contains a mesh (geometry) which is made up of vertices, triangles, uvs and vertex colors and a few more things. Each mesh is unique to each object (at least for this discussion).

In order for an object to render, a material must be assigned to it. FaceColor, OutlineColor, Underlay, Glow, etc... are all material properties. So when changing Underlay or any of the material properties, all objects which shared this material will reflect this change.

When a Font Asset is assign to a text object, the Font Asset contains a default material. So when the Arial SDF Font Asset is assigned to several text object, they all share this default Arial SDF Material. Changing the FaceColor for instance of this material, will change the FaceColor on all of them.

How do you change material properties on one object and not the other?

In the Editor, you could use the built-in TextMeshPro Context Menu and create a material preset. See the following video for a full explanation of this important feature. This video also covers Font Asset Creation first and shader assignment.

Some users started duplicating Font Assets which you don't want to do. You want a duplicate of the default material used by the font asset which is what this Context Menu was added for. So using material presets, you could create an ARIAL SDF Material with some properties and then created another with different properties and assigned those different materials to different objects. Again, keep in mind that material presets are assets and any changes to the properties of those materials will be reflected on all objects that share them.

Ok so how do you get unique material for each object?

In Unity there is also the concept of Shared Material and Instanced Materials. An instance material is a temporary copy (instance) of a material. When using an object which has a Mesh Renderer for instance, accessing the Renderer.material will return an instance of the material. Accessing Renderer.sharedMaterial will return the material shared by all objects.

Assigning a material to TextMeshPro.fontMaterial will create an instance of this material. Assigning a material to TextMeshPro.fontSharedMaterial will not and this material is shared.

When Masking is used, an instance of the material is also created since masking requires unique material properties per material (namely stencil settings).

This concept of material instance and shared material is an important one to understand in Unity.

So why not use instances for every object?

In Unity each Material used results in 1 Draw call. So if 10 objects share the same material, Unity will batch those internally and you will have 1 draw call. However, if you create 10 instances of these materials, Unity will not be able to batch them and you will have 10 draw calls. Basically, it is a trade off between keeping the draw call as low as possible while getting the flexibility you need.

Special note about vertex colors.... Vertex colors are part of the mesh which is unique to each object. For simple color changes or gradient, it is more efficient to use vertex colors. On the other hand for more complex stuff, like assigning a face texture to a text object or animating glow, you have to use instances of the material.

Hopefully my explanation made sense to you :)




abobick

  • Newbie
  • *
  • Posts: 6
Re: Underlay Applied to All Text Mesh Pro Instances
« Reply #2 on: September 01, 2015, 04:26:25 PM »
Phew!

That is exactly the explanation I was looking for, thank you!

Sounds like the bottom line is I will have to coordinate with our Art Director to limit the font styles.

Thanks again for your prompt reply  :)

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5362
Re: Underlay Applied to All Text Mesh Pro Instances
« Reply #3 on: September 01, 2015, 04:46:35 PM »
Phew!

That is exactly the explanation I was looking for, thank you!

Sounds like the bottom line is I will have to coordinate with our Art Director to limit the font styles.

Thanks again for your prompt reply  :)

Using Material Presets (materials created / derived by using the Context Menu - Duplicate) from the default font material of a given Font Asset, you can still use lots of different styles.

For instance, if you had 10 text objects in a scene where all of them were using ARIAL SDF, you could easily via scripting (or in the editor) assign a different material preset to each of them to get a unique look. Assuming 3 objects shared the same material preset and you wanted to tweak the Outline thickness of just one of them, then you would create an instance of the material used by that given object and tweak its outline which would not affect to other two objects.

My point is there isn't any reason to limit the number of styles used. You just need to keep in mind how materials, material presets and instance work overall.

abobick

  • Newbie
  • *
  • Posts: 6
Re: Underlay Applied to All Text Mesh Pro Instances
« Reply #4 on: September 02, 2015, 10:09:57 AM »
My point is there isn't any reason to limit the number of styles used. You just need to keep in mind how materials, material presets and instance work overall.

Yes, thank you.

I understand what you posted earlier.  However, our app is extremely UI heavy (almost entirely).  From what you've explained about instanced materials and from our current style guide, it would require dozens of draw calls per screen just to handle the different font styles.  My take away was to, as you say, balance the performance with pie in the sky design asks. 

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5362
Re: Underlay Applied to All Text Mesh Pro Instances
« Reply #5 on: September 02, 2015, 12:39:01 PM »
My point is there isn't any reason to limit the number of styles used. You just need to keep in mind how materials, material presets and instance work overall.

Yes, thank you.

I understand what you posted earlier.  However, our app is extremely UI heavy (almost entirely).  From what you've explained about instanced materials and from our current style guide, it would require dozens of draw calls per screen just to handle the different font styles.  My take away was to, as you say, balance the performance with pie in the sky design asks.

I guess to make sure other users also reading these threads get as much information out of them as possible. Here is another piece of data that might be useful.

As already established, each instance of a material will result in a draw call. Now in some instances, you might need to use an instance to modify a Material Preset to achieve a certain visual look and assuming you had several objects which require the same change, it would be more efficient to assign the same instance to all objects which would share the visual look vs. creating an instance for each other them. This would ensure that this instance actually results in only one draw call.

You might also run into a scenario where this visual treatment is only required temporarily like to highlight a certain text object on mouse over or something. So instead of creating instances every time this happens, you would keep a reference to the original material and one for the instance. So if you have 20 text objects using the same Material Preset, when mouse over would occur, one object would use the cached instance while the other 19 batch together for 1 draw call. As soon as mouse over is done, you would re-assign the Material Preset to then have all 20 batch again into a single draw call.

Some of this information might appear obvious but time and time again, I have seen users create instances over and over instead of sort of handling material the same way you would handle object pooling. Materials can be pooled too :)