Instancing 이란?

인스턴싱은 형태가 같은 오브젝트를 화면에 여러개 렌더할 때, Batch를 최적화시켜 병목현상을 최적화시켜 속도를 향상시키는 기법이다.

모양이 같다고 하여도, 위치, 스케일, 색만 다른 수많은 복사본의 메시들을 렌더링 할 때, 모든 하나하나의 오브젝트들이 드로우콜을 보내면 병목 현상이 발생하게 된다.

이러한 문제를 해결하기 위해 기하적인 요소를 담은 하나의 버텍스 버퍼와 각 기하 모델마다의 수정 정보를 갖고있는 인스턴스 버퍼를 사용해 물체를 만들어내는 방법을 쓴다.

버텍스 버퍼는 대부분 그래픽 카드 메모리에 Cache 해두고, 인스턴스 버퍼의 인스턴스마다 수정해 렌더하는 방법을 사용하는 것 같다. (적어도 Direct X 에서는 이렇다.)

조금 더 쉽게 말하면 하나의 오브젝트에 대한 원시 모양을 갖고 있다면 그 정보를 저장해두고, 여러 오브젝트에서 나눠 쓰는 방법이다.

위치, 스케일 등등의 개별 객체에 대한 정보만 저장해두면, 기존에 있던 메시만 그리면 되기때문에 Draw Call을 하나로 묶을 수 있게 된다.

하지만 만약, 텍스쳐나 쉐이더가 개별적으로 들어간다면 그에 따른 Draw Call이 생겨난다.

최고의 효율을 위해서는 똑같은 머티리얼, 똑같은 쉐이더가 적용된 스테틱 메시를 잔뜩 배치할 때 사용하면 된다.

언리얼 엔진 4의 경우엔 4.22 버전에서부터 Auto Instancing을 적용해서, 콘텐츠 브라우저에서 Drag & Drop 을 할 때, 같은 스테틱 메시라면 자동으로 판별해 가능할 경우 묶어서 렌더링(Instancing) 한다.

Batch 란?

모든 DrawCall을 모아서 한 번에 그리는 방법이다.

렌더링 과정에서 비슷비슷한 것 끼리 모아서 한꺼번에 처리하는 렌더링 기법인데, 인스턴싱을 위해 필요한 기술이다.

렌더링이 필요한 각각의 오브젝트를 하나씩 그리지 않고 여러개를 묶어 그려 오버헤드를 줄이는 것이다.

최적화된 렌더링을 위해 중요한 것은 Batch는 크게잡고 렌더링은 적게 하는게 좋다.

Rendering을 조목조목 나눠 Draw Call을 잔뜩 보내는 것은 아주 비효율적이고, 병목현상을 유발한다. 이러한 렌더링 기법을 Batch Rendering 이라고 한다.

Batch Rendering의 장점

  • Draw Call 감소
  • Cache Miss 감소
  • Set Render State 감소
  • Set Texture 감소

인스턴싱의 장점

인스턴싱은 특히 동일 객체를 많이 찍어내면 찍어낼수록 효율이 아주 높아진다.

인스턴싱을 사용하면 이런 짓도 가능하다.

족히 몇만개는 되어보이는 운석 Static Mesh 들이 120 FPS 에서 렌더링 되고있다…..

Instancing과 Batching의 차이

Instancing은 적당한 크기를 가진, 다량의 오브젝트를 빠르고 적은 비용으로 처리하기 적합하고,

Batching은 크고, 같은 머티리얼을 공유하는 물체들이 각각 렌더링되면 비용이 커서 그것을 묶기 위한 방법인 것 같다.

UE4 에서의 Instancing 기법들

UE4 에서 Static Mesh들을 인스턴싱하기 위해서 콘텐츠 개발자가 사용가능한 3가지 정도의 인스턴싱 기법을 제공한다.

  • Instanced Static Mesh
  • Hierarchical Instanced Static Mesh
  • Auto Instancing (UE 4.22 +)

위에 띄웠던 영상은 Hierarchical Instanced Static Mesh를 사용해 운석을 띄웠다.

하지만, 4.22 버전부터는 씬 안에 배치되어있는 정적 메시들에 대한 인스턴싱을 자동으로 진행해주어, 런타임에서 확인해보면 DrawCall이 개별 오브젝트당 하나씩 되어있는 것이 아닌, 더 낮은 값으로 보이는걸 볼 수 있다.

Mesh Draw Calls가 100개의 메시를 렌더해야 하는 상황에서 4개번만 호출됨을 볼 수 있다.

더 자세한 것은 추후에 공부해보며 알아봐야겠다.