-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Upgrading From MRTK2's Standard Shader Breaks GPU Instancing And Causes Performance Degradation
After upgrading our project to MRTK3, we observed our app's framerate dropping down to 30-40 fps in a scene with 520 instances of 4 variants of low-vertex-count models, sharing the same opaque material with GPU Instancing enabled. We identified the source of the issue being the new GraphicsTools/Standard (GTS) shader from MRTK3 Graphics Tools. Switching back to MixedRealityToolkit/Standard (MRTS) shader eliminated the issue and brought us back up to 60 FPS.
We investigated this with RenderDoc and the difference between the two seems to be that GTS is ignoring its Material's GPU Instancing setting causing a much higher event count per frame than when using MRTS. RenderDoc.zip
With the MRTS shader, instanced objects are drawn with very few DrawIndexedInstanced(IndexCountPerInstance, InstanceCount) calls, often with the InstanceCount argument being tens or hundreds:
But with the GTS shader, DrawIndexedInstanced always gets called with only 1 as InstanceCount argument:
To reproduce
Steps to reproduce the behavior:
- Download, extract and open this project MRTK3 Shader Performance Degradation.zip
- Open the scene
MRTK3 Shader Performance Issue.unity
which has meshes all using the same materialHäuserColourMap
- Verify that this material uses the
Graphics Tools/Standard
shader (from this repository) and "GPU Instancing" is enabled - Run the scene and verify that the
Stats
window showsSaved by batching: 0
- Use RenderDoc to verify that DrawIndexedInstanced is called with an instance argument of 1 leading to a high amount of render events
- Stop play mode
- Deploy a UWP build to HL2 and verify it runs at 30-40 fps
- On the
HäuserColourMap
, switch its shader toMixed Reality Toolkit/Standard
(from the MRTK2) - Run the scene and verify that the
Stats
window showsSaved by batching ~1500
- Use RenderDoc to verify that DrawIndexedInstanced is called with an instance argument of tens or hundreds, leading to only a few render events
- Deploy a UWP build to HL2 and verify it runs at 60fps
Expected behavior
We expected the new default shader to not break GPU instancing (if enabled in its material settings) and to not degrade performance.
Setup
- Unity Version 2022.3.59f1
- Graphics Tools Version v0.8.1
Target platform
- HoloLens 2
Additional context
It's worth noting that inspecting the new MeshInstancer example scenes with RenderDoc seems like the InstanceCount argument of the DrawIndexedInstanced call is considerably higher than one there. However, this used to work automatically with the MRTK2 shader which allowed our designers to just place content using Unity's tools.