빌트인 셰이더 변수(Built-in shader variables)
GLSL 셰이더 프로그램(GLSL Shader programs)

여러 셰이더 프로그램 배리언트 만들기(Making multiple shader program variants)

셰이더 코드 조각 대부분을 고정시키되 약간 다른 셰이더 “배리언트”가 생성될 수 있게 하면 편리합니다. 일반적으로 “메가 셰이더” 또는 “우버 셰이더”라고 하며, 각 경우마다 다른 프리프로세서 명령으로 셰이더 코드를 여러 번 컴파일할 수 있습니다.

Unity 에서는 #pragma multi_compile 또는 #pragma shader_feature 명령을 셰이더 스니핏에 추가하여 이렇게 할 수 있습니다. 표면 셰이더에서도 가능합니다.

런타임 시 적절한 셰이더 배리언트는 머티리얼 키워드(Material.EnableKeyword 및 DisableKeyword) 또는 전역 셰이더 키워드(Shader.EnableKeyword 및 DisableKeyword)에서 선택됩니다.

multi\_compile 작동 방식

명령은 다음과 같습니다.

#pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON

하나는 FANCY_STUFF_OFF가 정의되고 다른 하나는 FANCY_STUFF_ON이 정의된 두 가지 셰이더 배리언트를 생성합니다. 머티리얼 및 전역 셰이더 키워드에 따라 런타임 시점에 둘 중 하나가 활성화됩니다. 두 키워드가 모두 활성화되지 않는 경우 전자(“off”)가 사용됩니다.

multi\_compile 줄에 키워드가 두 개보다 많을 수 있습니다. 예를 들어, 다음은 네 가지 셰이더 배리언트를 생성합니다.

#pragma multi_compile SIMPLE_SHADING BETTER_SHADING GOOD_SHADING BEST_SHADING

모두 밑줄 처리된 이름이 있으면 프리프로세서 매크로가 정의되지 않은 셰이더 배리언트가 생성됩니다. 이 배리언트는 일반적으로 셰이더 기능에 사용하여 키워드 2 개를 모두 소진하는 것을 방지합니다(키워드 제한에 대한 아래 참고 사항 참조). 예를 들어, 다음은 셰이더 배리언트를 아무 것도 정의되지 않은 것과 FOO_ON이 정의된 것을 하나씩 포함해 총 2 개 생성하는 명령입니다.

#pragma multi_compile __ FOO_ON

shader\_feature 와 multi\_compile 의 차이

#pragma shader_feature#pragma multi_compile과 매우 유사하고 shader\_feature 셰이더의 사용되지 않는 배리언트가 게임 빌드에 포함되지 않는다는 유일한 차이점이 있습니다. 따라서 shader\_feature 는 머티리얼에 설정되는 키워드에 가장 적합하고 multi\_compile 은 코드에서 전역으로 설정되는 키워드에 적합합니다.

또한 키워드가 하나뿐인 짧은 표기도 있습니다.

#pragma shader_feature FANCY_STUFF

이 표기는 #pragma shader_feature _ FANCY_STUFF의 단축키로, 두 셰이더 배리언트로 확장됩니다(첫 번째는 정의가 없고 두 번째는 정의가 있음).

여러 multi\_compile 줄 결합

여러 multi_compile 줄이 제공될 수 있고, 결과 셰이더가 가능한 모든 줄 조합에 대해 컴파일됩니다.

#pragma multi_compile A B C
#pragma multi_compile D E

첫 번째 줄에서 세 가지 배리언트가 생성되고, 두 번째 줄에서 두 가지 배리언트가 생성되어 총 여섯 가지의 셰이더 배리언트(A+D, B+D, C+D, A+E, B+E, C+E)가 생성됩니다.

각 multi\_compile 줄이 셰이더 “기능” 하나를 제어한다고 생각하면 가장 이해하기 쉽습니다. 이 방법을 사용하면 전체 셰이더 배리언트 수가 매우 빠르게 증가합니다. 예를 들어, 옵션이 각각 두 개인 multi\_compile “기능”이 열 개가 있으면 셰이더 배리언트가 총 1,024 개 생성됩니다.

키워드(Keyword) 제한

셰이더 배리언트를 사용할 때는 Unity 에서 키워드가 256 개로 제한되고 이 중 약 60 개가 내부적으로 사용되므로 실제로 사용 가능한 키워드는 더 적어진다는 점을 기억해야 합니다. 또한 키워드는 특정 Unity 프로젝트 전반에 걸쳐 전역으로 활성화되므로 여러 셰이더에 여러 키워드가 정의된 경우 제한을 초과하지 않도록 주의해야 합니다.

빌트인 multi\_compile 단축키

