Shader Compile Frame Hitches even with Shader.WarmupAllShaders

Hi There,

I have been doing some profiling on iOS and getting some really noticeable frame hitches during camera transitions. Using the metal analyser I can clearly see that this is due to shader compilation on the GPU at run time.

I have tried 3 documented methods of trying to preload/precompile these shaders, none of which have worked.

1.) Calling Shader.WarmupAllShaders() in an OnStart() method in a game object in the scene
2.) Doing a playthrough of my scene then following the documentation for Unity - Scripting API: ShaderVariantCollection and doing a ‘save to asset’ for the currently tracked variants. Which does seem to grab the correct variants of shaders for my materials. Then assigning it in graphics settings for ‘Shader Preloading’
3.) Using that same ShaderVariantCollection asset but calling WarmUp() in an OnStart() and then checking the ‘IsWarmed’ flag.

Despite trying all of these methods (and combinations), I still get the large compilation hitches on device (latest iOS, latest xCode, unity 5.5.2p2) that you can see in the screenshot.

Is this a bug within Unity? Note switching to OpenGL doesn’t seem to help.

Possibly of note is that I’m using an UberShader with about 10 different shader features, though again the variant collection does seem to correctly track which combinations are in use following step 2.)

Thanks,

Matt

Well I have a semi workaround which is to render a second camera to a render texture with a cube with all the materials in the scene assigned to force them to be rendered at least once, then disable the camera. but this is obviously not ideal.

Actually it seems even with this (and checking that it matches the number of shader variants that the tracker finds in the graphics settings) there are still some 40ms+ shader compiles on the GPU. Which maybe implies that the variant tracker is not actually tracking all the variants, or possibly that the GPU is doing something funky that is unexpected. But I’m still really stabbing the dark here, as I would at least expect Shader.WarmUpAllShaders to catch everything.

1 Like

So I have now learnt that you can explicitly set a shader keyword on a material (mat.EnableKeyword) and on device that will force an immediate recompile on the GPU.

Although I am not doing this in my code, I’m starting to suspect maybe something within unity / light mapping might be setting keywords dynamically (maybe LIGHTMAP_ON?) but need to investigate further. Still generally speaking at a loss.

Submitted a bug for this now, hopefully it’ll get resolved

https://fogbugz.unity3d.com/default.asp?901330_ka77t7aulg5p44ab

Did you find any solution for this? I noticed the same problem in my game with Unity 5.6.1p4.
And is there a way to at least find out which shaders are recompiled? I didn’t find any information in instruments other than when compiling shaders happens and how long it takes…

1 Like

I would love to get a resolution to this. My issue is with the WebGL build, buy same problem - big dips in framerate when the game is running as additional shader variants are compiled which were not cause by the Graphics Settings tool.

Even just having the ability to log what shader variants are being compiled at runtime would be massively helpful.

1 Like