Version: 2022.1
Branching in shaders
Check how many shader variants you have

셰이더 배리언트

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.

매우 많은 배리언트가 있는 셰이더는 “메가 셰이더” 또는 “우버 셰이더”라고 부릅니다. Unity의 스탠다드 셰이더는 그러한 셰이더의 한 예입니다.

Advantages and disadvantages of shader variants

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.

그래픽스 API

Unity는 현재 빌드 타겟의 리스트에 있는 각 그래픽스 API를 위해 1세트의 셰이더 배리언트를 컴파일합니다. 셰이더는 빌드 타겟과 그래픽스 API의 조합마다 다릅니다. 예를 들어, Unity는 Metal iOS와 Metal macOS를 위해 각각 다른 셰이더를 컴파일합니다.

일부 셰이더 프로그램이나 키워드는 특정 그래픽스 API나 특정 빌드 타겟만 타게팅할 수 있으므로, 그래픽스 API와 빌드 타겟의 각 조합을 위한 배리언트 수의 합계는 다를 수 있습니다. 단, 이러한 배리언트를 컴파일하는 프로세스는 동일합니다.

현재 빌드 타겟을 위한 그래픽스 API의 리스트를 보고 수정하려면 Player Settings 창이나 PlayerSettings API를 사용하십시오.

셰이더 프로그램 수

Unity는 현재 빌드 타겟과 그래픽스 API의 조합을 위해 컴파일할 셰이더 프로그램의 수를 정해야 합니다.

Unity는 빌드에 포함된 셰이더 소스 파일마다 몇 개의 고유한 셰이더 프로그램을 정의할지 다음과 같이 정합니다.

  • 컴퓨트 셰이더 에셋은 하나의 셰이더 프로그램을 정의합니다.
  • 직접 코딩한 셰이더의 경우, 셰이더 프로그램의 수는 코드에 따라 다릅니다. 합계는 다음과 같습니다.
    • 소스 파일 자체에 있는 모든 패스의 모든 셰이더 단계. 예: 각 버텍스 단계는 하나의 셰이더 프로그램을 정의하고, 각 프래그먼트 단계는 하나의 셰이더 프로그램을 정의.
    • 소스 파일의 종속성에 있는 모든 패스의 모든 셰이더 단계. 이는 UsePass 커맨드를 사용하여 모든 폴백 셰이더 및 포함된 모든 패스를 구성합니다.
  • 셰이더 그래프 셰이더에서 셰이더 프로그램의 수는 Unity가 그래프에서 생성하는 코드에 따라 달라집니다. Unity가 생성하는 셰이더 코드를 확인하려면 셰이더 그래프 에셋을 컨텍스트 클릭하고 See generated code를 선택합니다. 그런 다음 직접 코딩한 셰이더의 경우와 같은 방법으로 셰이더 프로그램 수의 합계를 파악할 수 있습니다.

참고: 셰이더 소스 파일은 빌드의 씬에서 참조되었거나, 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가 셰이더 프로그램을 위해 컴파일하는 셰이더 배리언트의 수는 키워드 세트의 산물입니다. 즉, Unity는 각 세트의 요소 하나를 포함하는 각 조합마다 하나의 배리언트를 컴파일합니다.

For example, this set contains three shader variant keywords:

  • COLOR_RED
  • COLOR_GREEN
  • COLOR_BLUE

This set contains four shader variant keywords:

  • QUALITY_LOW
  • QUALITY_MEDIUM
  • QUALITY_HIGH
  • QUALITY_ULTRA

A shader program affected by those shader variant keywords will result in the following twelve variants:

  • COLOR_RED 및 QUALITY_LOW
  • COLOR_RED 및 QUALITY_MEDIUM
  • COLOR_RED 및 QUALITY_HIGH
  • COLOR_RED 및 QUALITY_ULTRA
  • COLOR_GREEN 및 QUALITY_LOW
  • COLOR_GREEN 및 QUALITY_MEDIUM
  • COLOR_GREEN 및 QUALITY_HIGH
  • COLOR_GREEN 및 QUALITY_ULTRA
  • COLOR_BLUE 및 QUALITY_LOW
  • COLOR_BLUE 및 QUALITY_MEDIUM
  • COLOR_BLUE 및 QUALITY_HIGH
  • COLOR_BLUE 및 QUALITY_ULTRA

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는 같은 패스 내 동일한 배리언트를 자동으로 식별하여 이러한 동일 배리언트가 같은 바이트코드를 가리키도록 합니다. 이를 중복 제거라고 합니다.

중복 제거는 같은 패스의 동일 배리언트가 파일 크기를 늘리는 일을 방지합니다. 단, 동일 배리언트는 여전히 컴파일 중 작업 낭비를 초래하며, 런타임 시 메모리 사용 및 셰이더 로딩 시간도 증가시킵니다. 이를 감안하여 항상 불필요한 배리언트를 스트리핑하는 것이 좋습니다.

Branching in shaders
Check how many shader variants you have