여러 셰이더 배리언트를 컴파일하는 데 사용되는 “단축키” 표기가 몇 개 있으며, 주로 Unity 의 다양한 광원, 섀도우, 라이트맵을 처리하는 데 사용됩니다. 자세한 내용은 렌더링 파이프라인을 참조하십시오.

  • multi_compile_fwdbaseForwardBase(포워드 렌더링 베이스) 패스 타입에 필요한 모든 배리언트를 컴파일합니다. 각 배리언트는 다양한 라이트맵 타입과 섀도우가 켜지거나 꺼진 주 방향 광원을 처리합니다.
  • multi_compile_fwdaddForwardAdd(포워드 렌더링 추가) 패스 타입의 배리언트를 컴파일합니다. 방형광, 스폿 광원 또는 점 광원 타입과 쿠키 텍스처가 있는 각각의 배리언트를 처리하도록 배리언트를 컴파일합니다.
  • multi_compile_fwdadd_fullshadows - 위와 동일하지만, 광원이 실시간 섀도우를 표시하는 기능도 포함합니다.
  • multi_compile_fog는 다양한 안개 타입(off/linear/exp/exp2)을 처리하는 여러 배리언트로 확장됩니다.

대부분의 빌트인 단축키를 사용하면 여러 셰이더 배리언트가 생깁니다. #pragma skip_variants를 사용하여 일부 불필요한 배리언트를 컴파일하지 않아도 됩니다. 예제:

#pragma multi_compile_fwdadd
// will make all variants containing
// "POINT" or "POINT_COOKIE" be skipped
#pragma skip_variants POINT POINT_COOKIE

셰이더 하드웨어 배리언트(Shader Hardware Variants)

셰이더 배리언트를 사용하는 일반적인 이유 중 하나는 OpenGL ES 같은 단일 타겟 플랫폼에서 하이엔드 및 로우엔드 하드웨어로 모두 효율적으로 실행할 수 있는 폴백이나 간단한 셰이더를 만들기 위해서입니다. 셰이더 하드웨어 배리언트를 사용하여 각기 다른 레벨의 하드웨어 기능에 특별히 최적화된 여러 베리언트를 제공할 수 있습니다.

셰이더 하드웨어 배리언트 생성을 활성화하려면 #pragma hardware_tier_variants renderer를 추가합니다. 여기서 renderer셰이더 프로그램 pragma에 사용 가능한 렌더링 플랫폼 중 하나입니다. 이#pragma로 다른 키워드에 관계없이 셰이더 배리언트가 각 셰이더마다 3 개씩 생성됩니다. 각 배리언트에는 다음 중 하나가 정의됩니다.

UNITY_HARDWARE_TIER1
UNITY_HARDWARE_TIER2
UNITY_HARDWARE_TIER3

위 정의를 사용하여 조건부 폴백이나 로우엔드 또는 하이엔드용 추가 기능을 작성할 수 있습니다. 에디터에서 각 티어 간에 전환할 수 있는 그래픽스 에뮬레이션 메뉴를 사용하여 티어를 테스트할 수 있습니다.

플레이어에 셰이더 집합이 하나만 로드되므로 배리언트의 영향을 가능한 한 작게 유지하는 데 도움이 됩니다. 또한, 예를 들어 TIER1 에 대해서만 특수 버전을 작성하고 나머지는 모두 동일하게 한 경우처럼 결과적으로 동일한 셰이더는 디스크 공간을 추가로 사용하지 않습니다.

로드 시에 Unity 는 사용 중인 GPU 를 검사하고 티어 값을 자동으로 인식합니다. GPU 가 자동으로 인식되지 않는 경우 디폴트는 가장 높은 티어입니다. Shader.globalShaderHardwareTier를 설정하여 이 티어 값을 오버라이드할 수 있지만, 배리언트를 생성할 셰이더가 로드되기 전에 이 작업을 수행해야 합니다. 셰이더가 로드된 후에는 이미 배리언트 집합이 선택된 상태이므로 이 값은 영향을 받지 않습니다. 메인 씬을 로드하기 전에 프리로드 씬에서 설정하는 것이 좋습니다.

이런 셰이더 하드웨어 티어는 플레이어의 품질 설정과 관련이 없고, 전적으로 플레이어를 실행하는 GPU 의 상대적인 성능을 통해 인식됩니다.

플랫폼 셰이더 설정(Platform Shader Settings)

다양한 하드웨어 티어에 따라 셰이더를 미세 조정하는 작업과 별도로 Unity 내부 정의를 미세 조정해야 할 수 있습니다(예를 들어 모바일에서 캐스캐이드된 섀도우 맵을 적용해야 할 수 있습니다). 이에 대한 자세한 내용은 UnityEditor.Rendering.PlatformShaderSettings 문서에서 확인할 수 있습니다. 이 문서에는 현재 지원되는 피어당 오버라이드 기능의 리스트가 있습니다. UnityEditor.Rendering.EditorGraphicsSettings.SetShaderSettingsForPlatform을 사용하여 플랫폼 셰이더 설정을 플랫폼과 티어별로 미세 조정할 수 있습니다.

다른 티어로 설정된 PlatformShaderSetting이 동일하지 않으면 #pragma hardware_tier_variants가 없어도 티어 배리언트가 셰이더에 대해 생성됩니다.

참고 항목

빌트인 셰이더 변수(Built-in shader variables)
GLSL 셰이더 프로그램(GLSL Shader programs)