TextMeshPro performance

Under the known issues for 1.0.3, it mentions the following

  • Runtime updates of TextMeshPro text content can cause significant performance issues.

Is this an issue new to 1.0.3 or has this persisted in previous versions too? Also would this be expected if the TextMeshPro instance wasn’t tracked by a PolySpatial tracker?

Hi @LandAndSte

This is not a new issue, and the performance issues we’ve sometimes observed with TextMeshPro are not always present; they seem to result from a combination of factors we haven’t yet tracked down. We added this known issue mostly as breadcrumb for developers to follow: if you’re seeing significant performance issues from dynamic text updates, try turning them off.

And yes, disabling tracking for your TMPro GameObjects - for example by using the ignored objects layer mask in the PolySpatial Settings - should likewise shield you from any performance issues here.

We are actively looking at these performance issues, too, and hope to improve the
situation in the future. Hope that helps!

–Tim

Thanks @timc-unity!

We have been encountering some issues that I suspect are related to TMPro text updates. However, I have been using the “Ignored Scenes” functionality via PolySpatial Internal, so I assumed that this would prevent them from being tracked.

I’ll try disabling the “Platform Text” tracking as well as using the Layer Mask and see if there’s any improvement!

TMP updates have always been slow and best avoided, but can be even more so in PolySpatial due to all the mesh objects having to be sent to RK and regenerated there too.

Typical way to deal with this, even outside polyspatial, is ensure any TMP components that continually change are on their own sub-canvas. This can isolate them from change events occurring elsewhere in the Canvas and avoid unnecessary regeneraiton.

This is good workflow for anything in a canvas. All things static and never-changing can be on one canvas. Anything that moves or changes should be on a sub-canvas.

Thanks @RyanGoodrichUnity!

There are certainly things we could do to optimise our Canvas updates, but this hasn’t affected us on other platforms. I think the reason for the thread was that this issue with TMPro was called out in the release notes, and I wanted to know if this is something we should be expecting to have to contend with in a way we wouldn’t for other platforms.

Just to clarify something on this point:

For our specific use case, we aren’t rendering any TMPro assets inside our PolySpatial Volume. We are rendering a stereo camera setup in our standard scene and outputting them to RenderTextures on objects in a separate PolySpatial scene. I am using a specific layer for objects inside our PolySpatial Volume, and I have excluded every other layer within the PolySpatial Settings. For good measure, I have also disabled the “Platform Text” tracker in the PolySpatial settings also.

Given this, would you still anticipate we would be taking the greater performance hit you describe? Or more specifically, is this related to the PolySpatial implementation or visionOS as a platform?

Everything gets replicated to RK side right now which is not in the ‘Ignore Object Layer Mask’ in PolySpatialSettings.

We are discussing and going through some designs right now to improve this and have individual volume cameras be more controlled in what exactly gets replicated and how.

It appears that the issue that TMP is so extremely slow on instantiate and text updating is

  1. that it uses the default Vertex Helper functions to build the meshes which is way overkill to build quads
  2. It builds a ton of very slow lists instead of doing a struct

According to AI these are the bottlenecks

The TMP class being 5000 lines is also not really best practices.

In the Profiler, TextMesh Pro related stuff is labeled as TMP_ . In the above profiler sample, Text.UpdateGeometry is the UGUI Text component.

As noted, this looks like you are using old UGUI text support and not the UGUI w/TMP. The recommendation is to update to TMP supported text in UGUI.

As well, if this is still an issue please file a bug a note the incident number (IN-XXXXX) here, please.

When I profile TextMeshProUGUI, the one that the editor also promotes in the context menu, I can see that actually the majority of the CPU time tmp is using is being spent on TextMeshProUGUI.GenerateTextMesh() and actually not for the part where it generates the 3d geometry but the preliminary checks.

This function is total mess, I can not remember in 10 years seeing anyone write a 2500 lines function.

It seems there is a lot of stuff being checked that is almost never the case for example

bool isBaseGlyph = TMP_TextParsingUtilities.IsBaseGlyph(charCode);

is called for every character which is a giant block of || that is practically never true so the cpu will have to check every last option there. Judging by the comments there this seems to be for special thai, arabic etc characters.

Many, many things here look like they can be entirely skipped by just checking for character being in a-Z range and maybe other typical characters ranges.

It may be possible that there is some hidden optimizations that me and gemini 2.5 are missing, after all it, is a 2500 lines function.

For reference the GenerateText Phase 1 section is for me in my tests 0.1ms, the actual mesh handling later barely registers.