Version: 2023.1
언어: 한국어
셰이더 키워드
셰이더 키워드와 머티리얼 인스펙터 함께 사용

셰이더 키워드와 C# 스크립트 함께 사용

셰이더 키워드를 활성화 또는 비활성화할 수 있습니다.셰이더 키워드를 활성화 또는 비활성화하면 셰이더가 적절한 조건부 동작을 표시합니다.키워드가 셰이더 배리언트 또는 동적 브랜치와 함께 작동하는지 여부에 따라 이것은 Unity가 적절한 셰이더 배리언트를 렌더링하거나 GPU가 적절한 브랜치를 실행한다는 의미입니다.

이 페이지는 다음에 관한 정보를 제공합니다.

로컬 및 전역 셰이더 키워드

Unity가 C#에서 셰이더 키워드를 나타낼 때 로컬 셰이더 키워드전역 셰이더 키워드의 개념을 사용합니다.

로컬 셰이더 키워드는 셰이더 소스 파일에서 선언하는 모든 키워드로 구성됩니다. 로컬 셰이더 키워드는 개별 셰이더 또는 컴퓨트 셰이더에 영향을 줍니다. 로컬 키워드는 로컬 또는 전역 범위를 가질 수 있으며 전역 셰이더 키워드로 오버라이드할 수 있는지에 영향을 줍니다.

전역 셰이더 키워드는 로컬 셰이더 키워드의 오버라이드 기능을 합니다. 이 키워드는 셰이더 소스 파일에서 선언하지 않고 C# 코드에만 존재합니다. 전역 셰이더 키워드는 동시에 여러 개의 셰이더와 컴퓨트 셰이더에 영향을 미칠 수 있습니다.

로컬 셰이더 키워드

셰이더 소스 파일에서 셰이더 키워드를 선언하면 Unity가 이를 C#에서 LocalKeyword 구조로 나타냅니다. 이를 로컬 셰이더 키워드라고 합니다.

LocalKeywordisOverridable 프로퍼티는 소스 파일에서 키워드가 전역 범위로 선언되었는지, 아니면 로컬 범위로 선언되었는지 나타냅니다. 키워드가 전역 범위로 선언되어 동일한 이름을 가진 전역 셰이더 키워드로 오버라이드할 수 있다면 true입니다. 로컬 범위로 선언되어 동일한 이름을 가진 전역 셰이더 키워드로 오버라이드할 수 없다면 false입니다.

Unity는 셰이더 또는 컴퓨트 셰이더에 영향을 미치는 모든 로컬 셰이더 키워드를 LocalKeywordSpace 구조체에 저장합니다.그래픽스 셰이더의 경우 Shader.keywordSpace로 액세스할 수 있습니다.컴퓨트 셰이더의 경우, ComputeShader-keywordSpace로 액세스할 수 있습니다.

전역 셰이더 키워드

Unity는 소스 파일에서 선언한 로컬 셰이더 키워드 외에도 별도로 전역 셰이더 키워드 리스트를 유지합니다. 이 키워드는 셰이더 소스 파일에서 선언하지 않습니다. 대신 C#에서 작업하는 로컬 셰이더 키워드에 대한 런타임 오버라이드입니다. 전역 셰이더 키워드는 동시에 여러 개의 셰이더와 컴퓨트 셰이더에 영향을 미칠 수 있습니다.

Unity는 GlobalKeyword 구조로 전역 셰이더 키워드를 나타냅니다.

