Unity 내일배움캠프 TIL 1120 | 드로우 콜(Draw Call) | 동적/정적 배칭

cheeseonrose·2023년 11월 20일
0

Unity 내일배움캠프

목록 보기
82/89
post-thumbnail

💡 드로우 콜 배칭



🍫 정의

  • 드로우 콜(Draw Call)
    • 화면에 게임 오브젝트를 그리기 위해 엔진이 그래픽스 API(OpenGL, Direct3D) 등에 보내는 신호이다.
  • 배칭(Batching)
    • 많은 수의 드로우 콜로 인해 CPU 성능이 저하될 수 있는데, 이때 드로우 콜을 줄이기 위해 여러 번의 드로우 콜이 일어날 상황을 하나로 묶는 과정을 배칭이라고 한다.



🍬 Material과 Batching

  • 다른 오브젝트, 메시를 사용하더라도 머테리얼이 같다면 하나의 Batch로 구성할 수 있다.
    -> 머테리얼이 같다는 것은 동일한 머테리얼 인스턴스를 의미
  • 같은 텍스쳐, 같은 쉐이더를 사용한 머테리얼이라도 따로 두 개를 만들면 다른 머테리얼로 인식된다.
GetComponent<Renderer>().material.color = Color.red;
  • 위 코드는 머테리얼의 복사본이 생성된다.
    → Renderer.sharedMaterial 로 수정하면 공유된 머테리얼 원본을 수정
  • Batching을 하기 위해서는 하나의 머테리얼을 여러 메시들이 공유해서 사용해야 한다.
    → 텍스쳐 하나에 여러 개의 텍스쳐를 합쳐서 사용하는 텍스쳐 아틀라스(Texture Atlas) 기법으로 리소스를 제작



🍭 종류

  • 동적 배칭(Dynamic Batching)
    • Static이 체크되지 않은 동적인 오브젝트들 중, 특정 조건을 만족하고 같은 머테리얼을 공유하면서 움직이는 게임 오브젝트를 동일 드로우 콜 안에 처리하는 것이다.
    • 매번 데이터 구축과 갱신이 발생하므로 매 프레임마다 오버헤드가 발생한다.
    • 제약 사항
      • Skinned Mesh에는 적용 불가능
      • 버텍스가 너무 많은 메시는 불가능
    • CPU에서 모든 게임 오브젝트 버텍스를 월드 공간으로 변환하는 방법으로 작동하기 때문에, 드로우 콜을 수행하는 것보다 효율적인 경우에만 유리하다.

  • 정적 배칭(Static Batching)
    • 움직이지 않는 게임 오브젝트를 큰 메시로 합쳐서 빠르게 렌더링하는 것이다.
    • 주로 배경 오브젝트들에 활용할 수 있으며, 인스펙터 창에서 Static을 체크하면 정적 배칭의 대상이 되어 자동으로 처리가 된다.
    • 런타임에서 수행할 버텍스 연산이 없기 때문에 동적 배칭보다 효율적이지만 추가 메모리가 필요하다.
      • 오브젝트들을 합쳐서 내부적으로 하나의 메시로 만들기 때문




🍮 Mesh.CombineMeshes

  • 가까이 있는 게임 오브젝트를 수동으로 하나의 메시로 합치는 것으로, 드로우 콜 배칭에 대한 좋은 대안이 될 수 있다.
  • 런타임동안 파츠가 조합되어 오브젝트가 만들어져야 하는 경우 활용할 수 있다.
public void CombineMeshes (
    CombineInstance[] combine,
    bool mergeSubMeshes= true, 
    bool useMatrices= true
);
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class ExampleClass : MonoBehaviour {
    void Start() {
        MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];
        int i = 0;
        while (i < meshFilters.Length) {
            combine[i].mesh = meshFilters[i].sharedMesh;
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            meshFilters[i].gameObject.active = false;
            i++;
        }
        transform.GetComponent<MeshFilter>().mesh = new Mesh();
        transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);
        transform.gameObject.active = true;
    }
}



출처 - Unity Documentation 드로우 콜 배칭
출처 - Unity Documentation Mesh.CombineMeshes
출처 - [유니티 그래픽스 최적화] 04.드로우콜과 배칭



끗-!

0개의 댓글