What is StdRender.ApplyShader?

I’ve been profiling my game on an Android device and I’ve noticed that some spikes occasionally show up and these spikes are caused by StdRender.ApplyShader. It usually takes up around 1% of CPU usage, but during the spike it jumps to around 6%. Please check the screenshot below (btw I’m using LWRP with GPU instancing).

I’m seeing the same thing, as well as SRPBRRender.ApplyShader (I’m using URP).

Seeing the same as well in 2019.3.7f1, even with all materials sharing the same ShaderGraph based shader that is confirmed to support SRP Batcher. This is killing our performance (takes about 75ms per render pass).

I had to use ShaderVariantCollections and pre-warm the shaders in an initialization script. Go to each scene and then in the Graphics settings inspector, you’ll find a button to save all the tracked shader variants used in the scene so far to an asset. Here’s my pre-warming script (including some timing metrics to see how long warming is taking):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShaderWarmer : MonoBehaviour
{
    public ShaderVariantCollection[] collections;
    public bool Initialized { get; private set; }
    private void Awake()
    {
        Initialized = false;
        for (int i = 0; i < collections.Length; ++i)
        {
            if (collections[i] != null && !collections[i].isWarmedUp)
            {
                System.DateTime now = System.DateTime.Now;
                collections[i].WarmUp();
                System.TimeSpan span = System.DateTime.Now - now;
                Debug.Log("Shader warming took: " + span);
            }
            else
            {
                if (collections[i] != null)
                {
                    Debug.Log("Shaders were already warm!");
                }
            }
        }
        Initialized = true;
    }
}

If you do this at an opportune time in your game, you’ll avoid unexpected runtime slowdowns. I also recommend combining these collections with this excellent UnityShaderStripper tool that will DRASTICALLY reduce your build times:

Careful though, you can wind up excluding a shader you need and get unexpected behavior. But the time savings, as well as memory savings, are well worth it.

1 Like