머티리얼을 볼 때 인스펙터에 표시되는 머티리얼의 모든 파라미터는 스크립트를 통해 액세스할 수 있으며 런타임 시 머티리얼의 작동 방식을 변경하거나 애니메이션화할 수 있는 권한을 부여합니다.
이렇게 하면 머티리얼의 숫자 값을 수정할 수 있으며 컬러를 바꾸고 게임플레이 동안 텍스처를 동적으로 스왑할 수 있습니다. 이를 수행하기 위해 사용되는 가장 일반적인 함수는 다음과 같습니다.
함수 이름 | 용도 |
---|---|
SetColor | 머티리얼의 컬러 변경(예: 알베도 틴트 컬러) |
SetFloat | 부동 소수점 값 설정(예: 노멀 맵 멀티플라이어) |
SetInt | 머티리얼의 정수 값 설정 |
SetTexture | 머티리얼에 새 텍스처 할당 |
스크립트를 통해 머티리얼을 조정하는 데 사용할 수 있는 함수의 전체 세트는 머티리얼 클래스 스크립팅 레퍼런스에서 찾을 수 있습니다.
한 가지 중요한 참고 사항은 이 함수가 머티리얼에서 현재 셰이더에서 사용할 수 있는 프로퍼티만 설정한다는 점입니다. 즉, 텍스처를 사용하지 않는 셰이더가 있거나 셰이더가 아예 바운딩되어 있지 않으면 SetTexture 호출은 효과가 없습니다. 나중에 텍스처가 필요한 셰이더를 설정해도 마찬가지입니다. 따라서 프로퍼티를 설정하기 전에 원하는 셰이더를 설정하는 것이 좋습니다. 그러나 설정 후에도 원할 경우 동일한 텍스처나 프로퍼티를 사용하는 셰이더로 전환할 수 있으며 이 값은 보존됩니다.
이 함수는 레거시 셰이더와 스탠다드 셰이더 이외의 빌트인 셰이더(예: 파티클, 스프라이트, UI 및 조명이 꺼진 셰이더)와 같이 모든 간단한 셰이더가 예상하는 대로 작동합니다. 그러나 스탠다드 셰이더를 사용하는 머티리얼의 경우 머티리얼을 완전히 수정하기 전에 알아야 할 요구 사항이 있습니다.
런타임 시 머티리얼을 수정하려고 할 경우 스탠다드 셰이더에는 추가 요구 사항이 필요합니다. 내부적으로는 여러 셰이더가 실제 하나로 묶여 있기 때문입니다.
이 다양한 타입의 셰이더는 셰이더 배리언트라고 하며 활성화 여부를 떠나 셰이더 기능의 가능한 모든 조합으로 간주될 수 있습니다.
예를 들어 노멀 맵을 머티리얼에 할당하려면 노멀 매핑을 지원하는 셰이더의 배리언트를 활성화해야 합니다. 나중에 하이트 맵도 할당하는 경우 노멀 매핑과 하이트 매핑을 지원하는 셰이더 배리언트를 활성화해야 합니다.
이 시스템이 좋은 이유는 스탠다드 셰이더를 사용하지만 특정 머티리얼에 노멀 맵을 사용하지 않으면 노멀 맵 셰이더 코드를 실행할 때 해당 코드를 제외하고 셰이더 배리언트를 실행하기 때문에 성능 비용이 발생하지 않습니다. 또한 특정 기능 조합(예를 들어, 하이트맵과 이미시브)을 사용하지 않으면 배리언트가 빌드에서 완전히 제외됩니다. 실제로 스탠다드 셰이더의 사용 가능한 배리언트 중 아주 적은 수만 일반적으로 사용됩니다.
Unity는 단순히 가능한 모든 셰이더 배리언트를 빌드에 포함하지 않습니다. 모든 셰이더 배리언트를 포함시키면 숫자가 너무 많아 수만 개가 될 수도 있습니다. 머티리얼 인스펙터에 다양한 기능의 조합을 사용할 수 있고 각 조합에 HDR 사용 여부, 라이트맵, GI, 안개 등과 같은 렌더링 시나리오별로 각 기능 조합의 배리언트가 있기 때문입니다. 모든 배리언트를 포함하면 로딩이 느려지고 메모리 소모가 늘어나며 빌드 크기 및 빌드 시간이 증가합니다.
대신 Unity는 프로젝트에 사용된 머티리얼 에셋을 검사하여 사용된 배리언트를 추적합니다. 프로젝트에 포함한 스탠다드 셰이더의 배리언트가 빌드에 포함됩니다.
다음은 스탠다드 셰이더를 사용하는 스크립트를 통해 머티리얼에 액세스하는 경우 발생하는 두 가지 문제입니다.
스크립팅을 사용하여 스탠다드 셰이더의 다른 배리언트를 사용하게 하는 머티리얼을 변경하는 경우 EnableKeyword 함수를 사용하여 해당 배리언트를 사용하도록 설정해야 합니다. 머티리얼이 처음에 사용하지 않은 셰이더 기능을 사용하기 시작하면 다른 배리언트가 필요합니다. 예를 들어 노멀 맵을 가지고 있지 않은 머티리얼에 노멀 맵을 할당하거나 이전에 0이었던 이미시브 레벨을 0보다 큰 값으로 설정합니다.
스탠다드 셰이더 기능을 사용하기 위해 필요한 특정 키워드는 다음과 같습니다.
키워드 | 기능 |
---|---|
\NORMALMAP | 노멀 매핑| |_ALPHATEST_ON | “컷아웃” 투명도 렌더링 모드| |_ALPHABLEND_ON | “페이드” 투명도 렌더링 모드| |_ALPHAPREMULTIPLY_ON | “투명” 투명도 렌더링 모드| |_EMISSION | 이미션 컬러 또는 이미션 매핑| |_PARALLAXMAP | 하이트 매핑| |_DETAIL_MULX2 | 2차 “세부” 맵(알베도 및 노멀 맵)| |\METALLICGLOSSMAP | 메탈릭 워크플로의 메탈릭/평활도 매핑 |
_SPECGLOSSMAP | 스페큘러 워크플로의 스페큘러/평활도 매핑 |
위의 키워드를 사용하면 에디터에서 실행되는 동안 스크립팅된 머티리얼 수정 작업을 수행할 수 있습니다.
하지만 Unity는 빌드에 포함할 배리언트를 결정하기 위해 프로젝트에서 사용되는 머티리얼만 검사하므로 런타임 시점에 스크립트를 통해서만 식별되는 배리언트는 포함하지 않습니다.
즉, 스크립트의 머티리얼에 대해 _PARALLAXMAP 키워드를 사용할 수 있지만 동일한 기능 조합과 일치하는 프로젝트에 사용된 머티리얼이 없는 경우 패럴랙스 매핑이 에디터에서는 작동하는 것처럼 보여도 최종 빌드에서는 작동하지 않게 됩니다. 이는 배리언트가 필요하지 않은 것으로 간주되어 빌드에서 생략되었기 때문입니다.
이렇게 하려면 Unity가 에셋에 적어도 하나의 해당 타입의 머티리얼을 포함하여 셰이더 배리언트를 사용한다는 것을 알고 있어야 합니다. 머티리얼은 씬에서 사용되거나 Resources 폴더에 배치되어야 합니다. 그렇지 않으면 사용되지 않는 것으로 보여 Unity가 빌드에서 이를 생략합니다.
위의 두 단계를 모두 완료하면 런타임 시 스탠다드 셰이더를 사용하여 머티리얼을 완전히 수정할 수 있습니다.
셰이더 배리언트에 대한 자세한 내용과 직접 작성하는 방법에 대한 자세한 내용은 여기에 여러 셰이더 프로그램 배리언트 만들기를 참조하십시오.