Shader variants, also sometimes called shaderA program that runs on the GPU. More info
See in Glossary permutations, are one way of introducing conditional behavior into shader code.
Unity compiles shader source files into shader programs. Each compiled shader program has one or more variants: different versions of the shader program for different conditions. At runtime, Unity uses the variant that matches the current requirements. You configure variants using shader keywords.
For a general overview of conditionals in shader code and when to use which technique, see Conditionals in shader code. For more information on how Unity loads shader variants, see Shader loading.
Shaders with a large number of variants are called “mega shaders” or “uber shaders”. Unity’s Standard Shader is an example of such a shader.
The main advantage of shader variants is that they allow you to use runtime conditionals in your shader programs, without the GPU performance impact of dynamic branching. The main disadvantage of shader variants is that a large number of them can lead to both build time and runtime performance issues.
When Unity creates shader variants, it uses static branching to create multiple small, specialized shader programs. At runtime, Unity uses the shader program that matches the conditions. This means that you can use shader variants for code that would likely result in reduced GPU performance in a dynamic branch, without suffering a GPU performance penalty.
However, a large number of variants can result in increased build times, file sizes, runtime memory usage, and loading times. It also leads to greater complexity when manually preloading (“prewarming”) shaders. When a project contains a very large number of shader variants, these issues can lead to significant problems with performance and workflow.
Warning: It is easy to inadvertently create an excessively large number of shader variants, which can lead to significant performance problems. It is therefore very important to understand how Unity determines the number of shader variants, how to exclude (“strip”) unneeded variants from compilation, and when to use other types of conditionals in shaders.
At build time, Unity compiles one set of shader variants for each graphics API for the current build target. The number of variants for each combination of graphics API and build target depends on your shader source files, and your use of shader keywords.
You can check how many shader variants you have.
Unity compiles one set of shader variants for each graphics API in the list for the current build target. The shaders differ for each combination of build target and graphics API; for example, Unity compiles different shaders for Metal on iOS than for Metal on macOS.
Some shader programs or keywords might only target a given graphics API or a given build target, so the total number of variants for each combination of graphics API and build target can differ; however, the process for compiling these variants is the same.
To view and edit the list of graphics APIs for your current build target, use the Player SettingsSettings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary window, or the PlayerSettings API.
Unity must determine how many shader programs to compile for the current combination of build target and graphics API.
For each shader source file that is included in your build, Unity determines how many unique shader programs it defines:
Note: A shader source file is included in a build if it is referenced in a sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary in that build, referenced by something in the Resources folder, or included in the Always-included shaders section of the Graphics Settings window.
When Unity has determined how many shader programs it must compile for the current build target and graphics API, it then determines how many shader variants it must compile for each shader program.
For each shader program, Unity determines the combination of shader keywords that result in different variants. This comprises:
The number of shader variants that Unity compiles for a shader program is the product of the keyword sets; that is to say, Unity compiles one variant for every combination that includes one element from each set.
For example, this set contains three shader variant keywords:
This set contains four shader variant keywords:
A shader program affected by those shader variant keywords will result in the following twelve variants:
The number of variants that Unity compiles can grow very rapidly as you add more sets of shader variant keywords. The term for this very rapid growth is combinatorial explosion.
For example, consider a fairly typical use case, where a shader has a number of sets of shader variant keywords that contain two keywords each (<feature name>_ON
and <feature name>_OFF
). If the shader has two such sets of keywords, this results in four variants. If the shader has ten such sets of keywords, this results in 1024 variants.
After compilation, Unity automatically identifies identical variants within the same Pass, and ensures that these identical variants point to the same bytecode. This is called deduplication.
Deduplication prevents identical variants in the same Pass from increasing file size; however, identical variants still result in wasted work during compilation, and increased memory usage and shader loading times at runtime. With this in mind, it is always best to strip unneeded variants.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.