때로는 2개 이상의 서로 다른 모드(분기) 동작이 필요한 쉐이더도 있다.
예를 들면, 다른 플랫폼에서 동작할 때는 다른 쉐이더 피쳐를 사용하게 하는 방식으로 말이다.
경우에 따라서는 서로 다른 쉐이더 파일을 추가로 만들어서 해결할 수도 있다. 하지만, 이 방식은 코드 중복 생성을 야기 할 수 있다.
이를 방지하기 위해, Shader Keywords를 이용 할 수 있다.

키워드들은 일종의 토글들처럼 동작한다.
좀 더 넓게 말해서, 키워드는 2가지 타입이 존재한다.
첫째는 스위치처럼 On OFF 가능한 토글처럼,
둘째는 Enum처럼 여러 옵션 중에서 하나를 선택 가능한 방식
우리가 키워드들을 넣을때마다, 유니티는 빌드 할 때 각각의 키워드를 위한 여러 Shader Variants를 컴파일 할 것이다.
각 배리언트는 게임 빌드때 포함되는 여러 버전의 쉐이더 파일을 의미한다.
만약 우리가 하나의 키워드 토글을 만든다면, 2개의 배리언트가.. 두번째 토글 키워드를 만든다면 총 4개의 배리언트가 생성된다.
이는 이상적으로 늘어난 것이다. 실제로는 키워드가 생성될때마다 분기 가능한 모든 배리언트들이 생성되며
그 수는 어마어마하게 많아질 가능성이 많다.

Sahder Varians는 많아질 수록 빌드 시간과 사이즈가 늘어난다. 이것도 다 최적화 과정이 필요한 부분이다.
그 부분은 나중에 다루겠다.
샘플로 사용할 키워드는 색상을 붉은 색으로 바꾸도록 하여 두 개의 상태를 전환하는 역할이다.
스크립팅을 이용하여, 런타임중에도 상태 전환을 가능하도록 할 것이다.
Properties
{
_BaseColor ("Base Color", Color) = (1,1,1,1)
_MainTex ("Main Texture", 2D) = "white" {}
_Tiling("Tiling", Vector) = (1, 1, 0, 0)
_Offset("Offset", Vector) = (0, 0, 0, 0)
[Toggle(OVERRIDE_RED_ON)] _OverrideRed("Force Red", Float) = 0
}

다음처럼 Properties에 Toggle을 추가하였다.
그러면 매트리얼에서 토글 버튼이 하나 생성된 것을 확인 할 수 있다.
이 토글을 사용하기 전에 특별한 Syntax를 사용할 필요가 있다.
Keywords 사용하기
키워드를 사용하기 위해서는 2가지 사용 방법이 존재한다.
둘 다 Precompiler인 #pragma를 필요로 한다.
(1) #pragma multi_compil
키워드 리스트의 값들을 가져와서 사용 가능한 모든 Shader Variant를 자동으로 컴파일한다.
런타임중에 켜고 끄는 방식을 구현하려면, 이 방법을 이용해야 한다.
과용하면 빌드 시간과 메모리를 크게 잡아먹는다.
하나의 리스트에 여러 키워드들이 있으면, 하나만 활성화 가능하다.
#pragma multi_compile KEYWORD_A KEYWORD_B KEYWORD_C
위의 예시에서는 3개의 키워드중 하나만 활성화가 가능하다.
#pragma multi_compile KEYWORD_A KEYWORD_B KEYWORD_C __
multi_compile을 사용하면, 목록에 있는 키워드 중 하나도 활성화되지 않은 배리언트도 컴파일할 수도 있다.
아무 전처리기 매크로도 정의되지 않은 셰이더 배리언트를 생성하려면 밑줄(__)만 포함하는 이름을 추가하자. 프로젝트에서 사용할 수 있는 키워드 개수에는 제한이 있으며, 이렇게 하면 두 개의 키워드를 사용하는 것을 피할 수 있다
(2) #pragma shader_feature
빌드 할 때, 사용되는 Shader Variants들만을 빌드한다.
Variants의 양은 줄어들고, 빌드의 시간과 사이즈는 줄어들 것이다.
하지만 키워드를 런타임동안 다른 배리언츠들이 있지 않다면, 토글링 하는 것은 불가능하다.
shader_feature를 사용할 때는, 다른 플랫폼에서 쉐이더를 빌드하면서 호환되지 않는 것을 포함하지 않는게 중요하다.
#pragma shader_feature FEATURE_A FEATURE_B FEATURE_C
Keyword를 사용할 때, Global 혹은 Local 수준으로 범위(scope) 설정이 가능하다.
Global Scope는 게임속 모든 쉐이더들이 사용할 수 있게 하는 것이고,
Local Scope는 개별 매트리얼을 위한 키워드로 제약한다.
기본적으로는 Global Scope 가 디폴트로 되어있다.
키워드 뒤에 _Local을 붙이면 Scope 설정으로 Local로 바꿀 수 있다.
#pragma multi_compile_local OVERRIDE_RED_ON __
우리 이제 쉐이더의 색상을 바꿀지 On Off 가능한 상태로 사용할 수 있다.
#if , #endif , #else문을 이용하여 키워드를 켤 수 있는 것이다.
float4 frag(v2f i) : SV_Target
{
float4 textureSample = SAMPLE_TEXTURE2D(_MainTex, sampler_RepeatLinear, i.uv);
#if OVERRIDE_RED_ON
return textureSample * float4(1.0f, 0.0f, 0.0f, 1.0f);
#else
return textureSample * _BaseColor;
#endif
}
이제 키워드 토글을 한번 On / Off 해보자

Keywords Shader Graph에서 사용하기


Shader Graph에서는 Properties 추가 맨 아래에 Keyword에서 찾을 수 있다.
추가하고나면 Node Setting에서 Multi_Compile / Shader_Feature를 선택 할 수 있는데
Scope는 유니티 6에서는 is Overridable 로 통합되어 On을 하면 Local로 역할을 한다. 꼭 유의하자

C#에서 Keyword ON/OFF 제어하기
using UnityEngine;
public class ModifyingKeyword_Script : MonoBehaviour
{
[SerializeField] private MeshRenderer rend;
[SerializeField] private Material material;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
rend = GetComponent<MeshRenderer>();
material = rend.material;
}
// Update is called once per frame
void Update()
{
bool toggelr = Time.time % 2.0f > 1.0f;
if (toggelr)
{
material.EnableKeyword("OVERRIDE_RED_ON");
}
else
{
material.DisableKeyword("OVERRIDE_RED_ON");
}
}
}
마치며
처음에 Keyword 와 그 내부 원리에 대해 감이 잘 안와서
포스팅을 2번 3번 쓴거 같다.
Shader Variants 개념이 조금 생소해서 그랬던 걸로 보인다.
'Game Dev > Unity Shader' 카테고리의 다른 글
| 15. Lighting And Shadow - 다니엘 릿 쉐이더 프로젝트 (1) | 2025.10.18 |
|---|---|
| 14. UsePass, GrapPass - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.18 |
| 12. Dissolve Effect 개선하기, C# 코드와 상호작용 - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.17 |
| 11. Tranparancy And Alpha 심화 - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.17 |
| 10. Transparency And Alpha - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.17 |