FPS drops from 60 to 30 every frame that certain properties - including image.color - are modified, even if only once

Note: I just submitted a bug report containing a project that repros this with precise instructions under IN-73929.

The Issue

Modifying any of the following fields AT ALL will cause FPS to drop from 60 to 30 FPS immediately for every frame in which their value changes:

  • Image.Color
  • RectTransform.AnchorMin
  • RectTransform.AnchoMax
  • RectTransform.Pivot
  • RectTransform.SizeDelta

All components of multi-component fields cause the drop (my project modifies them one at a time (ex: r → g → b → a).

The project I submitted provides examples of both animation and script driven modification of these properties that my team has confirmed reliably reproduces on both the visionOS simulator and visionOS device. It does NOT repro in editor.

The most concerning is image.color.

This massively impacts our FPS and get in the way of us hitting apple FPS requirements given that our UI changes image.color all over the place (and we animate the other properties as well but they might be able to be worked around).

Extra Context

One interesting note: CanvasGroup.alpha has a similar effect to image.color.a modification yet does not cause the drop.

This appears very similar to an issue we reported previously which was fixed in the next unity update after we reported it: IN-65491 (also discussed here: Animator causes FPS to drop). In that case FPS would drop any time RectTransform.Rotation was modified. I’m not sure if this issue might be related.

Question

Do you have any further insight into why this happens (including potential work arounds) and/or when it’ll be fixed?

Thanks in advance (and for the quick resolution of the rotation issue)!

1 Like

Since you are using RectTransform, I assume that this is UGUI/Canvas based objects you are modifying? If so, note that any change to something within a canvas hierarchy will require a full re-sorting and serialziation of the full hierarchy in order to keep sorting and other things inline on the host side. UGUI is very expensive in regards to keeping things in sync between the expected UGUI display in Unity and how we are able to make it work in RealityKit.

Image.Color changes may be causing texture re-serialization over the wire as well.

With that said, the big lag you see in the profiler is in WaitForTargetFPS, and AFAICT there is no PolySpatial work happening in that portion of the profiler. I’m asking around internally to see if I can get some information on what is actually happening here with WaitForTargetFPS.

I’d also caution you that the simulation FPS is NOT the rendering FPS, as that is all handled by RealityKit. To get an accurate handle on the FPS rate that is being rendered you’ll have to use Instruments to capture data on device. I would not depend on the running in or against the simulator to be an accurate reflection of real performance.

“Any” change? Moving, scaling, change in position? Or do you mean changing the hierarchy order?

Why would this have anything to do with texture? Color on image (graphic.color) changes the vertex colors on the mesh, not the texture. It seems like if changing the vert color on mesh causes a texture re-serialization, that would be a bug.

1 Like

“Any” change? Moving, scaling, change in position? Or do you mean changing the hierarchy order?

Any thing that in any way will cause Unity itself to re-calculate sorting order in any way will require us to recalculate the sort indices we generate and send updates over to the host platform.

Why would this have anything to do with texture? Color on image (graphic.color) changes the vertex colors on the mesh, not the texture.

Sorry, for some reason I was thinking of Image.tintColor. You are correct for UGUI Graphic that it should only cause a mesh update.

Talking to others on the team, and noting that Image.Color is modifying the mesh, I believe you are hitting an issue that we have reported to Apple as FB13566439. The root problem is that ShapeResource, which is used to generate the hit box for Apple to hit against, causes a significant performance impact when called. This causes the CADisplayLink to report a longer than normal wait time for the next frame, which is what we then depend on to handle the target FPS.

This may also be the issue with the other changes you are noting that cause this WaitForTargetFPS.

I’m not sure what we (Unity) can do to get around this but we are looking into it.

2 Likes

Thank you for the response @joejo.

When was FB13566439 reported to Apple and has there been any communication with them that indicates there could be a fix soon?

1 Like

Looks like 1/29/2024. Not sure if there has been any feedback as I didn’t file it.

Maybe @kapolka can say, since they filed it.

1 Like

No; I’m afraid they haven’t gotten back to us about it.

1 Like

In the tests we did (the op) while Image.Color was impacting performance, the same tests against TextMeshProUGUI.color there wasn’t the same performance hit. Which is odd/concerning as I believe TMP uses the graphic class.

1 Like

That makes sense given the changes we’ve made recently, and it confirms how we can work around the issue. Because of the slowdown caused by creating ShapeResources (which are used for raycasting in RealityKit), we stopped creating them automatically for TMP objects in 1.1.X (with the assumption that text typically has an Image/RawImage behind it). I believe we can work around this issue by not recreating ShapeResources when only the Image/RawImage color has changed.

4 Likes