빠른 비교
| 방식 | 핵심 | 잘 맞는 상황 |
|---|---|---|
| Static batching | 여러 mesh를 미리 합침 | 움직이지 않는 물체 |
| Dynamic batching | 작은 draw를 런타임에 묶음 | 작은 동일 상태 물체 |
| GPU instancing | 같은 mesh를 instance 데이터로 반복 | 나무, 풀, 총알, 군중 |
| Indirect draw | GPU가 draw 인자를 준비 | GPU culling, 대량 객체 |
one mesh
many transforms/material params
-> one instanced draw구조
Draw call은 CPU가 GPU에 "이 상태로 이 geometry를 그려라"라고 명령을 제출하는 단위입니다. 물체가 많을수록 CPU submission, state change, descriptor binding 비용이 커질 수 있습니다.
Instancing은 같은 mesh를 여러 번 그리되, 각 instance의 transform, color, material parameter만 별도 buffer로 넘깁니다. GPU는 instance id를 이용해 각 물체의 데이터를 읽고 같은 vertex shader를 반복 실행합니다.
vertex input:
- position
- normal
- uv
instance input:
- model matrix
- tint color
- object idBatching은 여러 draw를 묶는 더 넓은 개념입니다. geometry를 실제로 합칠 수도 있고, 같은 pipeline state를 가진 객체를 정렬해 state change를 줄일 수도 있습니다.
instancing과 batching은 해결하는 비용이 다르다
Instancing은 같은 mesh가 반복될 때 강합니다. 서로 다른 mesh를 억지로 instancing할 수는 없습니다. 반면 batching은 mesh가 달라도 material, shader, texture atlas 같은 조건을 맞춰 draw 수와 상태 변경을 줄일 수 있습니다.
선택 기준
| 상황 | 선택 |
|---|---|
| 같은 mesh가 수백 개 이상 | GPU instancing |
| 서로 다른 정적 mesh가 많음 | static batching |
| material이 자주 바뀜 | material 정렬 또는 atlas |
| 객체별 transform만 다름 | instance buffer |
| GPU culling 뒤 남은 객체만 그림 | indirect draw |
| 객체 수가 적음 | 단순 draw 유지 |
좋은 instancing 후보는 geometry와 shader가 같고, instance마다 달라지는 정보가 작고 고정된 경우입니다. material variant가 너무 많으면 instance batch가 자주 쪼개집니다.
주의할 점
Instancing은 draw call을 줄이지만 vertex나 fragment 비용을 줄이지는 않습니다. 화면을 많이 덮는 나무를 instancing하면 CPU는 줄어도 fragment 병목은 그대로일 수 있습니다.
또 instance별 데이터가 너무 크거나 자주 갱신되면 buffer upload와 memory bandwidth가 병목이 됩니다. instance data는 필요한 값만 압축해서 넘기는 편이 좋습니다.
참고 링크
1 sources