SHDR001
A shader with a huge keyword space costs import and build-compile time
Every #pragma multi_compile / shader_feature keyword multiplies a shader’s variant space. Big uber-shaders and ShaderGraph outputs routinely reach tens of thousands of variants; a trivial custom shader sits in the hundreds. The scan flags shaders at 3,000 variants or more in their full keyword space.
What that number is — and isn’t
This is Unity’s “variants total”: the theoretical maximum, the same figure the shader Inspector shows. It is not the number of variants shipped in your build. Unity strips variants no material in the project uses, and the remainder can be precompiled or warmed up.
We report the total anyway because it’s the number that predicts cost: the keyword space drives shader import time in the editor and shader compilation time during a build, which is where “why does our build take 40 minutes” usually lives. For the actually-included count, open the shader’s Inspector and use Compile and show code ▸ variants included. The scan doesn’t compute that — Unity’s used-variant enumeration is slow enough per shader that it would dominate scan time.
How to bring it down
- Prefer
shader_featureovermulti_compilewhere the keyword is set by materials, not code.shader_featurevariants that no material enables are stripped;multi_compilevariants are kept because the engine can’t prove nothing sets them at runtime. - Use dynamic branching for cheap toggles. A uniform-driven
ifcosts a few cycles; a keyword costs a combinatorial multiplication of your whole build’s shader compile time. - Delete dead keywords. Feature flags nobody enables anymore still multiply the space.
- Keep URP’s default variant stripping on (URP Global Settings), and use the pipeline’s stripping options rather than fighting them.
- Warm up what you actually use so the reduced set doesn’t cost you a first-use hitch at runtime. PerfLint has a Shader Variants window for recording and warming these; the point of the exercise is fewer variants and no hitches, not one at the expense of the other.
What PerfLint does about it
Report-only, at Info, with counts formatted exactly the way Unity’s Inspector formats them (K/M/B) so you can cross-check a finding against the Inspector at a glance. There’s no button here: which keywords a shader needs is authoring intent, and stripping variants blind is how you ship a magenta object that only appears on one platform.
The related, executable slice is variant stripping settings — Built-in pipeline instancing variant stripping and URP’s strip-unused toggles — which PerfLint does surface as one-click, because those are settings rather than source edits.
Check your own project. The scan is free, runs entirely on your machine, and reports this rule with the exact assets that trip it — nothing is uploaded.
Last reviewed · All rules