전역 셰이더 키워드 설정은 여러 개의 머티리얼과 컴퓨트 셰이더에 대해 같은 셰이더 키워드를 활성화하거나 비활성화해야 할 때 편리합니다. 단, 다음과 같은 단점이 있을 수 있습니다.

  • 키워드의 전역 상태를 설정하는 경우, 셰이더가 실수로 같은 이름의 키워드를 정의하는 경우 의도하지 않은 결과가 발생할 수 있습니다. 로컬 범위의 키워드를 선언하거나, 충돌 가능성을 낮추는 방식으로 키워드의 이름을 지정하여 이러한 일을 방지할 수 있습니다.
  • 새로운 GlobalKeyword를 만들면 Unity가 이 시점에 로드된 모든 셰이더 및 컴퓨트 셰이더의 전역 키워드 공간과 로컬 키워드 공간 간 내부 매핑을 업데이트합니다. 이 작업의 CPU 소모량이 높을 수 있습니다. 이 작업의 영향을 줄이려면 애플리케이션 시동 직후 애플리케이션이 로드되는 중 모든 전역 키워드를 만드십시오.

로컬 및 전역 셰이더 키워드 상호작용 방법

이름이 같은 전역 셰이더 키워드와 로컬 셰이더 키워드의 상태가 서로 다른 경우, Unity는 LocalKeywordisOverridable 프로퍼티를 사용하여 개별 머티리얼 또는 컴퓨트 셰이더에 대해 키워드가 활성화되었는지 아니면 비활성화되었는지 파악합니다. isOverridable은 키워드가 전역 범위로 선언된 경우 true이고 로컬 범위로 선언된 경우 false입니다.

  • isOverridabletrue인 경우: 같은 이름의 전역 키워드가 존재하며 활성화되어 있는 경우, Unity는 글로벌 키워드의 상태를 사용합니다. 이외의 경우 Unity는 로컬 키워드의 상태를 사용합니다.
  • isOverridablefalse인 경우: 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);
            }            
        }
    }
}

셰이더 배리언트 또는 동적 브랜치

Unity에서는 셰이더 키워드를 셰이더 배리언트와 함께 사용하거나 동적 브랜치와 함께 사용할 수 있습니다.사용자가 키워드를 언제 선언할지 결정할 수 있습니다.

LocalKeywordisDynamic 프로퍼티는 키워드가 셰이더 소스 파일에서 동적 브랜치에 사용하도록 선언되었는지 여부를 나타냅니다.키워드가 동적 브랜치와 함께 사용하도록 선언된 경우 true이고, 셰이더 배리언트와 함께 사용하도록 선언된 경우 false입니다.

셰이더 키워드 활성화 및 비활성화

그래픽 셰이더에 로컬 키워드가 활성화되어 있는지 확인하려면 Material.IsKeywordEnabled 또는 Material.EnableKeyword를 사용하면 됩니다.컴퓨트 셰이더의 경우, ComputeShader.IsKeywordEnabled 또는 ComputeShader.EnableKeyword를 사용하십시오.

전역 키워드가 활성화되었는지 확인하려면 Shader.IsKeywordEnabled 또는 Shader.EnableKeyword 또는 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는 모든 키워드를 독립적으로 활성화하거나 비활성화하도록 허용하며, 키워드 활성화 또는 비활성화는 다른 키워드 상태에 영향을 미치지 않습니다. 즉, 같은 세트의 여러 키워드를 활성화하거나 세트의 모든 키워드를 비활성화할 수 있습니다.

셰이더 배리언트와 함께 키워드를 사용하는 경우, 세트에 둘 이상의 키워드가 활성화되어 있거나 세트에 활성화된 키워드가 없는 경우 Unity는 “충분히 일치하는” 것으로 간주되는 배리언트를 선택합니다.정확히 어떤 일이 일어날지 보장할 수 없으며 의도하지 않은 결과가 발생할 수 있습니다.키워드 상태를 신중하게 관리하여 이러한 상황을 피하는 것이 가장 좋습니다.

동적 브랜치가 있는 키워드를 사용하는 경우, 세트에 하나 이상의 키워드가 활성화되어 있거나 세트에 활성화된 키워드가 없는 경우 조건부 브랜치가 그에 따라 실행됩니다.예를 들어 KEYWORD_AKEYWORD_B가 모두 활성화된 경우 (KEYWORD_A)if (KEYWORD_B)`의 브랜치가 모두 실행됩니다.

셰이더 키워드
셰이더 키워드와 머티리얼 인스펙터 함께 사용