Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

셰이더(파이프라인) 컴파일에서 끊김 현상 줄이기

경고

This page only applies to the Forward+ and Mobile renderers, not Compatibility. Ubershaders and pipeline precompilation rely on functionality only available in modern low-level graphics APIs (Vulkan, Direct3D 12, Metal). The Compatibility renderer uses OpenGL 3.3, OpenGL ES 3.0, or WebGL 2.0 depending on the platform. These versions lack the functionality to effectively implement ubershaders and pipeline precompilation.

To avoid shader stutters in Compatibility, you need to use the legacy approach of preloading materials, shaders, and particles by displaying them for at least one frame in the view frustum when the level is loading.

일반적으로 셰이더 컴파일로도 알려진 파이프라인 컴파일은 엔진이 GPU를 사용하여 모든 종류의 콘텐츠를 그릴 수 있도록 하는 데 필요한 비용이 많이 드는 작업입니다.

셰이더: VisualShader 및 표준 자료에서 Godot 셰이딩 언어, GLSL에서 중간 형식(SPIR-V)에서 파이프라인까지의 전체 컴파일 프로세스를 보여주는 순서도. 셰이더 컴파일은 GLSL에서 중간 형식으로의 단계입니다. 파이프라인 컴파일은 파이프라인 단계의 중간 형식입니다.

셰이더 및 Godot의 자료는 GPU에서 실행되기 전에 여러 단계를 거칩니다.

보다 정확한 용어로, *셰이더 컴파일*은 Godot가 생성한 GLSL 코드를 시스템 간에 공유할 수 있는 중간 형식(예: Vulkan을 사용할 때 SPIR-V)으로 변환하는 것을 포함합니다. 그러나 이 형식은 GPU에서 직접 사용할 수 없습니다.

*파이프라인 컴파일*은 GPU 드라이버가 중간 셰이더 형식(셰이더 컴파일의 결과)을 GPU가 실제로 렌더링에 사용할 수 있는 형식으로 변환하는 단계입니다. 드라이버는 일반적으로 게임이 실행될 때마다 프로세스가 반복되는 것을 피하기 위해 시스템 어딘가에 파이프라인 캐시를 저장해 둡니다. 이 캐시는 일반적으로 드라이버가 업데이트되면 삭제됩니다.

파이프라인에는 셰이더 코드보다 더 많은 정보가 포함되어 있습니다. 즉, 각 셰이더에 대해 수십 개 이상의 파이프라인이 있을 수 있습니다! 이는 매우 느리고 많은 메모리를 차지하기 때문에 엔진이 미리 컴파일하기 어렵게 만듭니다. 게다가 이 단계는 사용자의 시스템에서만 수행할 수 있으며 동일한 하드웨어 및 드라이버 버전이 없으면 사용자 간에 결과를 공유하기가 매우 어렵습니다.

Godot 4.4 이전에는 카메라 뷰 내부에 객체가 나타날 때 파이프라인 컴파일을 생성하는 것 외에는 파이프라인 컴파일에 대한 솔루션이 없었습니다. 이로 인해 악명 높은 셰이더 끊김 또는 첫 번째 플레이 도중에만 발생하는 끊김 현상이 발생했습니다. Godot 4.4에서는 파이프라인 컴파일의 끊김 현상을 완화하기 위한 새로운 메커니즘이 도입되었습니다.

  • Ubershaders: Godot는 드라이버가 조명, 그림자 품질 등과 같은 매개변수 세트를 중심으로 파이프라인의 코드를 최적화할 수 있도록 하는 기능인 특수화 상수를 사용합니다. 특수화 상수는 불필요한 기능을 제한하여 셰이더를 최적화하는 데 사용됩니다. 특수화 상수를 변경하려면 파이프라인을 다시 컴파일해야 합니다. Ubershaders는 렌더링하는 동안 이러한 상수를 변경할 수 있는 셰이더의 특수 버전입니다. 이는 Godot가 미리 하나의 파이프라인만 미리 컴파일하고 게임 플레이 중에 백그라운드에서 더 최적화된 버전을 컴파일할 수 있음을 의미합니다. 이렇게 하면 생성해야 하는 파이프라인의 양이 크게 줄어듭니다.

  • 파이프라인 사전 컴파일: 엔진은 ubershader를 사용하여 메시가 로드되거나 노드가 씬에 추가되는 경우와 같이 여러 위치에서 미리 파이프라인을 사전 컴파일할 수 있습니다. 리소스 로딩 프로세스의 일부가 됨으로써 파이프라인은 로딩 화면이나 게임플레이 중에 가능하다면 여러 백그라운드 스레드에서 사전 컴파일될 수도 있습니다.

