Unity는 셰이더 소스 파일을 개별 셰이더 프로그램으로 컴파일합니다. 각 컴파일된 셰이더 프로그램에는 하나 이상의 배리언트가 있습니다. 배리언트는 여러 셰이더 키워드 조합과 함께 작동하는 셰이더 프로그램 버전입니다. 런타임 시 Unity가 지오메트리를 렌더링할 때, Unity는 현재 요구 사항과 부합하는 배리언트를 사용합니다. Unity가 셰이더 배리언트를 로드하고 사용하는 방식에 대해 자세히 알아보려면 셰이더 로딩을 참조하십시오.
셰이더 배리언트는 현재 시점에 현재 머티리얼에 필요한 코드만 포함하는 셰이더 프로그램을 생성하므로 성능을 개선할 수 있습니다. 보통 텍스처 판독, 버텍스 입력, 인터폴레이터, 루프와 같은 복잡한 코드 등을 이러한 방식으로 최적화합니다. 또한 셰이더 프로그램 자체도 크기가 더 작습니다.
또한 셰이더 배리언트는 같은 셰이더 소스 파일을 여러 방식으로 사용할 수 있도록 허용하므로 워크플로를 개선할 수 있습니다. 예를 들어, 여러 머티리얼의 설정을 구성하고, 여러 하드웨어의 기능을 정의하고, 런타임 시 셰이더의 동작을 동적으로 변경할 수 있습니다.
단, 단점도 있을 수 있습니다. 다량의 배리언트를 만들기가 쉬우며, 이로 인해 다음과 같은 결과를 초래될 수 있습니다.
보다 큰 프로젝트에서는 이러한 단점이 성능과 워크플로에서 심각한 문제를 초래할 수 있습니다. 따라서 셰이더 배리언트의 작동 방식을 숙지하고 불필요한 배리언트를 컴파일에서 제외(“스트립”)하는 방법을 이해하는 것이 매우 중요합니다. 셰이더 스트리핑에 대한 자세한 내용은 셰이더 배리언트 스트리핑을 참조하십시오.
아주 많은 수의 배리언트가 있는 셰이더를 “메가셰이더” 또는 “초셰이더(uber shaders)”라고 합니다. Unity의 스탠다드 셰이더가 이러한 셰이더에 해당합니다.
빌드 시 Unity는 현재 빌드 타겟의 각 그래픽스 API를 위해 1세트의 셰이더 배리언트를 컴파일합니다. 그래픽스 API와 빌드 타겟의 각 조합을 위한 배리언트 수는 셰이더 소스 파일과 셰이더 키워드 사용에 따라 달라집니다.
Unity는 현재 빌드 타겟의 리스트에 있는 각 그래픽스 API를 위해 1세트의 셰이더 배리언트를 컴파일합니다. 셰이더는 빌드 타겟과 그래픽스 API의 조합마다 다릅니다. 예를 들어, Unity는 Metal iOS와 Metal macOS를 위해 각각 다른 셰이더를 컴파일합니다.
일부 셰이더 프로그램이나 키워드는 특정 그래픽스 API나 특정 빌드 타겟만 타게팅할 수 있으므로, 그래픽스 API와 빌드 타겟의 각 조합을 위한 배리언트 수의 합계는 다를 수 있습니다. 단, 이러한 배리언트를 컴파일하는 프로세스는 동일합니다.
현재 빌드 타겟을 위한 그래픽스 API의 리스트를 보고 수정하려면 Player Settings 창이나 PlayerSettings API를 사용하십시오.
Unity는 현재 빌드 타겟과 그래픽스 API의 조합을 위해 컴파일할 셰이더 프로그램의 수를 정해야 합니다.
Unity는 빌드에 포함된 셰이더 소스 파일마다 몇 개의 고유한 셰이더 프로그램을 정의할지 다음과 같이 정합니다.
참고: 셰이더 소스 파일은 빌드의 씬에서 참조되었거나, Resources 폴더의 요소에 의해 참조되었거나, Graphics Settings 창의 Always-included shaders 섹션에 포함된 경우 해당 빌드에 포함된 것입니다.
Unity는 현재 빌드 타겟과 그래픽스 API를 위해 컴파일해야 하는 셰이더 프로그램을 정한 후, 각 셰이더 프로그램을 위해 컴파일해야 하는 셰이더 배리언트 수를 정합니다.
Unity는 각 셰이더 프로그램에 대해 해당 셰이더 프로그램에 영향을 미치는 셰이더 키워드 조합을 정합니다. 이는 다음을 구성합니다.
Unity가 셰이더 프로그램을 위해 컴파일하는 셰이더 배리언트의 수는 키워드 세트의 산물입니다. 즉, Unity는 각 세트의 요소 하나를 포함하는 각 조합마다 하나의 배리언트를 컴파일합니다.
예를 들어, 이 세트는 3가지 키워드를 포함합니다.
이 세트는 4가지 키워드를 포함합니다.
이러한 키워드에 영향을 받는 셰이더 프로그램으로 인해 다음의 12가지 배리언트가 생성됩니다.
Unity가 컴파일하는 배리언트의 수는 키워드 세트를 더 많이 추가할수록 급속하게 증가할 수 있습니다. 예를 들어, 셰이더에 각각 두 개의 키워드(<feature name>_ON
, <feature name>_OFF
)가 포함된 키워드 세트가 여러 개 있는 일반적인 사용 사례를 가정해보겠습니다. 셰이더에 이러한 키워드 세트가 2개 있는 경우, 배리언트는 4개가 됩니다. 셰이더에 이러한 세트가 10개 있는 경우, 배리언트는 무려 1,024개가 됩니다.
컴파일 후 Unity는 같은 패스 내 동일한 배리언트를 자동으로 식별하여 이러한 동일 배리언트가 같은 바이트코드를 가리키도록 합니다. 이를 중복 제거라고 합니다.
중복 제거는 같은 패스의 동일 배리언트가 파일 크기를 늘리는 일을 방지합니다. 단, 동일 배리언트는 여전히 컴파일 중 작업 낭비를 초래하며, 런타임 시 메모리 사용 및 셰이더 로딩 시간도 증가시킵니다. 이를 감안하여 항상 불필요한 배리언트를 스트리핑하는 것이 좋습니다.