일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- Page Fault
- 취준
- Tesselation
- 디퍼드 렌더링
- Fetching
- rasterization
- DrawCall
- Stack
- 데이터분석
- 코테
- Input Assembler
- 그래픽스 파이프라인
- multiset
- vertex shader
- Output Merge
- graphics rendering pipeline
- 포워드 렌더링
- Mipmap
- 외적
- bvh
- occlusion culling
- c++
- std::vector
- 개발자면접
- UnReal
- 힙
- 스택
- im뱅크
- 이중우선순위큐
- 어레이
- Today
- Total
평생 배우는 개발자
DrawCall, Batching, Occlusion Culling 본문
서론
Drawcall이란 무엇이고 최적화를 진행할 때 왜 이것을 줄여야 하나요?
이때 쓰일 수 있는 Batching이란 무엇인가요?
Occlusion Culling을 위의 서술한 내용을 바탕으로 어떤 것인지 설명해 주세요
개요
게임을 만드는 개발자가 되기 위해서 게임을 개발하거나 최적화를 할 때 위는 drawcall이라는 단어를 많이 들어보았다. 또한 이것은 최적화를 하기 위해 큰 도움이 될 수 있다. drawcall은 무엇이고 batching, occlusion culling은 무엇일까?
본론
DrawCall은 말 그대로 draw 하라는 명령이라고 볼 수 있다. 더 자세히 말하자면 CPU에서 GPU에게 draw를 하기 위해 정보를 전달하는 것이 drawcall이다. 즉, CPU에서 vertex shader에 주어진 정보들을 전달해 주는 것이고, GPU는 이 정보를 바탕으로 여러 가지 계산을 한 뒤 실제 우리가 보는 스크린에 계산된 픽셀에 대한 color값을 그린다. 이 과정을 최대한 줄일 수 있으면 그만큼 최적화를 진행할 수 있다.
예를 들어, 우리가 달리는 GIF를 만들고 싶어서 가만히 서있는 그림, 왼발 오른손이 앞선 그림, 오른발 왼손이 앞선 그림, 이 동작을 자연스레 연결하는 그림 총 4장을 반복적으로 그려서 달리는 소년을 표현하고 싶다. 이러한 소년을 총 4명 그리고 싶다고 해보자. 그러면 4장의 그림 x 4 해서 총 16장의 그림이 필요하고 우리는 각각의 그림을 위한 vertex buffer를 생성하고 vertex shader 및 fragmet shader에 각각의 정보들을 전달할 수 있다.
즉 16번의 DrawCall이 발생하는 것이다. 이때 조금의 발상 전환을 해서 하나의 그림판에 네 개의 그림을 가진 이미지를 그릴 수 있다. 즉 4가지의 그림을 가진 이미지 4장만 draw 하면 되는 것이다 이런 식으로 16번의 drawcall에서 4번의 drawcall로 줄일 수 있다. 여기서 끝이 아니라 이제는 그냥 한 장의 그림에 16가지의 그림을 모두 그려서 GPU에서 UV 조정만으로 4가지의 GIF를 표현할 수도 있다.
즉, 단 한 번만의 drawcall로도 4가지의 GIF를 표현 할 수 있는 것이다. 항상 이렇게 할 수는 없는데 비슷한 vertex shader의 종류를 가진 데이터 들이라면 충분히 가능하다.
이렇게 drawcall을 줄이는 방법을 Batching이라고 부른다. Unity엔진은 이러한 Batching기술을 편히 쓸 수 있게 가이드를 제공한다.
다음으로 Occlusion Culling은 무엇일까?
OC는 카메라의 입장으로 보았을 때 어떠한 사물에 가려서 보이지 않는 것은 렌더링 하지 않는 기법을 말한다. 즉 Camera View에서 보이는 것만 rendering 하는 것이다. 이를 위해서 Bounding Volume Heirachy나 AABB, Oct Tree와 같은 계산법을 통해서 실현할 수 있다. Camera View의 입장에서 앞의 사물들이 보이는지 안 보이는지 계산하는 방법이다.
BVH는 말 그대로 Bounding Volume들을 트리 구조화 시켜 점점 세분화시키고 보이지 않는 부분들의 폴리곤들을 계산해 나가는 방법이다.
위 사진처럼 하나의 가장 큰 큐브를 8 등분하고 그 조각에서 다시 8등분... 계속 진행해 나가는 과정이다. 만약 이 과정을 거치지 않고 Occlusion Culling을 진행한다면 다음과 같은 상황이 발생할 수 있다. 만약 카메라의 관점에서 A오브젝트가 B오브젝트에 의해 아주 약간 가려졌다. 그러면 아주 약간 가려졌음에도 불구하고 그 부분만 렌더링 하지 않는 것이 아닌 A오브젝트 전체가 나오지 않는 상황이 발생할 수 있는 것이다. 따라서 정말 가려진 부분만 렌더링 하지 않게 하려면 가려진 부분이 정확히 어디인지 위와 같은 세분화를 통해서 그 부분만 렌더링 하지 않게 계산하는 것이다.
위 사진만 보아도 상당히 복잡한 계산이 수백 번 이상 일어날 수 있다. 따라서 많은 수의 폴리곤이나 오브젝트를 갖는 장면에서는 오히려 이런 복잡한 계산 과정이 최적화에 악영향을 끼칠 수 있어서 Occlusion Culling을 실행만 하면 최적화가 된다는 생각은 금물이다.
결론
최적화의 길을 멀고도 험하다. 각자의 상황에 맞는 최적화 기법을 생각해 내고 그 안에서도 적절한 방법을 취하자.
마무리
위의 내용을 바탕으로 개발자 면접간
1. DrawCall이란 무엇인가요?
2.이를 줄이려면 어떻게 해야하나요?
3.Batching이란 무엇인가요?
4.Ocllusion Culling이란? 장단점은 무엇인가요?
5.Backface Culling이란?
등에 대한 질문을 생각해 볼 수 있겠다. 스스로에게 질문을 해보고 답해보자.
헷갈리는 부분은 보완하기! 찡긋 O.<
틀린 부분이나 보완해줬으면 하는 내용이 있으면 댓글로 알려주세요! 추가 설명이 필요하신 부분도 댓글로 알려주세요.
어떠한 피드백도 환영입니다. 긴 글 읽어주셔서 감사합니다.
'개발면접준비' 카테고리의 다른 글
가상함수,순수가상함수,추상클래스,인터페이스 (8) | 2024.12.21 |
---|---|
set 과 multiset 그리고 map과 multimap 그리고 unordered_map (4) | 2024.12.19 |
TCP와 UDP (4) | 2024.12.16 |
프로세스, 스레드 Let's Go (1) | 2024.12.14 |
std::vector의 크기가 변경 될 때 (7) | 2024.12.13 |