Godot 4.4부터 Godot는 어떤 파이프라인이 필요한지 감지하고 로드 타임에 미리 컴파일합니다. 이 감지 시스템은 대부분 자동이지만 로드 시 모든 셰이더, 메시 또는 렌더링 기능의 증거를 확인하는 RenderingServer에 의존합니다. 예를 들어 게임이 실행되는 동안 메시와 셰이더를 로드하는 경우 해당 메시/셰이더 조합에 대한 파이프라인은 메시/셰이더가 로드될 때까지 컴파일되지 않습니다. 마찬가지로 MSAA를 활성화하거나 게임이 실행되는 동안 VoxelGI 노드를 인스턴스화하는 등의 작업은 파이프라인 재컴파일을 트리거합니다.

파이프라인 사전 컴파일 모니터

파이프라인을 미리 컴파일하는 것은 Godot가 셰이더 끊김 현상을 완화하기 위해 사용하는 주요 메커니즘이지만 완벽한 솔루션은 아닙니다. 파이프라인 중단으로 이어질 수 있는 상황을 알고 있으면 매우 도움이 될 수 있으며 해결 방법은 이전 버전에 비해 매우 간단합니다. 더 많은 탐지 기술이 구현됨에 따라 이러한 해결 방법은 시간이 지남에 따라 Godot의 향후 버전에서 덜 필요해질 수 있습니다.

Godot 디버거는 게임에서 생성된 파이프라인의 양과 컴파일을 트리거한 단계를 추적하기 위한 모니터를 제공합니다. 테스트할 때마다 드라이버 캐시를 지우지 않고도 셰이더 끊김의 잠재적 원인을 식별하기 위해 게임이 실행되는 동안 이러한 모니터를 계속 주시할 수 있습니다. 로딩 화면 외부에서 이러한 값이 갑자기 증가하면 누군가가 시스템에서 게임을 처음 플레이할 때 게임 플레이 중에 장애가 나타날 수 있습니다. 이러한 모니터를 살펴보고 플레이어의 끊김 현상이 발생할 수 있는 원인을 파악하는 것이 좋습니다. 드라이버 캐시를 삭제하거나 약한 시스템에서 테스트하지 않으면 이러한 현상을 직접 경험하지 못할 수도 있습니다.

존재하는 Godot 머티리얼 사용하기

데모 프로젝트 중 하나의 파이프라인 컴파일입니다.

참고

게임 플레이 중에 컴파일된 파이프라인을 보고 어떤 단계에서 끊김 현상이 발생할 수 있는지 확인할 수 있습니다. 삭제된 파이프라인은 이러한 모니터에 의해 추적되지 않으며 게임 플레이 중에 파이프라인이 삭제되고 다시 생성될 수 있으므로 이러한 값은 증가하기만 하고 결코 감소하지 않습니다.

  • 캔버스: 2D 노드를 그릴 때 컴파일됩니다. 엔진에는 현재 2D 요소에 대한 사전 컴파일 기능이 없으며 2D 노드가 처음으로 그려지면 끊김 현상이 나타납니다.

  • 메시: 3D 메시를 로드하고 해당 속성에서 사전 컴파일할 수 있는 파이프라인을 식별하는 과정의 일부로 컴파일됩니다. 게임 플레이 중에 메시가 로드되면 끊김 현상이 발생할 수 있지만, 백그라운드 스레드를 사용하여 메시를 로드하면 완화될 수 있습니다. 재질 재정의와 같은 노드의 일부인 수정자는 이 단계에서 컴파일할 수 없습니다.

  • 표면: 프레임이 그려지려고 할 때 컴파일되고 처음으로 씬 트리에 3D 개체가 인스턴스화되었습니다. 여기에는 씬 트리에도 표시되지 않는 노드에 대한 컴파일도 포함될 수 있습니다. 끊김 현상은 노드가 씬에 추가된 첫 번째 프레임에서만 발생하며, 로딩 화면 직후에 발생하더라도 뚜렷한 끊김 현상이 발생하지 않습니다.

  • Draw: Compiled on demand when a 3D object needs to be drawn and an ubershader was not precompiled ahead of time. The engine is unable to precompile this pipeline due to triggering a case that hasn't been covered yet or a modification that was done to the engine's code. Leads to stutters during gameplay. This is identical to Godot versions before 4.4. If you see compilations here, please let the developers know as this should never happen with the Ubershader system. Make sure to attach a minimal reproduction project when doing so.

  • 특화: 프레임 속도를 최적화하기 위해 게임 플레이 중에 백그라운드에서 컴파일됩니다. 끊김 현상을 일으킬 수는 없지만 프레임당 발생하는 현상이 많으면 프레임 속도가 저하될 수 있습니다.

