런타임 시 셰이더 키워드를 활성화하거나 비활성화할 수 있습니다. 셰이더 키워드를 활성화하거나 비활성화하면 Unity가 렌더링에 적합한 셰이더 배리언트를 사용합니다.
런타임 시 셰이더 배리언트를 변경하면 성능에 영향을 줄 수 있습니다. 키워드를 변경하기 위해 배리언트를 처음으로 사용해야 하는 경우, 그래픽스 드라이버가 셰이더 프로그램을 준비하는 동안 문제가 발생할 수 있습니다. 이는 특히 크거나 복잡한 셰이더 또는 전역 키워드 상태 변경이 여러 개의 셰이더에 영향을 주는 경우 문제가 될 수 있습니다. 이를 방지하려면 셰이더 로딩 및 예열 전략에서 키워드 배리언트를 고려하십시오. 자세한 내용은 셰이더 로딩을 참조하십시오.
Unity에는 로컬 셰이더 키워드와 전역 셰이더 키워드가 있습니다.
셰이더 소스 파일에서 셰이더 키워드를 선언하면 Unity가 이를 C#에서 LocalKeyword 구조로 나타냅니다. 이를 로컬 셰이더 키워드라고 합니다.
LocalKeyword
의 isOverridable 프로퍼티는 소스 파일에서 키워드가 전역 범위로 선언되었는지, 아니면 로컬 범위로 선언되었는지 나타냅니다. 키워드가 전역 범위로 선언되었다면 true
이며, 로컬 범위로 선언되었다면 false
입니다. 이 값은 이 로컬 키워드가 같은 이름의 전역 키워드로 오버라이드될 수 있는지를 정합니다.
Unity는 셰이더 또는 컴퓨트 셰이더에 영향을 미치는 모든 로컬 셰이더 키워드를 LocalKeywordSpace 구조에 저장합니다. 그래픽스 셰이더의 경우 Shader.keywordSpace로 이 구조에 액세스할 수 있습니다. 컴퓨트 셰이더의 경우 ComputeShader-keywordSpace로 이 구조에 액세스할 수 있습니다.
Unity는 소스 파일에서 선언한 로컬 셰이더 키워드 외에도 별도로 전역 셰이더 키워드 리스트를 유지합니다. 전역 셰이더 키워드는 로컬 셰이더 키워드의 오버라이드로 기능하며, 동시에 여러 개의 셰이더와 컴퓨트 셰이더에 영향을 미칠 수 있습니다.
Unity는 GlobalKeyword 구조로 전역 셰이더 키워드를 나타냅니다.
전역 셰이더 키워드 설정은 여러 개의 머티리얼과 컴퓨트 셰이더에 대해 같은 셰이더 키워드를 활성화하거나 비활성화해야 할 때 편리합니다. 단, 다음과 같은 단점이 있을 수 있습니다.
GlobalKeyword
를 만들면 Unity가 이 시점에 로드된 모든 셰이더 및 컴퓨트 셰이더의 전역 키워드 공간과 로컬 키워드 공간 간 내부 매핑을 업데이트합니다. 이 작업의 CPU 소모량이 높을 수 있습니다. 이 작업의 영향을 줄이려면 애플리케이션 시동 직후 애플리케이션이 로드되는 중 모든 전역 키워드를 만드십시오.이름이 같은 전역 셰이더 키워드와 로컬 셰이더 키워드의 상태가 서로 다른 경우, Unity는 LocalKeyword
의 isOverridable
프로퍼티를 사용하여 개별 머티리얼 또는 컴퓨트 셰이더에 대해 키워드가 활성화되었는지 아니면 비활성화되었는지 파악합니다.
isOverridable
이 true
인 경우: 같은 이름의 전역 키워드가 존재하며 활성화되어 있는 경우, Unity는 글로벌 키워드의 상태를 사용합니다. 이외의 경우 Unity는 로컬 키워드의 상태를 사용합니다.isOverridable
이 false
인 경우: Unity는 항상 로컬 키워드의 상태를 사용합니다.따라서 개별 머티리얼 또는 컴퓨트 셰이더에 대해 셰이더 키워드가 활성화되어 있는지 또는 비활성화되어 있는지 알아보려면 isOverridable
프로퍼티의 상태와 전역 및/또는 로컬 키워드 상태를 점검해야 합니다.
이 예제는 Unity가 머티리얼에 대해 키워드가 활성화된 것으로 간주하는지, 아니면 비활성화된 것으로 간주하는지 확인하는 방법을 보여줍니다.
using UnityEngine;
using UnityEngine.Rendering;
public class KeywordExample : MonoBehaviour
{
public Material material;
void Start()
{
CheckShaderKeywordState();
}
void CheckShaderKeywordState()
{
// Get the instance of the Shader class that the material uses
var shader = material.shader;
// Get all the local keywords that affect the Shader
var keywordSpace = shader.keywordSpace;
// Iterate over the local keywords
foreach (var localKeyword in keywordSpace.keywords)
{
// If the local keyword is overridable (i.e., it was declared with a global scope),
// and a global keyword with the same name exists and is enabled,
// then Unity uses the global keyword state
if (localKeyword.isOverridable && Shader.IsKeywordEnabled(localKeyword.name))
{
Debug.Log("Local keyword with name of " + localKeyword.name + " is overridden by a global keyword, and is enabled");
}
// Otherwise, Unity uses the local keyword state
else
{
var state = material.IsKeywordEnabled(localKeyword) ? "enabled" : "disabled";
Debug.Log("Local keyword with name of " + localKeyword.name + " is " + state);
}
}
}
}
그래픽스 셰이더에 대해 로컬 키워드가 활성화되었는지 확인하려면 Material.IsKeywordEnabled나 Material.enabledKeywords를 사용하십시오. 컴퓨트 셰이더의 경우, ComputeShader.IsKeywordEnabled나 [ComputeShader.enabledKeywords]를 사용하십시오.
전역 키워드가 활성화되었는지 확인하려면 Shader.IsKeywordEnabled나, Shader.enabledGlobalKeywords 또는 ComputeShader.enabledKeywords를 사용하십시오.
그래픽스 셰이더에 대해 로컬 셰이더 키워드를 활성화하거나 비활성화하려면 Material.SetKeyword, Material.EnableKeyword 또는 Material.DisableKeyword를 사용하십시오. 컴퓨트 셰이더의 경우, ComputeShader.SetKeyword, ComputeShader.EnableKeyword 또는 ComputeShader.DisableKeyword를 사용하십시오.
전역 셰이더 키워드를 활성화하거나 비활성화하려면 Shader.SetKeyword, ComputeShader.EnableKeyword 또는 ComputeShader.DisableKeyword를 사용하십시오.
커맨드 버퍼로 로컬 또는 전역 키워드를 활성화하거나 비활성화하려면 CommandBuffer.EnableKeyword 또는 CommandBuffer.DisableKeyword를 사용하십시오.
셰이더 키워드를 저작할 때는 세트에서 키워드를 선언합니다. 세트는 상호 배타적인 키워드를 포함합니다.
런타임 시 Unity는 이러한 세트에 대한 개념이 없습니다. Unity는 모든 키워드를 독립적으로 활성화하거나 비활성화하도록 허용하며, 키워드 활성화 또는 비활성화는 다른 키워드 상태에 영향을 미치지 않습니다. 즉, 같은 세트의 여러 키워드를 활성화하거나 세트의 모든 키워드를 비활성화할 수 있습니다.
세트의 키워드가 두 개 이상 활성화되어 있거나 활성화된 키워드가 없는 경우, Unity는 “충분히 일치”하는 것으로 간주되는 배리언트를 선택합니다. 정확히 어떤 일이 생길지는 보장할 수 없으며, 의도하지 않은 결과가 초래될 수 있습니다. 키워드 상태를 신중하게 관리하여 이러한 상황을 방지하는 것이 좋습니다.