합치지 않고도 빨라지는 법
Esc

    합치지 않고도 빨라지는 법

    –Unity최적화Batching

    메시를 합치는 게 비싸다면 안 합치면 됩니다. 문제는 드로우 콜이 아니라 그 앞에 붙는 상태 변경이었으니, 상태를 안 바꾸면 됩니다.

    SRP Batcher 가 하는 일이 정확히 그것입니다.

    값을 GPU 에 두고 온다

    머티리얼마다 색, 타일링, 커스텀 프로퍼티 같은 값이 있습니다. 기존 방식은 오브젝트를 그릴 때마다 이 값들을 CPU 에서 GPU 로 올려 보냈습니다. SRP Batcher 는 이걸 미리 GPU 쪽 상수 버퍼에 올려 두고, 바뀔 때만 갱신 합니다.

    기존 방식 상태 세팅 + 값 업로드 상태 세팅 + 값 업로드 상태 세팅 + 값 업로드 Draw Draw Draw SRP Batcher 상태 세팅 1회 Draw Draw Draw GPU 상수 버퍼 머티리얼 A 머티리얼 B 머티리얼 C 오프셋만 바꿔 가며 값이 GPU 에 이미 있으니 드로우 콜마다 올릴 것이 없습니다 그래서 드로우 콜 수는 그대로거나 늘어나는데 총 CPU 시간은 줄어듭니다
    메시는 200개 그대로입니다. 줄어든 것은 드로우 콜 하나하나에 붙는 CPU 비용입니다.

    그래서 앞의 실측에서 드로우 콜이 524 에서 765 로 늘었는데 SetPass Call 이 517 에서 300 으로 떨어졌던 것입니다. 그리기 명령은 오히려 잘게 나뉘었지만 그 앞에서 하던 일이 사라졌습니다.

    배치 조건이 다르다

    여기가 다이나믹 배칭과 갈리는 지점이고, 실무에서 가장 헷갈리는 자리입니다.

    배치가 이어지는 조건
    다이나믹 배칭 같은 머티리얼 (같은 텍스처, 같은 값)
    SRP Batcher 같은 셰이더 변형 (값은 달라도 됨)

    SRP Batcher 에서는 머티리얼이 달라도 됩니다. 빨간 적과 파란 적이 같은 셰이더를 쓰고 값만 다르면 배치가 안 끊깁니다. 값은 어차피 버퍼에 다 있고 오프셋만 바꾸면 되니까요.

    반대로 값이 완전히 같아도 셰이더가 다르면 끊깁니다. Sprite-Default 와 Sprite-Lit-Default 를 섞어 쓰면 그 경계마다 끊깁니다. 커스텀 셰이더를 하나 추가할 때마다 배치가 하나씩 더 쪼개집니다.

    다이나믹 배칭에서는 “머티리얼 종류를 줄여라” 가 맞고, SRP Batcher 에서는 “셰이더 종류를 줄여라” 가 맞습니다. 조언이 서로를 대체하지 않습니다.

    셰이더 쪽 조건

    SRP Batcher 가 걸리려면 셰이더가 머티리얼 프로퍼티를 UnityPerMaterial 이라는 상수 버퍼 블록 안에 선언해야 합니다. URP 내장 셰이더는 전부 그렇게 돼 있습니다.

    직접 쓴 셰이더나 오래된 에셋에서 가져온 셰이더는 아닐 수 있습니다. Shader Graph 로 만든 것은 자동으로 맞춰집니다. 셰이더 인스펙터를 열면 SRP Batcher 호환 여부가 한 줄로 적혀 있고, 호환이 아니면 그 이유까지 적혀 있습니다. 먼저 여기를 봅니다.

    켜는 것만으로는 절반이다

    Unity 6 에서 SRP Batcher 는 기본으로 켜져 있습니다. 그래서 “이미 켜져 있는데 왜 안 빨라지지” 가 자주 나옵니다.

    켜는 것은 조건을 만들어 준 것뿐입니다. 배치가 실제로 이어지려면 콘텐츠 구조가 받쳐 줘야 합니다. 셰이더가 몇 종류인지, 정렬 레이어를 얼마나 쪼갰는지, 반투명 순서가 교차하는지가 전부 여기에 걸립니다.

    그러니 켰다면 그다음 할 일은 Frame Debugger 를 열어 어디서 몇 번 끊겼는지 세는 것입니다.

    6.3 의 3D Mesh in 2D 는 예외다

    Unity 6.3 부터 3D 메시를 2D 정렬 체계에 넣을 수 있게 됐습니다. 예전에는 스프라이트 뒤에 3D 오브젝트를 자연스럽게 끼우려면 카메라 트릭이 필요했는데, 이제는 Mesh 2D 계열 셰이더에 Sorting Group 컴포넌트를 붙이면 됩니다.

    단 이 셰이더 계열은 현재 SRP Batcher 와 호환되지 않습니다. 3D 와 2D 를 자주 번갈아 배치하면 배치가 그때마다 끊깁니다.

    쓸 거라면 레이어 구조를 단순하게 유지하는 편이 낫습니다. 배경, 게임플레이, 전경 정도로 층을 나누고 그 안에서 섞지 않는 식입니다. 이건 버전에 따라 바뀔 수 있으니, 쓰는 Unity 6.x 패치 릴리스 노트를 확인해 보세요.