SRP 배처는 동일한 셰이더 배리언트를 사용하는 머티리얼이 많이 포함된 씬에서 CPU 렌더링 속도를 높여주는 렌더링 루프입니다.
SRP 배처를 사용하려면 프로젝트가 스크립터블 렌더 파이프라인을 사용해야 합니다. 다음 파이프라인 중 하나일 수 있습니다.
URP에서 SRP 배처를 활성화하려면 다음 단계를 따르십시오.
HDRP에서 SRP 배처는 기본적으로 활성화되며, 이를 비활성화하면 안 됩니다. 하지만 디버깅 목적으로 SRP 배처를 일시적으로 비활성화하려면 다음 단계를 따르십시오.
런타임 시점에 SRP 배처를 활성화하거나 비활성화할 수도 있습니다. 이렇게 하려면 C# 코드로 작성된 다음의 전역 변수를 토글하십시오.
GraphicsSettings.useScriptableRenderPipelineBatching = true;
SRP 배처는 거의 모든 플랫폼에서 동작합니다. 이 표에는 지원되는 플랫폼과 필요한 최소 Unity 버전이 나와 있습니다.
Platform | Minimum Unity version required |
Windows DirectX 11 | 2018.2 |
PlayStation 4 | 2018.2 |
Vulkan | 2018.3 |
OSX Metal | 2018.3 |
iOS Metal | 2018.3 |
Nintendo Switch | 2018.3 |
Xbox One DirectX 11 | 2019.2 |
OpenGL 4.2 and higher | 2019.1 |
OpenGL ES 3.1 and higher | 2019.1 |
Xbox One DirectX 12 | 2019.1 |
Windows DirectX 12 | 2019.1 |
참고: XR의 경우 SinglePassInstanced
모드에서만 SRP 배처를 사용할 수 있습니다.
Unity에서는 프레임 동안 언제든지 모든 머티리얼의 프로퍼티를 수정할 수 있습니다. 하지만 그에 대한 단점도 있습니다. 예를 들어 DrawCall이 새로운 머티리얼을 사용하는 경우 많은 작업이 필요합니다. 따라서 씬에 포함된 머티리얼이 많을수록 Unity는 GPU 데이터를 설정하기 위해 더 많은 CPU를 사용해야 합니다. 이를 해결하기 위한 기존의 방법은 DrawCall의 수를 줄여서 CPU 렌더링 부하를 최적화하는 것이었습니다. 왜냐하면 DrawCall을 발행하기 전에 많은 것을 설정해야 하기 때문입니다. 실제 CPU 부하는 GPU DrawCall 자체가 아니라 설정에서 발생합니다. 이 경우 Unity는 일부 바이트를 GPU 커맨드 버퍼로 푸시해야 합니다.
SRP 배처는 Bind
및 Draw
GPU 커맨드 시퀀스를 배칭하여 DrawCall 간에 GPU 설정을 줄여줍니다.
렌더링 성능을 극대화하려면 이러한 배치의 크기가 커야 합니다. 이를 위해 동일한 셰이더가 포함된 다른 머티리얼을 최대한 많이 사용할 수 있지만, 가능한 한 소수의 셰이더 배리언트로 사용해야 합니다.
렌더 루프 동안 Unity가 새 머티리얼을 감지하면 CPU는 모든 프로퍼티를 수집하고 GPU 메모리에 다양한 상수 버퍼를 설정합니다. GPU 버퍼 수는 셰이더가 CBUFFER를 선언하는 방법에 따라 다릅니다.
씬이 서로 다른 머티리얼을 많이 사용하는 반면 셰이더 배리언트는 아주 소수만 사용하는 경우 속도 최적화를 위해 SRP는 GPU 데이터 지속성 등과 같은 패러다임을 네이티브 방식으로 통합합니다.
SRP 배처는 머티리얼 데이터가 GPU 메모리에 지속하도록 만드는 저레벨 렌더 루프입니다. 머티리얼 콘텐츠가 변하지 않으면 SRP 배처는 설정하거나 버퍼를 GPU 메모리에 업로드할 필요가 없습니다. 대신에 SRP 배처는 전용 코드 경로를 사용하여 대형 GPU 버퍼로 Unity 엔진 프로퍼티를 빠르게 업데이트합니다.
여기에서 CPU는 위 다이어그램의 Per Object large buffer 라는 레이블이 지정된 Unity 엔진 프로퍼티만 처리합니다. 모든 머티리얼에는 GPU 메모리에 위치해 있고 사용할 준비가 된 지속 CBUFFER가 있습니다. 이렇게 하면 모든 머티리얼 콘텐츠가 GPU 메모리에 지속되기 때문에 렌더링 속도가 개선됩니다. 전용 코드는 모든 오브젝트별 프로퍼티에 대한 오브젝트별 GPU CBUFFER를 관리합니다.
특정 씬에서 일부 오브젝트만 SRP 배처와 호환 가능합니다. 호환되지 않는 오브젝트를 사용하는 경우에도 Unity는 씬을 적절하게 렌더링합니다. 이는 호환 가능한 오브젝트가 SRP 배처 코드 경로를 사용하고, 그러지 않는 오브젝트는 표준 SRP 코드 경로를 사용하기 때문입니다.
SRP 배처 코드 경로가 오브젝트를 렌더링하려면 다음 사항을 충족해야 합니다.
셰이더가 SRP 배처와 호환 가능하려면 다음 사항을 충족해야 합니다.
unity_ObjectToWorld
또는 unity_SHAr
를 예로 들 수 있습니다.UnityPerMaterial
라는 이름의 단일 CBUFFER로 선언합니다.인스펙터 패널에서 셰이더의 호환성 상태를 볼 수 있습니다.
SRP 배처를 사용하는 경우 씬의 속도 증가를 측정하려면 SRPBatcherProfiler.cs
C# 스크립트를 SRP 배처 템플릿에서 씬에 추가하십시오. 이 스크립트가 동작 중이면 다음을 수행하십시오.
F8 키를 사용하여 오버레이 디스플레이를 토글합니다.
F9 키를 사용하는 재생되는 동안 SRP 배처를 켜고 끌 수도 있습니다.
오버레이는 다음과 같은 모습입니다.
시간은 밀리초(ms) 단위로 측정되며, CPU가 Unity SRP 렌더링 루프에서 소비한 시간을 보여줍니다.
참고: 여기에 있는 시간은 스레드 소유자와 관계없이 프레임 동안 호출된 모든 RenderLoop.Draw
및 Shadows.Draw
마커의 누적 시간과 동일합니다. 예를 들어 1.31ms SRP 배처 코드 경로가 표시되면 드로우 콜이 메인 스레드에 대해 0.31ms를 소비하고, 1ms는 모든 그래픽스 작업에 분산됩니다.
이 표는 Play 모드에 표시되는 SRP 배처 오버레이의 각 설정에 대해 설명합니다.
오버레이의 이름 | 설명 | |
---|---|---|
(SRP batcher ON) / (SRP batcher OFF) | 현재 SRP 배처가 활성화되었는지 표시합니다. SRP 배처를 토글하려면 F9를 누르십시오. | |
CPU Rendering time | 사용되는 멀티 스레드 모드에 관계없이 SRP 루프가 CPU에서 소비한 총 누적 시간을 나타냅니다(예: 단일 클라이언트/워커 또는 그래픽스 작업). 여기에서 SRP 배처의 효과를 가장 잘 볼 수 있습니다. 배처의 최적화를 확인하려면 배처를 켜거나 끌 때 CPU 사용량의 차이를 살펴보십시오. 이 예에서 총 시간은 2.11밀리초입니다. (incl RT idle): SRP가 렌더 스레드에서 소비한 대기 상태 시간을 나타냅니다. 앱이 그래픽스 작업이 없는 클라이언트/워커 모드에 있는 경우를 예를 들 수 있습니다. 이는 렌더 스레드가 메인 스레드의 그래픽스 커맨드를 기다려야 할 때 발생합니다. 이 예에서 렌더 스레드의 대기 상태 시간은 0.36밀리초였습니다. |
|
SRP Batcher code path (flushes) | 게임이나 앱이 SRP 배처 코드 경로에서 소비한 시간을 나타냅니다. 이 값은 게임이 All objects (섀도우 패스 제외)(1.18ms)와 Shadows (1.13ms)를 렌더링하는 데 소비한 시간으로 나눌 수 있습니다. Shadows 숫자가 높으면 씬에서 그림자 드리우기 광원 수를 줄이거나, 렌더 파이프라인 에셋에서 더 낮은 캐스케이드 수를 선택하십시오. 이 예에서는 1.31ms였습니다. (flush(s)) 숫자는 Unity가 새로운 셰이더 배리언트를 만날 때 씬을 플러시한 횟수를 나타냅니다(이 예에서는 89). 플러시 횟수가 적은 것이 언제나 좋습니다. 이는 프레임에 적은 수의 셰이더 배리언트가 있었다는 의미입니다. |
|
Standard code path (flushes) | Unity가 SRP 배처와 호환되지 않는 오브젝트(예: 파티클)를 렌더링하는 데 소비한 시간을 나타냅니다. 이 예에서 SRP 배처는 81개 오브젝트의 플러시에 0.80ms, 섀도우 패스에 0.09ms, 기타 다른 패스에 0.71ms를 소비했습니다. |
|
Global Main Loop: (FPS) | 전역 메인 루프 시간(단위: 밀리초)을 나타내며, 이 값은 초당 프레임 수(FPS)에 해당합니다. 참고: FPS는 선형이 아니기 때문에 FPS가 20만큼 증가해서 씬에 반드시 최적화되었다고 볼 수는 없습니다. SRP 배처가 씬 렌더링을 최적화했는지 확인하려면, SRP 배처를 켰을 때와 껐을 때 CPU Rendering time 아래의 숫자를 비교해보십시오. |
Frame Debugger 창에서 SRP 배처 “배치”의 상태를 확인할 수 있습니다.
SRP 배처 배치의 상태를 확인하려면 다음 단계를 따르십시오.
SRP Batch 세부 정보에 사용된 드로우 콜 수, 셰이더에 연결된 키워드, 특정 드로우 콜이 이전 드로우 콜과 함께 배칭되지 않은 이유가 나와 있습니다. 아래 예에서 명시된 이유는 노드가 다른 셰이더 키워드를 사용함 입니다. 즉, 해당 배치에 대한 셰이더 키워드가 이전 배치의 셰이더 키워드와 다르다는 의미입니다. SRP 배처가 다른 셰이더 배리언트를 사용했기 때문에 배칭이 제대로 이루어지지 않았습니다. SRP 배치에 적은 수의 드로우 콜이 있는 경우 너무 많은 셰이더 배리언트를 사용할 가능성이 큽니다.
URP 또는 HDRP를 사용하지 않고 자체 SRP를 작성하는 경우 최소한의 키워드를 사용하여 일반 “uber” 셰이더를 작성하십시오. 하지만 각 머티리얼 내에는 원하는 만큼 많은 Material 파라미터와 Material 프로퍼티를 사용할 수 있습니다.