프레임 디버거
Texture Streaming

셰이더 로드 시간 최적화(Optimizing Shader Load Time)

셰이더는 GPU에서 실행되는 소형 프로그램으로 로딩하는 데에는 다소 시간이 소요됩니다. 각각의 GPU 프로그램은 빠르게 로딩되지만, 셰이더는 내부적으로 많은 “배리언트”를 포함하고 있습니다.

예를 들어 스탠다드 셰이더는 완전히 컴파일된 경우 서로 조금씩 다른 수천 개의 GPU 프로그램으로 구성됩니다. 이러한 이유로 다음과 같이 두 개의 잠재적인 문제가 발생합니다.

  • 셰이더 배리언트가 다수 생성되는 경우 게임 빌드 시간과 게임 데이터 크기가 증가합니다.
  • 게임 도중 다수의 셰이더 배리언트를 로드하면 시간이 오래 걸리며, 메모리를 많이 차지합니다.

셰이더 빌드 타임 스트리핑

Unity는 게임 빌드 중에 게임에서 사용되지 않는 몇몇 내부 셰이더 배리언트를 찾아 빌드 데이터에 포함되지 않도록 할 수 있습니다. 빌드 타임 스트리핑은 다음을 제거하기 위해 수행됩니다.

  • #pragma shader_feature를 사용하는 셰이더의 개별 셰이더 기능. 사용되는 머티리얼 중 아무 것도 특정 배리언트를 사용하지 않는 경우 빌드에 포함하지 않습니다. 내부 셰이더 배리언트 문서를 참조하십시오. 빌트인 셰이더 이외에 스탠다드 셰이더가 이 기능을 사용합니다.
  • Shader variants to handle Fog and Lightmapping modes not used by any of the scenes are not included into the game data. See the Graphics window if you want to override this behavior.

위의 조합을 사용하면 셰이더의 데이터 크기가 상당히 줄어듭니다. 예를 들어 완전히 컴파일된 스탠다드 셰이더는 수백 메가바이트를 차지하지만 일반적인 프로젝트에서는 몇 메가바이트만 차지합니다. 또한 애플리케이션 패키징 과정에서 이 용량은 더욱 압축됩니다.

디폴트 Unity 셰이더 로딩 동작

모든 디폴트 설정에서 Unity는 shaderlab 셰이더 오브젝트를 메모리에 로드하지만 실제로 필요하기 전까지는 내부 셰이더 배리언트를 생성하지 않습니다.

즉, 게임 빌드에 포함되는 셰이더 배리언트가 사용될 수도 있지만 필요한 시점 전까지는 메모리나 로드 타임을 요구하지 않습니다. 예를 들어, 셰이더는 항상 배리언트를 포함하여 섀도우가 있는 점 광원을 처리하지만 섀도우가 있는 점 광원을 한 번도 사용하지 않는 경우 이 특정 배리언트가 로드되지 않습니다.

이 디폴트 동작의 단점은 특정 셰이더 배리언트가 처음으로 필요한 경우 일시적으로 성능 저하가 발생할 수 있다는 점입니다. 새로운 GPU 프로그램 코드가 그래픽스 드라이버에 로드되어야 하기 때문입니다. 게임플레이 중에는 이런 현상이 발생하지 않아야 하므로 Unity는 이를 해결하기 위해 ShaderVariantCollection 에셋을 지원합니다.

셰이더 배리언트 컬렉션

ShaderVariantCollection은 셰이더의 리스트에 해당하는 에셋이며, 각각은 로드할 패스 타입과 셰이더 키워드 조합의 리스트를 포함합니다.

셰이더 배리언트 컬렉션 인스펙터
셰이더 배리언트 컬렉션 인스펙터

To help with creating these assets based on actually used shaders and their variants, the editor can track which shaders and their variants are actually used. In the Graphics window, there is a button to create a new ShaderVariantCollection out of currently tracked shaders, or to clear the currently tracked shader list.

Creating ShaderVariantCollection from Shaders used by editor
Creating ShaderVariantCollection from Shaders used by editor

Once you have some ShaderVariantCollection assets, you can set for these variants to be automatically preloaded while loading the application (under Preloaded Shaders list on the Graphics window), or you can preload an individual shader variant collection from a script.

미리 로드된 셰이더 리스트에는 자주 사용되는 셰이더가 나열됩니다. 이 리스트에 나열된 셰이더 배리언트는 애플리케이션의 전체 사용 기간 동안 메모리에 로드되어 있습니다. 따라서 ShaderVariantCollections 에셋에 다수의 배리언트가 포함된 경우 메모리가 매우 많이 사용될 수 있습니다. 이 문제를 방지하려면 ShaderVariantCollection 에셋을 더 작게 세분화하여 생성하고 스크립트에서 로드해야 합니다. 각 씬마다 사용된 셰이더 배리언트를 기록하고 별도의 ShaderVariantCollections 에셋에 저장하고 씬이 시작될 때 로드하는 등의 방법으로 이를 수행할 수 있습니다.

ShaderVariantCollection 스크립팅 클래스를 참조하십시오.

참고 항목

프레임 디버거
Texture Streaming