December 06 2021

Shader Variant Stripping — Get Rid of That Performance Waste!

In this post, I’ll show you the true cost you’re paying for the “shader variants” that Unity creates by default and how to stop paying for it.

What Unity Shader Variants Are Doing to You 😡

Good news: Unity creates shader variants automatically for you.

Bad news: Unity also creates performance bottlenecks automatically for you:

  • Build times: they can increase by 20 minutes or more for you, reducing your iteration times to just a couple of times per day max.
  • Load Times: shader variants can quickly make your loading times go beyond the 1-minute mark, clearly getting rid of the users that have little patience (almost all nowadays)
  • Memory Usage: here we’re talking about a potential extra 100 MB, which gives you extra tickets to win the lottery of the OS killing your project
  • Draw Calls: they might increase your draw calls by 20% - 40%, which effectively suffocates your CPU
  • GPU Cost: this may well add 1 millisecond or more due to expensive program switching, so you suddenly can’t ship all the visuals you worked so hard on

Jeez. That doesn’t look like a good idea, does it?

Are All Shader Variants Evil Then?

Yes, all shader variants are evil… but they’re a necessary evil that make your work 10x easier (at least at the beginning).

Can you imagine having to write by hand each sub shader every time you do any changes to…

  • The texture channels that you use
  • The light shapes you use
  • The rendering technique you use
  • VR rendering modes
  • In general, rendering features

No thanks, I’ll pass.

Why Shader Variants Are Created Sneakily Through Your Materials

You luckily don’t do so many sub-shaders by hand. Unity does this automatically for you, which is great.

But it is this “automatic step” that is so dangerous… because it makes you unaware of their performance cost.

Let me put it this way: you don’t know all the shaders that you end up using and therefore you don’t know the STEEP price you’re currently paying to use them.

I’m done listing the challenges. Now it’s time to think of solutions.

Here are the two steps you must follow to get rid of this performance robbery:

  1. Become aware of the shader variants you’re using.
  2. Kill the ones you decide you don’t need that badly.

My friend, let’s see how.

Reaping Your Hidden Performance Gains

1. Finding Shader Variants in Unity

This is a simple but slightly tedious process.

First, activate shader compilation logging in the project settings.

Second, compile and launch your project in your target platform. Play around through your entire game and get the player logs (you were gathering them, right?).

When you open the logs, you’ll find entries that look like this:

Compiled Shader: Universal Render Pipeline/Lit, pass: ForwardLit, stage:pixel, keywords FOG_EXP2 ...

Here’s another example:

Shader Variants

You see those?

Those are the shader variants you’re using.

So the question is now… do you need them all?

I bet you don’t, so let’s see how you can NUKE them for good so they don’t steal your performance juice.

2. Killing Shader Variants in Unity

To kill shader variants that you don’t want in, you have two approaches:

  1. Using the IPreprocessShaders API to abort the compilation of the shaders you don’t want.
  2. Importing and configuring tools like UnityShaderStripper.

No matter the route you choose, you work with whitelists or blacklists.

Basically, you tell which shaders you want to keep… or rather kick out. That’s up to you.

The Results of Stripping Shader Variants in Unity

Remember the potential cost of ignoring shader variants?

  • Build Times: extra 20+ minutes, which frustrates YOU
  • Load Times: over the 1-minute mark, which frustrates your users
  • Memory Usage: extra 100MB, which makes hard crashes more frequent
  • Draw Calls: extra 20% - 40%, which suffocates your CPU
  • GPU Cost: can well be over 1ms, which kills your GPU budget

Well, you can get rid of 80% of these costs if you follow the process I outlined in this post.

And it is not as hard as it looks once you’ve gone correctly through it once :)

If you want to experience the process, step by step, plus an in-depth explanation of shader variants, watch lesson #006 in the Unity Performance Taskforce.

This unique lesson is designed to teach you the 20% of what you need to know to rescue 80% of the performance stolen by shader variants.

So if compile times, load times, memory usage, draw calls and GPU cost are metrics that you care about, check out the lesson #006 of the Unity Performance Taskforce and let me know your results!

Ruben (The Gamedev Guru)

The Gamedev Guru Logo

Ruben Torres Bonet (VReality Labs)
Breitenbachstraße 23, 13509 Berlin, Germany

This website is not sponsored by or affiliated with Facebook, Unity Technologies, or Gamasutra.

The content you find here is based on my own opinions. Use this information at your own risk.
Some icons provided by Icons8