Shader variants, also sometimes called shader 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.
ビルド時に、Unity は現在のビルドターゲットの各グラフィックス API に対して 1 セットのシェーダーバリアントをコンパイルします。各グラフィックス API とビルドターゲットの組み合わせに対するバリアントの数は、シェーダーのソースファイルとシェーダーキーワードの使用に依存します。
You can check how many shader variants you have.
Unity は現在のビルドターゲットの各グラフィックス API に対して 1 セットのシェーダーバリアントをコンパイルします。シェーダーは、各ビルドターゲットとグラフィックス API の組み合わせごとに異なります。例えば、Unity は iOS の Metal と macOS の Metal に対して、異なるシェーダーをコンパイルします。
シェーダープログラムやキーワードによっては、指定のグラフィックス API やビルドターゲットのみを対象とするものもあります。そのため、グラフィックス API とビルドターゲットの組み合わせごとのバリアントの数は異なります。ただし、これらのバリアントをコンパイルする手順は同じです。
現在のビルドターゲットのグラフィックス API のリストを表示および編集するには、Player 設定 ウィンドウ、または PlayerSettings API を使用します。
Unity は、現在のビルドターゲットとグラフィックス API の組み合わせに対して、コンパイルするシェーダープログラム数を決定する必要があります。
ビルドに含まれるシェーダーのソースファイルごとに、固有のシェーダープログラムをいくつ定義するかが決定されます。
ノート: シェーダーのソースファイルは、ビルドのシーンで参照されている場合、Resources フォルダーの何かによって参照されている場合、Graphics Settings ウィンドウの Always-included Shaders セクションに含まれている場合に、そのビルドに含まれます。
Unity は、現在のビルドターゲットとグラフィックス API に対して、コンパイルするシェーダープログラム数を決定し、次に、各シェーダープログラムに対してコンパイルしなければならないシェーダーバリアントの数を決定します。
For each shader program, Unity determines the combination of shader keywords that result in different variants. This comprises:
Unity が 1 つのシェーダープログラムに対してコンパイルするシェーダーバリアントの数は、キーワードの積です。つまり、Unity は各セットから 1 つの要素を含むすべての組み合わせに対して 1 つのバリアントをコンパイルします。
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.
コンパイル後、Unity は同一パス内の同一バリアントを自動的に識別し、これらの同一バリアントが同じバイトコードを指すようにします。これを 重複排除 と呼びます。
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.