정리 1 게시글에서
렌더링 파이프라인이 보이지 않는 공간에 존재하는 오브젝트들이 2D 화면으로 그려지기까지의 과정이다.
라고 설명했는데, 이번 게시글에서는 이 과정을 풀어서 자세히 정리해보려고 한다.
헷갈리는 용어들 (드로우콜, 배칭, 레스터라이저, 컬링 등)에 대해서도 확실히 이해할 수 있을 것이다.
렌더링 파이프 라인 과정
Mesh의 Lifecycle을 기반으로 설명한다.
1. Mesh를 불러오고, 렌더링할 것을 요구한다.
게임(또는 어플)이 실행되면, 게임은 Mesh를 불러오는 것과 불러온 Mesh를 렌더링할 것을 요구한다.
2. Mesh를 Disk에서 RAM으로 불러온다.
Disk일 때는 .obj, .fbx 등이지만, RAM으로 Load하는 과정에서 메쉬 정보로 바뀐다.
RAM은 버텍스 위치의 정보를 가지는 등 메쉬의 정보를 저장한다.
3. CPU와 GPU의 상호작용이 일어난다.
이 둘은 Queue를 사용해서 상호작용을 하는데, 이 Queue의 이름이 커맨드 버퍼(또는 Ring Buffer)이다.
아까 2번 과정에서 Mesh 정보를 저장하는 RAM이 있었다.
GPU도 GPU를 위한 Video RAM을 가지고 있다.
4. CPU가 GPU에게 무언가를 그릴 것을 요구한다.
커맨드 버퍼를 통해 요구한다.
2단계에 걸친다.
1) Render State 설정해줘라.
RenderState는 메쉬가 그려지는 환경이다.
(Vertex Shader, Pixel Shader, Texture, Lighting Setting을 포함한다.)
2) Mesh 그려줘라. (Draw Call, 드로우콜)
메쉬가 그려질 환경이 세팅되면, 메쉬를 그리라는 명령을 실행할 수 있다.
이렇게 요구하는 동안에, RAM에서 Video RAM으로 메쉬 정보들이 전달된다.
GPU는 VRAM에 접근하는 게 빠르기 때문에, 정보가 VRAM에 전달되는 것이다.
Render State가 설정되었으면, Mesh를 그릴 수 있다.
Render State가 동일하다면, 해당하는 Mesh들은 Render State를 재설정할 필요없이 Mesh를 그리면 된다.
다른 Render State라면, Render State를 재설정하고 이것에 해당하는 Mesh를 그려야 한다.
Render State 설정은 Mesh를 그려달라(Draw Call)하는 작업보다 무거운 작업이다.
이러한 이유로 Batching이 필요한 것이다.
그러므로 Render State가 한번 설정되면, 계속 Mesh를 그릴 수 있도록 하는 것이 좋다.
예를 들어, 유니티는 동일 쉐이더, 머터리얼 ,텍스처 등을 사용하는 것들을 하나로 묶어서 관리한다. (이것이 Batching, 배칭)
5. 메쉬를 그려보자.
Render State와 Draw Call 과정이 끝이나면, 이젠 메쉬를 그릴 차례이다.
6. Vertext Shader, 버텍스 쉐이더 실행
우선, 버텍스 쉐이더가 실행된다.
버텍스 쉐이더는 메쉬로부터 속성을 읽어온다. (예를 들어 정점 위치, 노멀, 탄젠트 등)
이러한 정보들은 World Space -> View Space -> Projection Space로 전환된다.
Space 변환이 이해안되면, 한번 보고 오자. ㅎㅎ
https://mingyu0403.tistory.com/110?category=916229
Projection 행렬이 있다는 것은 카메라를 사용한다는 뜻이고, 픽셀을 그린다는 것이다.
7. Culling, 컬링 (선택적 단계)
픽셀을 그리기 전에, 오브젝트의 앞면, 뒷면(혹은 모두) 어디를 그릴 지 선택할 수 있다. (Culling, 컬링)
Culling은 앞면과 뒷면으로 구분된다. 구분되는 방식은 정점이 그려지는 순서에 의해서이다.
시계 방향이면 앞면, 반시계 방향이면 뒷면이다.
(삼각형으로 그려지는 데, 반시계 방향으로 그려진다는 것은 면이 뒤집혀 있다는 것이므로 뒷면으로 침.)
8. Rasterizer 레스터라이저 실행
컬링이 끝났으면, 메쉬를 모니터에 그리기 위해 어떤 픽셀들이 그려질 지를 결정한다.
픽셀 수만큼 실행된다.
메쉬가 모니터에서 벗어났다면, Projection Space로 전환될 때 잘렸을 것이다. (Clipping, 클리핑)
9. Pixel Shader, 픽셀 쉐이더 (=Fragment Shader 프래그먼트 쉐이더) 실행
레스터라이저를 통해 픽셀 위치가 정해졌다면, 픽셀 쉐이더가 실행된다.
픽셀 쉐이더로부터 얻을 수 있는 것은
최종 픽셀 컬러에 영향을 주는 Pixel Color와 Pixel Alpha,
Pixel z-depth이다.
10. Z Test 실행
Z Test의 결과는 Pass or Fail이다.
예를 들어, 스크린이 10x10 = 100Pixel이라고 했을 때,
0~99의 Color Buffer, 0~99의 Z Buffer가 있다.
Color Buffer에는 Pixel의 컬러가 저장된다.
Z Buffer에는 Pixel의 Z-depth가 저장된다.
모든 Mesh에 대해 Z Test가 계속 실행되면서,
최종적으로는
Color Buffer에는 스크린에 그려질 모든 Pixel의 컬러가 저장된다.
Z Buffer에는 스크린에 그려질 모든 Pixel의 Z-depth가 저장된다.
11. Z Test 가 Pass일 경우, Blending 발생 (선택적 단계)
반투명, 투명 픽셀에 대해 선택적 단계이다.
반투명 오브젝트가 불투명 오브젝트 앞에 올 때 어떻게 합칠까 선택한다.
SrcAlpha OneMinusSrcAlpha 등
12. Stecil Test 실행 (선택적 단계)
특정 부분만 보여지고 싶을 때 실행한다.
오브젝트가 그려지기 이전에 스크린 픽셀에 스텐실 값이 저장되어 있다.
'스텐실이 1값인 픽셀 위치에만 그려라' 하는 것이다.
13. ColorMask 실행
마지막 단계이다.
Color Mask를 실행하면 RGBA 채널 값을 거부하거나 분리할 수 있다.
Red Green Blue Alpha 채널 값이 모여서 색을 가진다. ex) RGBA 값이 (1, 1, 1, 1) 이면 흰색이다.
Color Mask RG 라고 실행하면, 픽셀에서 RG 채널 값만 보이게 한다. BA 채널 값은 거부된다.
14. 최종 컬러 지정
드디어 픽셀의 최종 컬러가 지정되었다.....
최종 컬러는 Color Buffer에 들어가고, 스크린에 그려지게 된다.
Mesh야!!! 너 정말 힘들게 모니터에 그려지는구나...
// 저녁먹고 적겠삼. <- 해서는 안되는 말이다. ㅋㅋ 2019.11.28일부터 지금까지 안 적고 있었다!!
(2021.01.20.)저녁을 좀 많이 오래 먹었네요 ㄷㄷ
엄청나게 늦었지만, 다시 이어서 적었습니다.
'기타 > Unity' 카테고리의 다른 글
[Unity] 캐릭터 파츠 교체하기 / 파츠 구조 변경 후 애니메이션 적용시키기 (0) | 2021.04.01 |
---|---|
[Unity Github Desktop] CRLF 오류 (2) | 2019.12.10 |
[Unity] Rendering Pipeline 정리 2 (기법) (0) | 2019.11.28 |
[Unity] Rendering Pipeline 정리 1 (정의, 종류) (0) | 2019.11.28 |
[Unity Shader] 전광판 쉐이더 만들기 (2) | 2019.11.27 |