일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- C# delegate
- git
- 유니티
- HTML
- c#
- Unity
- github
- C언어 포인터
- 깃
- jupyter
- C++
- 플러터
- Python
- c# winform
- Data Structure
- gitlab
- dart 언어
- 구조체
- c# 윈폼
- 다트 언어
- docker
- c# 추상 클래스
- Flutter
- jupyter lab
- Houdini
- vim
- 도커
- c언어
- 포인터
- Algorithm
- Today
- Total
nomad-programmer
[CG/HLSL] 렌더링 파이프라인 (Rendering Pipeline) 본문
- 오브젝트 데이터 받아오기
- 정점(버텍스: vertex) 셰이더
- 래스터라이져(Rasterizer)
- 픽셀셰이더(Pixel Shader) / 프레그먼트 셰이더(Fragmanet Shader)
1. 오브젝트 데이터 받아오기
그래픽 카드는 버텍스로 이루어진 물체의 데이터 값을 받아온다. 아직 화면에는 아무것도 존재하지 않고, 그래픽 카드 내부의 값으로만 존재하는 데이터일 뿐이다. 버텍스는 다음과 같이 필요한 정보들을 가지고 있다.
- 버텍스의 인덱스 넘버 (Index number)
- Position
- Normal
- Color
- 등등...
이제 그래픽 카드에서는 이 버텍스의 정보들을 가지고 버텍스들이 이어진 삼각형 면을 생성하게 된다. 오브젝트의 기본적인 형태가 갖추어졌고, 이 정보들을 버텍스 셰이더로 넘길 준비가 되었다.
2. 정점(버텍스: vertex) 셰이더
이제 이 데이터를 가지고 본격적인 셰이딩 작업이 가동되기 시작한다. 첫 번째 과정이 '정점 셰이더'라고도 불리는 버텍스 셰이더(vertex shader)이며, 이 데이터를 이용해 다음과 같은 좌표 변환을 한다.
- 버텍스의 위치 값은 현재 로컬(Local) 좌표계이다. 로컬 좌표계란 물체가 가지고 있는 '자기 중심적인' 위치 값을 의미한다. 오브젝트별로 가지고 있는 본인의 피봇이 0, 0, 0 위치 값(중심값)인 상태이다. 여기에서는 게임 안에 존재할 수 있는 다른 오브젝트의 위치는 전혀 고려되지 않는다. 즉, 모든 오브젝트들은 자기가 세상의 중심인 상태이다. 유니티에서는 이 로컬 좌표계를 "오브젝트(Object) 좌표계"라고도 부른다.
- 이제 여기에 '월드 변환 행렬(월드 좌표계)'을 곱해줌으로써, 로컬 좌표계를 월드 좌표계로 변환해준다. 월드 좌표계란, 절대 좌표인 월드 좌표계의 위치로부터 각 물체의 상대적 위치 값을 의미한다. 월드 좌표계에서는 실제 이 월드의 중심점인 0, 0, 0이며, 다른 물체들은 여기서 얼마나 떨어져 있는지로 표현된다. 여기서 각 오브젝트들은 더 이상 자기가 세상의 중심이 아니란 것을 알게 된다. 유니티에서는 이 월드(World) 좌표계를 '모델(Model)' 이라고 부른다. 그렇지만 여전히 카메라가 없기 때문에 화면에 출력할 수 없는 상태이다.
- 월드 행렬로 변환된 물체들은 이제 이 월드에 위치 값을 가지게 되었다. 그러나 여기에 아직 고려되지 않은 것이 있는데 바로 '카메라'이다. 월드에 존재하는 것은 알겠지만, 카메라가 없으면 화면에 보일 수 없다. 그래서 월드 좌표계의 버텍스들은 이제 다시 '카메라 행렬'로 곱해서 월드 좌표계에서 살고 있던 오브젝트의 버텍스 위치 값들이 카메라의 중심점으로부터의 상대적 거리로 다시 연산된다. 즉, 이 세계에서는 카메라의 중심점이 0, 0, 0이며, 다른 물체들은 여기에서 얼마나 상대적으로 떨어져 있는지로 표현된다. 드디어 물체들은 화면에 볼 수 있게 되었지만, 원금감은 고려되어 있지 않다. 카메라 행렬은 "뷰(View)"라고 불리며, 오쏘그래픽 프로젝션(Orthographic Projection)이라 불리기도 한다.그리고 이 시점부터 모니터에 출력하는 것이 가능한 상태가 된니다.
- 이렇게 카메라 행렬로 정렬된 버텍스들은, 다시 한번 '프로젝션(Projection) 행렬'로 곱해진다. '프로젝션 행렬'이란 원금감을 부여해주기 위한 방법으로, 카메라에서 먼 곳은 좁혀진 것처럼 버텍스 위치를 조정해주는 것이다. 사실상으로 카메라에서 멀수록 크기가 작아지는 물체가 된다. 그리고 흔히 볼 수 있는 뷰의 모습이 된다.
여기까지의 작업을 그대로 모니터에 출력한다면, 여전히 텍스쳐도 음영도 없는, 말 그대로의 폴리곤 덩어리가 생성된다. 화면에 찍힐 수 있는 준비는 되었지만, 이 오브젝트는 아직 필셀 셰이더를 거치지 않았기 때문이다. 결과적으로 모니터로 볼 수도 없는 단지 3D 공간에서 존재하는 오브젝트일 뿐이다.
3. 래스터라이져 (Rasterizer)
이렇게 좌표계가 조정된 버텍스를 이용해서 화면에 오브젝트를 출력할 준비가 되었다. 이 오브젝트가 모니터에서 표현될 때 어느 필셀로 표현될 것인지를 나타내는 장치를 거지게 되는데 이것을 래스터라이져(Rasterizer)라 부르며, 2D 픽셀로 표현되는 세계로 넘어오게 된다.
이제 3D 오브젝트는 모니터에 보이도록 '픽셀(Pixel)'이 되었고 이 과정을 '래스터화'라고 한다. 3D로 있떤 '석고상'을 촬영하는 순간 그 석고상은 2D 이미지가 되듯이, 3D 이미지가 2D 이미지가 되는 순간이다. 모니터에 보이려면 2D 이미지로 만들어야 하니 말이다.
이렇게 수학적인 가상 공간 안에서 입체로 떠돌던 오브젝트는 픽셀이 되고, 픽셀셰이더에서 이 픽셀에 접근할 수 있게 된다.
최근 Direct-X에서는 여기에 여러 가지의 셰이더가 추가로 들어간다. 버텍스 셰이더와 픽셀 셰이더의 중간에 위치하는 이 셰이더는 헐 셰이더(Hull Shader), 테셀레이터(Tessellator), 도메인 셰이더(Domain Shader), 지오메트리 셰이더(Geometry Shader), 컴퓨트 셰이더(Compute Shader) 등이 있다.
이 모든 작업이 매 프레임마다 일어난다.
4. 픽셀셰이더(Pixel Shader) / 프레그먼트 셰이더(Fragment Shader)
이렇게 모니터까지 넘어온 3D 그래픽 데이터는 본격적으로 화면에 픽셀로 찍히게 된다. 여기에 픽셀셰이더가 가동되면서 조명과 텍스처, 그림자와 각종 특수효과등을 연산하게 된다.
그러므로 이 프로세스를 아주 간략하게 정리해 보면 다음과 같다. 물론 실제 렌더링 프로세스가 이렇게 간략하진 않다.
'CG > HLSL' 카테고리의 다른 글
[CG/HLSL] 셰이더 관련 유용한 사이트 모음 (0) | 2021.11.06 |
---|