파이프라인 사전 컴파일 기능

Godot는 모든 게임에서 반드시 사용되지는 않는 많은 렌더링 기능을 제공합니다. 불행하게도 파이프라인 사전 컴파일은 특정 기능이 프로젝트에서 사용되는지 미리 알 수 없습니다. 이러한 기능 중 일부는 사용자가 노드를 씬에 추가하거나 프로젝트 또는 환경에서 특정 설정을 전환하는 경우에만 감지될 수 있습니다. 파이프라인 사전 컴파일 시스템은 이러한 기능을 처음 접할 때 추적하고 나중에 생성되는 모든 메시 또는 표면에 대해 사전 컴파일을 활성화합니다.

게임에서 이러한 기능을 사용하는 경우 대부분의 자산을 로드하기 전에 가능한 한 빨리 해당 기능을 사용하는 씬이 있어야 합니다. 이 씬는 매우 간단할 수 있으며 게임에서 사용하려는 기능을 사용하는 한 작업을 수행할 것입니다. 필요한 경우 적어도 한 프레임 동안 화면 밖에서 렌더링할 수도 있습니다. ColorRect 노드로 덮거나 창 경계 외부에 위치한 :ref:`class_SubViewport`를 사용합니다.

게임 플레이 중에 이러한 기능을 변경하면 즉시 끊김 현상이 발생한다는 점도 명심해야 합니다. 필요한 경우 구성 화면에서만 이러한 기능을 변경하고 변경 사항이 적용될 때 로딩 화면과 메시지를 삽입하십시오.

  • MSAA 레벨: 프로젝트 설정에서 3D MSAA 레벨을 변경하면 활성화됩니다. 불행히도, 서로 다른 뷰포트에서 서로 다른 MSAA 레벨을 사용하면 엔진이 사전 컴파일을 수행하기 위해 한 번에 한 레벨만 추적하므로 끊김 현상이 발생합니다.

  • 반사 프로브: ReflectionProbe 노드가 씬에 배치되면 활성화됩니다.

  • 별도의 반사광: 하위 표면 산란과 같은 효과를 사용하거나 화면에서 직접 반사광을 샘플링하는 합성 효과를 사용할 때 활성화됩니다.

  • 모션 벡터: TAA, FSR2와 같은 효과 또는 모션 벡터가 필요한 합성기 효과(예: 모션 블러)를 사용할 때 활성화됩니다.

  • 일반 및 거칠기: SDFGI, VoxelGI, 화면 공간 반사, SSAO, SSIL을 사용하거나 사용자 정의 셰이더 또는 :ref:`class_CompositorEffect`에서 ``normal_roughness_buffer``를 사용할 때 활성화됩니다.

  • 라이트맵: LightmapGI 노드가 씬에 배치되고 노드가 구운 라이트맵을 사용하는 경우 활성화됩니다.

  • VoxelGI: VoxelGI 노드가 씬에 배치되면 활성화됩니다.

  • SDFGI: WorldEnvironment가 SDFGI를 활성화하면 활성화됩니다.

  • 멀티뷰: XR 프로젝트에 대해 활성화됩니다.

  • 16/32비트 섀도우: 프로젝트 설정에서 섀도우맵의 깊이 정밀도 구성이 변경되면 활성화됩니다.

  • 옴니 섀도우 듀얼 포물면: 옴니 라이트가 그림자를 투사하고 듀얼 포물면 모드를 사용할 때 활성화됩니다.

  • 옴니 섀도우 큐브맵: 옴니 라이트가 그림자를 투사하고 큐브맵 모드(기본값)를 사용할 때 활성화됩니다.

게임 플레이 중에 끊김이 발생하고 모니터에서 Surface 단계 중에 컴파일이 갑자기 증가한다고 보고하는 경우 해당 기능이 미리 활성화되지 않았을 가능성이 높습니다. 게임을 로드하는 동안 이 효과를 활성화하면 문제가 완화될 가능성이 높습니다.

파이프라인 사전 컴파일 인스턴스화

게임에서 끊김이 발생하는 일반적인 원인 중 하나는 게임 플레이 중에만 발생하는 상호 작용으로 인해 일부 효과가 씬에만 인스턴스화된다는 사실입니다. 예를 들어 플레이어가 작업을 수행할 때 스크립트를 통해서만 씬에 추가되는 입자 효과가 있는 경우입니다. 씬이 사전 로드되어 있어도 효과가 씬에 한 번 이상 추가될 때까지 엔진이 파이프라인을 사전 컴파일하지 못할 수 있습니다.

