Version: 2023.1
언어: 한국어
셰이더 에셋
비동기 셰이더 컴파일

셰이더 컴파일

개요

프로젝트를 빌드할 때마다 Unity 에디터는 빌드가 필요로 하는 모든 셰이더, 즉 필요한 모든 그래픽스 API에 대해 필요한 모든 셰이더 배리언트를 컴파일합니다.

Unity 에디터에서 작업할 때 에디터는 모든 요소를 미리 컴파일하지 않습니다. 모든 그래픽스 API에 대해 모든 배리언트를 컴파일하는 데에는 매우 오랜 시간이 소요될 수 있기 때문입니다.

대신 Unity 에디터는 다음을 수행합니다.

  • 셰이더 에셋을 임포트할 때는 최소한의 프로세싱(예: 표면 셰이더 생성)을 수행합니다.
  • 셰이더 배리언트를 표시해야 하는 경우, Library/ShaderCache 폴더를 확인합니다.
  • 동일한 소스 코드를 사용하는, 이전에 컴파일된 셰이더 배리언트를 찾으면 해당 배리언트를 사용합니다.
  • 일치하는 항목을 찾을 수 없으면 필요한 셰이더 배리언트를 컴파일하여 캐시에 결과를 저장합니다.
    • 참고: 비동기 셰이더 컴파일을 활성화하면 이를 배경에서 수행하고 그동안 플레이스홀더 셰이더를 표시합니다.

셰이더 컴파일은 UnityShaderCompiler라는 프로세스를 사용합니다. 다수의 UnityShaderCompiler 프로세스가 시작될 수 있어 (보통 컴퓨터의 CPU 코어당 하나) 플레이어 빌드 시에 셰이더 컴파일이 동시에 진행될 수 있습니다. 에디터는 셰이더를 컴파일하지 않고 컴파일러 프로세스는 아무 일도 하지 않으며 컴퓨터 리소스를 소비하지 않습니다.

자주 변경되는 셰이더가 많으면 셰이더 캐시 폴더가 꽤 커질 수 있습니다. 이 폴더는 Unity가 셰이더 배리언트를 다시 컴파일하게 만들 뿐이므로 삭제하는 것이 안전합니다.

플레이어 빌드 시에는 “아직 컴파일되지 않은” 모든 셰이더 배리언트가 컴파일되므로 이러한 배리언트들이 에디터가 사용하지 않았어도 게임 데이터에 포함됩니다.

서로 다른 셰이더 컴파일러

다음과 같이 플랫폼마다 서로 다른 셰이더 컴파일러를 셰이더 프로그램 컴파일에 사용합니다.

  • DirectX를 사용하는 플랫폼은 Microsoft의 FXC HLSL 컴파일러를 사용합니다.
  • OpenGL(Core 및 ES)을 사용하는 플랫폼은 Microsoft의 FXC HLSL 컴파일러를 사용하며, 이후 HLSLcc를 사용하여 GLSL로 바이트코드 변환을 수행합니다.
  • Metal을 사용하는 플랫폼은 Microsoft의 FXC HLSL 컴파일러를 사용하며, 이후 HLSLcc를 사용하여 Metal로 바이트코드 변환을 수행합니다.
  • Vulkan을 사용하는 플랫폼은 Microsoft의 FXC HLSL 컴파일러를 사용하며, 이후 HLSLcc를 사용하여 SPIR-V로 바이트코드 변환을 수행합니다.
  • 콘솔 플랫폼과 같은 여타 플랫폼은 각각 해당하는 컴파일러를 사용합니다.
  • 표면 셰이더는 코드 생성 분석 단계에 HLSL 및 MojoShader를 사용합니다.

pragma 지시문을 사용하여 여러 셰이더 컴파일러 설정을 설정할 수 있습니다.

캐시 셰이더 프리 프로세서

셰이더 컴파일에는 여러 단계가 소요됩니다. 첫 단계는 프리 프로세싱입니다. 이 단계에는 프리 프로세서라는 프로그램이 컴파일러의 셰이더 소스 코드를 준비합니다.

이전 Unity 버전에서는 셰이더 컴파일러가 현재 플랫폼에 제공하는 프리 프로세서를 에디터가 사용했습니다. 이제 Unity는 캐시 셰이더 프리 프로세서라고도 하는 자체 프리 프로세서를 사용합니다.

캐시 셰이더 프리 프로세서는 더 빠른 셰이더 임포트와 컴파일에 최적화되어 있습니다. 이 프리 프로세서는 중간 프리 프로세싱 데이터를 캐시하여 작동하므로, 에디터는 include 파일의 콘텐츠가 변경되는 경우에만 해당 파일을 파싱하면 되며 같은 셰이더의 여러 배리언트를 더 효율적으로 컴파일할 수 있습니다.

캐시 셰이더 프리 프로세서와 이전 동작의 차이를 자세히 알아보려면 Unity 포럼의 글 새로운 셰이더 프리 프로세서를 참조하십시오.

AssetBundles and shaders

If you use AssetBundles, Unity might compile duplicate shaders if you reference one shader in two or more objects. For example:

  • A material in an AssetBundle and a material in a built scene reference the same shader.
  • Multiple AssetBundles contain materials that reference the same shader outside an AssetBundle.

This can increase the memory and storage space shaders use, and break draw call batching.

To avoid this, you can use the following approaches:

  • Load an AssetBundle that contains all your shaders first, then load and instantiate AssetBundle assets that reference the shaders. See AssetBundle Dependencies for more information.
  • Structure your AssetBundles to minimise duplication. See Asset Duplication for more information.

You can add materials and shader variant collections to an AssetBundle to specify which shader variants to include.

If you create a single AssetBundle, some shaders might stay in memory even if they’re no longer needed, because you cannot partially unload an AssetBundle. You can avoid this by creating a separate AssetBundle for each group of shaders you use together, for example a ‘forest’ AssetBundle and a ‘desert’ AssetBundle. See Managing loaded AssetBundles, or Memory management in the Addressables system if you use Addressables.

You can use the Asset Bundle Browser to check which assets in AssetBundles depend on other assets, and find out if any assets are duplicated.

빌드 타임 스트리핑

Unity는 게임 빌드 중에 게임에서 사용되지 않는 몇몇 내부 셰이더 배리언트를 찾아 빌드 데이터에서 제외(“strip”)할 수 있습니다. 자세한 내용은 셰이더 배리언트를 참조하십시오.

셰이더 에셋
비동기 셰이더 컴파일
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961