Drawcall
드로우콜
// OpemGL의 DrawCall
glDrawArrays(); // vertices rendering
glDrawElements(); // indices rendering
- CPU에서 그래픽 API 호출을 통해 GPU에 렌더링을 명령하는 것
드로우콜의 퍼포먼스
- 소규모 렌더링을 여러 번에 걸쳐 드로우콜 했을 때 (위)
- 대규모 렌더링을 한 번에 드로우콜 했을 때 (아래)
- 오버헤드 횟수를 줄임으로써 드로우콜 횟수를 줄여서 퍼포먼스 상승
키워드
- Draw Primitive Call - 메쉬를 그리는 드로우 콜 중 최종 단계
- Batch - DP Call과 상태 변경을 합친 넓은 의미의 드로우콜
- SetPass - 드로우콜 발생 시 Shader 변경 횟수
- Batch 적용보다 SetPass의 변경 적용이 더 높은 코스트
- 여러 타입의 Shader가 있을 경우 동일한 Shader룰 사용하는 오브젝트끼리 묶어서 렌더링하면 Shader Switching Cost를 줄일 수 있음
드로우콜의 코스트, 어떻게 줄이나
- Batching
- 같은 Material을 사용하는 오브젝트끼리 묶어서 Batch를 줄이는 작업(하나의 Batch로 만드는 작업)
- 버텍스들을 하나의 버텍스 리스트에 통합해 한번에 그리도록 함
- => 한 번의 Draw Call 호출로 처리
- Material(Texture)은 동일한 Instance여야 함
- => SpriteAtlas를 사용하는 이유
- 버텍스들을 하나의 버텍스 리스트에 통합해 한번에 그리도록 함
- 같은 Material을 사용하는 오브젝트끼리 묶어서 Batch를 줄이는 작업(하나의 Batch로 만드는 작업)
- Static Batch
- CPU로 Compile Time에 버텍스 연산
- Mesh를 통합하기 위해 추가적인 Memory 필요
- 추가 메모리를 사용하더라도 Run Time에서 Draw Call을 줄일 수 있기 때문에 Performance 상승
- Static Batch 함에도 오브젝트 단위로 Culling이 이뤄지기 때문에 GPU 낭비 최소화 가능
- 배경을 하나의 거대한 Mesh로 만들지 않는 이유
- Dynamic Batch
- CPU로 Run Time에 버텍스 연산
- 매 프레임 overhead 발생
- overhead < draw call 부르는 cost
- GPU Instancing
- 같은 오브젝트를 여러 번 Render 하는 것
- Single Render Call
- Batching에 비해 오버헤드 적음
- 별도로 Mesh를 생성하지 않고, 각 instance에 대해 transform 정보만 별도의 buffer에 담아 동일한 Mesh 정보를 바탕으로 여러 오브젝트들을 한번에 Draw 처리
- 이 과정을 GPU에서 처리
- Dynamic Object 처리에 비해 RunTime에서 제약 적음