Version: 2021.3
언어: 한국어
브랜치, 배리언트, 키워드
셰이더에서 브랜치

셰이더의 조건부

때로는 동일한 셰이더가 다양한 상황에서 서로 다른 작업을 수행하기를 원할 수 있습니다. 예를 들어 다양한 머티리얼에 대해 다르게 설정하거나 다양한 하드웨어에 대한 기능을 정의하거나 런타임 시 셰이더의 동작을 동적으로 변경할 수 있습니다. 텍스처 읽기, 버텍스 입력, 인터폴레이터, 루프와 같이 필요하지 않음에도 계산 소모를 많이 하는 코드를 실행하지 않으려고 할 수도 있습니다.

조건부를 사용하여 GPU가 특정 조건에서만 실행하는 동작을 정의할 수 있습니다.

** 다양한 조건부 유형

셰이더에서 조건부를 사용하려면 다음 접근 방식을 사용할 수 있습니다.

  • 정적 브랜치: 셰이더 컴파일러가 컴파일 시 조건부 코드를 평가합니다.
  • 동적 브랜치: GPU가 런타임 시 조건부 코드를 평가합니다.
  • 셰이더 배리언트: Unity는 정적 브랜치를 사용하여 셰이더 소스 코드를 여러 셰이더 프로그램으로 컴파일합니다. 그런 다음 Unity는 런타임 시 조건부와 일치하는 셰이더 프로그램을 사용합니다.

조건부의 타입과 사용 시기

셰이더의 조건부에는 "범용" 접근 방식이 없으며 주어진 프로젝트에서 주어진 셰이더에 대한 각 접근 방식의 장점과 단점을 고려해야 합니다.

다음의 내용을 유념해야 합니다.

  • 컴파일 시 조건부를 알고 있는 경우(예를 들어 주어진 하드웨어에 대해 빌드하고 있다는 것을 알고 있는 경우) 정적 브랜치가 가장 좋은 선택일 수 있습니다. 정적 브랜치 코드는 작성 및 유지 관리가 간단하며 빌드 시간, 파일 크기, 런타임 성능에 부정적인 영향을 주지 않습니다. 그러나 런타임 시 다른 조건에 대한 코드 실행에는 사용할 수 없습니다.
  • 런타임 시 다른 조건에 대한 코드를 실행해야 하는 경우 다음 옵션을 고려해야 합니다.
    • 셰이더 배리언트는 GPU 성능 저하를 초래하지 않습니다. 그러나 프로젝트에 셰이더 배리언트가 많으면 빌드 시간, 파일 크기, 런타임 메모리 사용, 로딩 시간 증가와 같은 심각한 문제가 발생할 수 있습니다. 셰이더 배리언트는 셰이더를 수동으로 사전 로딩(“예열”)할 때 코드 복잡도를 추가로 발생시킵니다.
    • 동적 브랜치는 셰이더 코드와 하드웨어에 따라 작거나 클 수 있는 GPU 성능 저하가 발생합니다. 그러나 프로젝트의 셰이더 배리언트 수를 늘리지 않고도 런타임에 조건부를 사용할 수 있습니다.
    • 브랜치 또는 배리언트를 방지하고 대신 조건부 코드를 실행하기 위해 0 또는 1을 반환하는 수학 연산을 사용하는 셰이더 코드를 작성할 수 있습니다. 이로 인해 유지 관리가 어려운 복잡한 코드가 생성될 수 있습니다. 상황에 따라 동적 브랜치에 비해 성능 향상이 매우 미미하거나 전혀 장점이 없을 수 있습니다.

일반적으로 가장 좋은 방법은 애플리케이션의 성능을 프로파일링하고 사례별로 신중하게 결정하는 것입니다. 예를 들어 GPU 사용량을 약간 증가시킬 수 있다면 동적 브랜치를 사용하여 “충분히 좋은” GPU 성능을 달성하고 더 많은 배리언트를 도입할 위험을 줄이는 것이 가장 좋을 수 있습니다. 그러나 GPU 성능이 해당 셰이더의 주요 관심사이고 추가 배리언트 사용량을 이미 계산했다면 배리언트 사용을 선택할 수 있습니다.

브랜치, 배리언트, 키워드
셰이더에서 브랜치