운 좋게도 씬이 씬에서 적어도 한 번 인스턴스화되는 한 Godot 4.4 이상에서는 이러한 파이프라인을 사전 컴파일할 수 있습니다. 완전히 보이지 않거나 카메라 시야 밖에 있는 경우에도 마찬가지입니다.

효과에 대한 숨겨진 노드 예의 스크린샷

데모 프로젝트 중 하나에서 플레이어에 숨겨진 총알 노드가 부착되었습니다. 이는 엔진이 효과의 파이프라인을 미리 컴파일하는 데 도움이 됩니다.

게임 플레이 중에 씬에 동적으로 추가되는 효과를 알고 이러한 효과가 나타날 때 편집 모니터에서 갑자기 증가하는 경우 해결 방법은 표시되는 위치에 숨겨진 버전의 효과를 연결하는 것입니다.

예를 들어 플레이어 캐릭터가 일종의 폭발을 일으킬 수 있는 경우 해당 효과를 플레이어의 하위로 보이지 않는 노드로 연결할 수 있습니다. 숨겨진 노드에 연결된 스크립트를 비활성화하거나 문제를 일으킬 수 있는 다른 노드를 숨기십시오. 이는 노드에서 **편집 가능한 자식 노드**를 활성화하여 수행할 수 있습니다.

셰이더

Godot 4.5부터, 초기 시작 시간을 개선하기 위해 내보내기 시 셰이더를 굽도록 선택할 수 있습니다. 이렇게 하면 일반적으로 기존 끊김 현상이 해결되지 않지만 처음으로 게임을 로드하는 데 걸리는 시간이 줄어듭니다. 이는 필요한 변환 단계로 인해 Vulkan보다 초기 셰이더 컴파일 시간이 상당히 느린 Direct3D 12 또는 Metal을 사용할 때 특히 그렇습니다. Godot의 셰이더는 GLSL과 SPIR-V를 사용하지만 Direct3D 12와 Metal은 다른 형식을 사용합니다.

참고

셰이더 베이커는 소스를 중간 형식(Vulkan의 경우 SPIR-V, Direct3D 12의 경우 DXIL, Metal의 경우 MIL)으로만 베이킹할 수 있습니다. GPU 드라이버와 하드웨어에 따라 달라지므로 중간 형식을 최종 파이프라인에 적용할 수 없습니다.

셰이더 베이커는 파이프라인 사전 컴파일을 대체하는 것은 아니지만 이를 보완하는 것을 목표로 합니다.

활성화되면 셰이더 베이커는 컴파일된 셰이더 코드를 PCK에 번들로 묶어 셰이더 컴파일 단계를 완전히 건너뜁니다. 단점은 내보내는 데 시간이 약간 더 오래 걸린다는 것입니다. PCK 파일은 몇 메가바이트 더 커집니다.

셰이더 베이커는 기본적으로 비활성화되어 있지만 셰이더 Baker > Enabled 내보내기 옵션을 선택하여 내보내기 대화 상자의 각 내보내기 사전 설정에서 이를 활성화할 수 있습니다.

셰이더 베이킹은 편집기가 현재 실행 중인 플랫폼에서 지원되는 드라이버에 대해서만 셰이더를 내보낼 수 있습니다.

  • Windows에서 실행되는 편집기는 Vulkan 및 Direct3D 12용 셰이더를 내보낼 수 있습니다.

  • macOS에서 실행되는 편집기는 Vulkan 및 Metal용 셰이더를 내보낼 수 있습니다.

  • Linux에서 실행되는 편집기는 Vulkan용으로만 셰이더를 내보낼 수 있습니다.

  • Android에서 실행되는 편집기는 Vulkan용으로만 셰이더를 내보낼 수 있습니다.

셰이더 베이커는 대상 플랫폼의 rendering/rendering_device/driver 프로젝트 설정과 일치하는 셰이더만 내보냅니다.

참고

셰이더 베이커는 Forward+ 및 모바일 렌더러에서만 지원됩니다. 프로젝트가 호환성 렌더러를 사용하는 경우 또는 Forward+ 또는 모바일 렌더러를 지원하지 않는 하드웨어로 인해 호환성 폴백을 사용하는 사용자에게는 아무런 효과가 없습니다.

이는 또한 웹 플랫폼이 호환성 렌더러만 지원하므로 셰이더 베이커가 웹 플랫폼에서 지원되지 않음을 의미합니다.