본문 바로가기
게임 개발 일지/내일배움캠프 TIL

[Unity] 스프라이트 아틀라스, GPU 인스턴싱

by 빛하_ 2024. 2. 28.

스프라이트 아틀라스 (Sprite Atlas)

스프라이트 아틀라스는 Unity 2D 에서 사용하는 최적화 기법이다. 

Unity 엔진에 내장되어 있으며, Project Settings_Editor_Sprite Packer 에서 체크할 수 있다.

 

2D 프로젝트는 스프라이트와 다른 그래픽스를 사용해 씬의 시각적 요소를 만든다. 그러므로 개발자(혹은 디자이너)는 단일 프로젝트에 다수의 텍스처 파일을 사용한다. 일반적으로 Unity는 씬의 각 텍스처에 대해 드로우콜을 발생시킨다. 따라서 많은 텍스처가 포함된 프로젝트의 경우 여러 개의 드로우 콜이 발생하면서 리소스를 많이 소비하므로 프로젝트의 성능을 저하시킬 수 있다.

스프라이트 아틀라스(Sprite Atlas)는 여러 개의 텍스처를 단일 텍스처로 결합하는 에셋이다. 이를 이용해 여러 개가 아닌 단일 텍스처를 호출함으로써 하나의 드로우 콜을  발생시킬 수 있다. 그러면 큰 성능 소모 없이도 패킹된 텍스처에 동시에 액세스할 수 있다. 또한 스프라이트 아틀라스 API는 프로젝트의 런타임 시점에 스프라이트 아틀라스를 로드하는 방법을 제어할 수 있도록 해준다.

 

결론적으로, 스프라이트 아틀라스를 사용함으로써 드로우콜 횟수를 줄일 수 있다.(최적화에 도움이 된다.)

단적인 예로 이미지 1개에 드로우콜이 1회 발생한다면, 스프라이트 아틀라스로 이미지 개수를 줄임으로써 드로우콜을 같이 줄여주는 것이다. 

 

인스턴싱

유니티에서 사용하는 인스턴싱이란, 씬에 렌더링할 오브젝트가 많을 때 같은 것끼리 묶어서 (batch를 최적화 시켜서) 속도를 향상시키는 방법이다. 인스턴싱의 핵심은 batch를 크게 잡고 rendering 수를 줄이는 것이다. 렌더링의 경우 나눠서 여러 번 실시하는 것보다 한 번에 몰아서 수행하는 것이 빠르기 때문이다. 동일 객체를 묶어서 찍을 때 효율이 높아지는 이유는 다음과 같다.

1) DP Call 감소

2) Cache Miss 감소  (캐시 미스 : 요청한 데이터가 캐시에 존재하지 않는 경우)

3) SetRenderState 감소 

4) SetTexture 감소 

 

GPU Instancing

배칭은 CPU에서 그래픽 정보들을 연산해 별도의 메시로 합치면 GPU가 이를 가져와 렌더링하는 방식이다.

반면, GPU 인스턴싱은 별도의 합쳐진 메시를 생성하지 않는다. 대신, 인스턴싱되는 오브젝트들의 트랜스폼 정보를 별도의 버퍼에 담아둔다. GPU는 이 버퍼와 원본 메시들을 이용해 여러 오브젝트들을 한번에 처리해서 렌더링한다. 이 과정에서 인스턴싱 처리를 GPU에서 한다. 따라서 CPU에서 메시를 재구성하는 오버헤드가 없고 원본 메시의 버텍스 갯수와 상관 없이 런타임에서 동적인 오브젝트를 배칭해줄 수 있다. 그러므로 CPU 오버헤드나 메모리 문제의 영향을 적게 받는다. 다만, 디바이스의 GPU에 따라 불가능할 수 있으며 동일한 메시끼리는 한 번의 드로우콜로 처리가 가능하다.

 

GPU Instancing의 특징

  • 동일 메시, 동일 매터리얼인 경우에만 가능하다.
  • 쉐이더에서 인스턴싱 사용 여부를 명시해주어야 한다.
  • 쉐이더에서 Instancing Buffer 영역을 선언하여 인스턴싱을 적용할 쉐이더 파라미터를 설정할 수 있다.
  • 매터리얼에서 Enable GPU Instancing에 체크하여 인스턴싱을 적용할 수 있다.
  • 배칭이 적용됨에도 불구하고 Material Property Block을 통해서 매터리얼마다 파라미터를 변경할 수 있다는 장점이 있다.
  • 동일한 메시의 복사본을 만들어서 드로우콜을 줄인다.
  • 다이나믹 배칭과 스태틱 배칭에 비해 런타임 오버헤드가 적다.
  • 별도의 메시를 생성하지 않는다.
  • 원본 메시의 버텍스 갯수 제한은 없으나 SkinnedMesh는 불가능하다.
  • OpenGL ES 3.0 이상이나 Vulkan, Metal에서만 가능하다.

 

GPU Instancing의 장점

많은 양의 동일한 개체를 그릴때 유리하다. 데이터를 검색하는데는 약간 느리지만 CPU에서 많은 양의 동일한 개체를 렌더링 하는 속도가 매우 빠르기 때문이다.

인스턴싱 처리를 GPU에서 하기 때문에 GPU에서 메시를 재구성하는 하는 오버헤드나 메모리 이슈로부터 자유롭다.

오버헤드로 인한 제약이 적어서 원본메시의 버텍스 개수와 상관없이 런타임에서 동적인 오브젝트들을 배칭 처리할 수 있다.

 

배칭과 GPU Instancing의 차이점

한 번의 드로우콜로 오브젝트의 여러 복사본을 렌더링한다는 점은 동일하다.

배칭은 CPU에서 그래픽 정보들을 연산한 뒤 합친 메시를 새로 만들어내는 과정을 거쳐 GPU로 보내 렌더링한다.

GPU인스턴싱은 오브젝트의 트랜스폼 정보를 별도의 버퍼에 담고 GPU가 해당 버퍼와 원본 메시를 이용해 여러 오브젝트를 한번에 처리한다. 따라서 GPU인스턴싱은 배칭에 비해 CPU 오버헤드나 메모리 문제로부터 영향을 덜 받는다.

 

 

공부자료 : https://docs.unity3d.com/kr/560/Manual/GPUInstancing.html

 

 

 

댓글