다이렉트 X는 정말 어렵다. 배우고는 싶었는데 개인포폴이랑 자료구조 공부랑 병행 할 엄두가 안났다.
당장 필요한것도 아니고 나중에 공부하자 생각해서 카테고리도 숨겨놨었는데
수업을 듣다보니 좀 욕심이 생겨서 제대로 좀 해보려고 한다.
몇 개월 전부터 렌더링 파이프라인이라는 단어는 수도없이 듣고 시험도 봤지만
머리속에 잘 들어오지 않았다.
하지만 다이렉트X 수업을 들을때 렌더링 파이프라인에 대한 이해가 없으면 많이 힘들거같아서 혼자 유튜브로 공부를 좀 했다.
그 내용을 조금 정리하려고 한다.
렌더링 파이프라인 이란?
우리가 '파이프라인' 이라는 단어를 떠올린다면 이런 파이프라인이 떠오를것이다.
렌더링 파이프라인 이라는것은 우리가 렌더링 정보들을 GPU에 주입시켜서
우리가 보는 화면에 출력해주기 까지의 과정을 렌더링 파이프라인 이라고 한다.
렌더링 파이프라인의 과정
마소 도큐먼트에서 사진을 하나 가져왔다.
그림만 봐도 드럽게 재미없게 생겼다.
Input Assembler
어셈블이라는 단어는 너무 유명할테지만 어셈블러는?
내가 본 유튜브에서는 Input Assembly라고 나와있어서 검색을 해봤다.
렌더링 파이프라인에서의 어셈블리가 이것을 의미하는지는 모르겠지만 뜻만 보면 너무나 적합하다.
이 과정은 글자 그대로 주입을 하는 과정이다.
CPU가 하드디스크 -> 메모리를 통해 가져온 정보들을 GPU에 넘기고
GPU가 VRAM에 받은 정보들을 넣고 연산을 시작한다.
우리 컴퓨터의 메모리의 사용 처럼 VRAM도 앞으로 보여지는 화면의 데이터를 임시 저장했다가 빠르게 모니터에 뿌려주는 역할을 한다.
그래서 화면에 보여지는 양이 많으면 많을 수록 , 그 품질이 높으면 높을수록 VRAM의 필요 용량은 늘어난다.
CPU와 GPU
CPU : Central Processing Unit
GPU : Graphics Processing Unit
우리에게 CPU는 너무나 익숙하다.
컴퓨터를 맞추려면 너무나 자연스럽게 알게되는 부품인데
컴퓨터의 머리라고 할 수 있다.
요즘은 멀티코어다 뭐다 해서 한번에 많은 작업을 수월하게 할 수 있는 멀티 코어 CPU들이 나온다.
위의 사진을 보면 CPU는 8개의 코어가 있지만 GPU는 수천개의 코어들을 가지고 있다.
저게 가능하면 왜 CPU는 달랑 코어 저거만 씀??
이라는 의문이 들 수 도 있다.
컴퓨터에서 CPU가 하는 일은 순서대로 굵직굵직한 일들을 하나하나 처리해도 상관이 없지만
GPU는 들어오는 엄청나게 많은 정보들을 한꺼번에 처리해야 한다.
그래서 CPU의 코어들보다 작은 코어들이 수천개가 있는 것이다.
당연히 GPU의 코어 하나는 큰 CPU의 코어보다 성능이 낮고 작은양의 연산을 하나씩 담당하여 수백 수천개의 작업을 한번에 처리 하기에 적합하다.
버텍스 버퍼와 인덱스 버퍼
Vertex : 꼭지점
Index : 색인
우리가 당장 펜을들고 삼각형을 그린다고 하면 버텍스(꼭지점)이 3개가 필요하다.
3개의 점을 선으로 이어보면 삼각형이 1개가 만들어진다.
(참고로 렌더링 파이프라인 에서는 선을 시계 반대 방향으로 연결한다.)
또 사각형을 그리려면 점이 4개이고 이것을 선으로 연결하면 사각형이 그려진다.
하지만 우리가 보는 3D는 사각형 1개가 아닌 삼각형 2개로 사각형이 표현 된다.
즉, 우리가 보는 3D 모델들은 수많은 삼각형의 집합체인 것이다.
그래서 버텍스 버퍼와 인덱스 버퍼가 뭐냐면
먼저 버텍스 버퍼는 버텍스들을 배열 형태로 저장한다.
그리고 그 안에는 버텍스의 위치, 평면에서 90도가 되는 방향의 벡터를 저장하는 버텍스 노말,색깔, uv 등등
여러가지 정보들이 저장된다.
그리고 인덱스 버퍼에는
어떤 순서로 버텍스들을 연결해야 삼각형이 되는지에 대한 정보가 배열로 들어있다.
버텍스 버퍼로도 충분히 삼각형을 그릴 수 있을거 같은데 왜 인덱스 버퍼가 있냐면
버텍스 버퍼엔 이미 많은 정보가 들어가 있고, 중복되는 꼭지점들을 좌표값으로 계속 호출을 한다면
그만큼 메모리와 작업량이 늘어나기 때문이라고 한다.
즉 Input Assembler 과정에서는
이 정보로부터 정점들이 어떻게 연결되어 삼각형을 형성하는지 결정 되는 단계이다.
Vertex Shading
쉐이딩이라는 단어는 보통 색깔을 칠한다 라는 의미로 많이 쓰이지만
여기에서 쉐이딩은 프로그래밍이라고 생각하면 쉽다고 한다.
- 정점들의 정보를 얻어와 정점별로 연산을 수행
- 이 단계의 목적은 정점들을 변환(Transform) 이라는 연산을 통해
현재 설정된 카메라의 위치를 중심으로 위치값을 재계산 하는 것
1.
예를들어 3d 물체 2개의 좌표가 자신의 공간에서 각각 (0,0,0) 이라고 해보자.
이 2개의 물체를 한 월드에 옮긴다면 좌표가 같기 때문에 물체가 겹칠것이다.
그래서 처음으로 하는 변환이 오브젝트 좌표(로컬 좌표) 에서 월드 좌표로 옮기는 것이다.
3D 물체 2개를 동일한 공간에 적절한 좌표로 옮겨준다.
2.
이러면 끝이 아니라 , 이젠 우리가 보는 카메라 공간으로 옮겨야 한다.
이것을 view transform이라고 한다.
3.
우리가 보는 모니터는 평면이다.
3D 물체들을 원근감이 있는 카메라 공간으로 옮겨놨다면 2d로 찍어내기 전에 정육면체로 변환시키는것이 Projection transform 이라고 한다.
(카메라 공간에서 시야를 정하고 보이지 않는 메쉬들을 잘라내어 최종적으로 카메라 시야에 보이는 메쉬들만 위치한 공간)
Rasterizer
우리는 버텍스들로만 화면을 채워놨기 때문에 그 안에 픽셀들도 채워 넣어야한다.
변화된 버텍스들로 삼각형을 조립 한 후에,
각 삼각형 내부를 차지하는 Fragment를 생성한다.
Fragment
컬러 버퍼의 한 픽셀을 갱신하는데 필요한 데이터를 총칭함
Input Assembler 과정에서 넣었던 버텍스 버퍼에 있는 정보들을 보간 처리하여 픽셀들에 넣어줌.
예를들어 버텍스1의 컬러는 하얀색이고, 버텍스2의 컬러는 검정색이라면
버텍스1 -> 버텍스2 사이에 있는 컬러들은 1에서 2로 갈수록 검정색에 가까워짐.
그리고 클리핑,원근나누기,뒷면제거,뷰포트변환,스캔변환의 작업들도 이루어짐.
Pixel Shading
픽셀의 최종 컬러값이 결정 됨.
Material의 속성,텍스쳐,라이팅 등 다양한 파라미터값이 결합 되어 처리
이 단계에서 엄청난 픽셀들을 찍어내기 떄문에
GPU는 이 단계에서 가장 많은 시간을 소모함.
Render Target Output
출력 병합.
Fragment와 현재 컬러 버퍼에 저장된 픽셀중 하나를 선택한다.
예를들면 이 물체 앞에 어떤 투명한 물체가 있다면 색이 투영되어 새로운 색이 만들어 지던지,
앞에 다른 물체가 완전히 가리고 있다면 그 픽셀은 앞의 물체의 색으로 채워지던지..와 같은 작업들이 이루어진다.
(Depth, Alpha/Stencil test 등등)
그래서 최종적으로 출력이 되는 단계이다.
마치며..
한 교수님이 강의하신것을 유튜브로 올려두셔서 그것을 보며 필기해둔것을 인터넷을 찾아가며 정리했다.
들으면서는 어느정도 이해가 갔는데 아직도 정확한 개념이 머리에 잡히지 않아 여러번 복습을 해야 할 것 같다.
그래도 다이렉트X 수업들으면서 버텍스 버퍼와 인덱스 버퍼를 수도없이 들었는데 이제 좀 더 이해하며 수업을 들을 수 있어서 기쁘다.
나중에 다른 정보들도 정리를 해봐야겠다.
끝.
'프로그래밍 공부 > C++ 프로그래밍' 카테고리의 다른 글
Direct X 7일차💻 DirectX의 시작 (0) | 2022.06.22 |
---|---|
Direct X 6일차💻 <WINAPI> #마지막 (0) | 2022.06.21 |
Direct X 5일차💻 <WINAPI> #3 (0) | 2022.06.19 |
Direct X 4일차💻 <WINAPI> #2 (0) | 2022.06.19 |
WINAPI 추가정리 (0) | 2022.06.19 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!