I have a very basic setup in Unity 6000.0.28: a new (basically empty) URP project with a single scene; the scene contains a single UIDocument containing a single fullscreen VisualElement. On a Xiaomi Redmi Note 4 (Android 7), the following behavior can be observed:
-
60+ FPS when the fullscreen VisualElement has neither a background color nor a background texture set.
-
55 FPS when the fullscreen VisualElement has a background color set.
fullscreenElement.style.backgroundColor = Color.gray;
-
30 FPS when the fullscreen VisualElement has both a background color and a background texture set.
fullscreenElement.style.backgroundImage = texture;
Is it possible to modify the internal shader for UI Elements or do something to improve performance? Since it’s just a single element with a background, I can’t think of many ways to optimize it.
I conducted further investigation and discovered that the issue primarily lies with the internal shader (UnityUIE.cginc). I managed to replace this shader with a simpler one by removing the branching logic from the original shader and making it return only the colors of the elements. This change resulted in a significant performance improvement.
The root cause appears to be the extensive branching in the UnityUIE.cginc shader, particularly when selecting a texture. While the original approach may work fine on newer devices, it makes UIToolkit practically unusable on older hardware.
A better solution might be to allow the use of more draw calls rather than relying on such a complex shader.
UI Toolkit has been heavily optimized assuming that the UI bottleneck is on CPU. It is generally the case, but the consequence is that our shader is more expensive. We’ve been using the Mali-T720 MP2 as our “low end device” for performance monitoring. We’ll try to get access to the Xiaomi Redmi Note 4 to investigate if it has some specific performance issue.
In the future we intend to make the shader more configurable. For example it could be possible for some VisualElements (e.g. full screen elements) to use a lighter version of the shader, at the expense of more draw calls. This could be helpful for simple VisualElements that cover a large area of the screen. In the meantime, if your bottleneck is the GPU, for your UI background, consider using an ImmediateModeElement with a simple shader. Also make sure that you don’t have unnecessary overdraw.
2 Likes
Thank you for the response. Overall, I think UIToolkit is improving significantly, and I enjoy working with it (much more than creating UI using the original Unity UI approach ). The option to use simpler/custom shaders would be fantastic. With a modified UnityUIE.cginc shader, I’m able to render quite complex UI even on the mentioned phone (Xiaomi Redmi Note 4), so the issue is definitely on the GPU side. Do you have an estimate for when the option to use custom shaders might become available?
We’re actively working on custom shaders, but what I was talking about would probably more take the form of a usage hint, which might potentially be backportable to previous unity versions (TBD). Could you submit a repro case of your test project in Help>Report a bug… ? Our QA will attempt to repro, they might have the device available.
1 Like
I have already reported it, including the steps to reproduce the issue. Thank you!
1 Like