이론/그래픽스

배칭(Batching)

tsyang 2021. 11. 15. 17:14

2021.11.13 - [이론/그래픽스] - 드로우콜(Draw Call)

배칭


배칭여러 배치를 묶어 하나의 배치를 만드는 것이다. 드로우콜 횟수를 줄이는 가장 효과적인 방법 중 하나이기도 하다. 

 

배칭을 위해서는 오브젝트들이 동일한 머티리얼을 사용해야 하는데, 이때 머티리얼이 동일하다는 것은 동일한 머티리얼 인스턴스가 같다는 것을 의미한다.

 


 

스태틱 배칭

스태틱 배칭정적인 오브젝트를 대상으로 하는 배칭 기법이다. 따라서 런타임에서 버텍스 연산을 하지 않아도 되기 때문에 매우 효율적이다. 

 

스태틱 배칭은 메시의 폴리곤 수에 상관 없이 같은 머티리얼을 사용하는 오브젝트들을 하나의 메시로 묶어준다. 단, 머티리얼이 1개라고 해서 무조건 1개의 배치로 합쳐지는 것은 아니며 라이트와 같은 요소들로 인해 배칭이 나뉠 수 있다. 합쳐진 메시를 생성해야 하기 때문에 추가적인 메모리가 필요하다. 

 

돌고래 이미지 : https://en.wikipedia.org/wiki/Polygon_mesh

 

 

당연히 스태틱 배칭의 대상이 되는 오브젝트들이 처음부터 씬에 존재하는 것이 일반적이지만, 동적으로 스태틱 배칭 대상을 추가해 줄 수 있다. 그러나 이 과정에서 메시를 재생성 해야 하기 때문에 많은 시간이 소요된다.

 

또한 씬 전체를 하나의 메시로 만드는 것보다는 모듈로 쪼개는게 더 나을 수 있는데, 씬 전체가 하나의 거대한 메시가 된다면 메시의 일부만 화면에 보이더라도 전체가 처리되기 때문이다. 물론 폴리곤 처리로 인해 GPU 병목이 발생한 경우인지 드로우 콜로 인한 CPU병목인지에 따라 이야기가 달라 질 수 있다.

 

유니티에서는 인스펙터에서 오브젝트의 스태틱 배칭 여부를 정해줄 수 있다.

 


 

다이나믹 배칭

 

다이나믹 배칭은 움직이는 오브젝트들을 대상으로 배칭처리를 한다. 매 프레임마다 다이나믹 오브젝트들의 버텍스를 모아서 합쳐주는 처리를 수행한다. 그리고 이 버텍스들을 모아 다이나믹 배칭에 쓰이는 버텍스 버퍼와 인덱스 버퍼에 담는다. GPU는 이 버퍼에 있는 합쳐진 버텍스들을 가져가서 렌더링 한다. 따라서 여러 개의 오브젝트가 버퍼를 거쳐 1번의 배치로 처리 될 수 있다.

 

이런 방식을 사용하는 경우 매번 데이터 구축과 갱신이 필요하기 때문에 매 프레임마다 오버헤드가 발생한다. 그럼에도 드로우콜을 줄임으로써 성능 향상을 가져올 수 있다. 스태틱 배칭과 달리 런타임에서 매 프레임 오버헤드가 발생하기 때문에 비교적 활용성이 낮으며 다음의 제약을 추가로 가진다.

  • 스키닝을 수행하는 Skinned Mesh에는 적용이 불가능하다.
  • 버텍스가 너무 많은 메시는 제외된다. (버텍스가 너무 많은 경우 배칭 처리가 드로우콜보다 비용이 높아짐)

 

다이나믹 배칭의 비용에 대해 좀 더 자세히 써보자면, 메시가 렌더링될 때에는 버텍스 쉐이더에서 월드스페이스로의 변환이 이뤄지며 이것은 GPU에서 고속으로 연산이 된다. 그러나 다이나믹 배칭을 위해서는 오브젝트들의 버텍스들을 월드스페이스로 변환하는 연산이 CPU에서 일어난다. 이런 연산 과정이 드로우콜보다 더 커지면 오히려 효율이 떨어지는 것이다. 

 

또한 드로우콜은 그래픽스 API의 영향을 많이 받는다. 예를 들어 Metal이나 불칸은 OpenGL ES보다 드로우콜이 훨씬 빨라서 다이나믹 배칭의 이득이 적어진다.

 

유니티에서는 플레이어 설정에서 Dynamic Batching 플래그를 켜주면 유니티 엔진이 알아서 처리해준다. 쉐이더에서 특정 오브젝트의 다이나믹 배칭 플래그를 꺼줄 수 있다.

 


 

텍스처 아틀라스 

배칭이 이뤄지기 위해서는 머티리얼이 같아야 한다. 즉, 다른 메시들끼리도 하나의 텍스처를 공유해야 한다. 이 때 여러 텍스처를 합쳐서 하나의 텍스쳐로 만들어 준다면 훨씬 효율적일 것이다. 이렇게 여러 텍스터를 하나로 합치는 것을 텍스처 아틀라스(Atlas)기법이라고 한다. 

 

텍스처 아틀라싱을 사용할 때에는 해상도를 고려해서 작업해야 한다.

 

 


 

2D 스프라이트 배칭

2D 스프라이트(평면의 메시)의 경우 버텍스가 적은 편이기 때문에 배칭이 훨씬 효율적으로 이뤄진다. 스프라이트의 경우에도 머티리얼이 동일한 것끼리 배칭이 가능하다. 따라서 텍스처 아틀라스와 마찬가지로 스프라이트들을 하나의 이미지에 미리 모아두는 스프라이트 시트를 제작하거나, 다른 이미지파일들을 모아서 하나의 스프라이트 아틀라스를 만들기도 한다.

 


 

GPU 인스턴싱

배칭은 CPU에서 지오매트리 정보들을 연산해 별도의 메시로 합치면 GPU가 이를 가져와 렌더링하는 방식이다. 반면, GPU 인스턴싱은 별도의 합쳐진 메시를 생성하지 않는다. 대신, 인스턴싱되는 오브젝트들의 트랜스폼 정보를 별도의 버퍼에 담아둔다. GPU는 이 버퍼와 원본 메시들을 이용해 여러 오브젝트들을 한번에 처리해서 렌더링한다. 이 과정에서 인스턴싱 처리를 GPU에서 한다. 따라서 CPU에서 메시를 재구성하는 오버헤드가 없고 원본 메시의 버텍스 갯수와 상관 없이 런타임에서 동적인 오브젝트를 배칭해줄 수 있다.

 

따라서 배칭과 달리 CPU 오버헤드나 메모리 문제에서 자유롭다. 그러나 디바이스의 GPU에 따라 불가능할 수 있으며 당연히 동일한 메시끼리만 한번의 드로우콜로 처리가 가능하다.

'이론 > 그래픽스' 카테고리의 다른 글

텍스처  (0) 2022.01.22
컬링(Culling)  (0) 2021.12.14
드로우콜(Draw Call)  (3) 2021.11.13
병목(Bottleneck)  (0) 2021.11.03
렌더링 파이프라인  (1) 2021.10.26