
Projection 변환 행렬

Projection은 3차원 공간에 있는 물체들을 2차원 화면에 투영하는 것이다. 투영하는 것은 카메라로부터 멀리 떨어져 있을 수록 작게 표시되기 때문에 떨어져 있는 만큼 좌표를 나누면 화면에 출력하는 좌표가 된다. 먼저 2차원으로 변환하고 해상도에 맞게 크기를 조절하면 크기가 달라질 수 있으므로 변환할 때 x에만 (그림의 y도 r로 나누는건 잘못된 것) 화면비율 width/height으로 나눈다. 해상도에 따라 크기가 늘어나는 것을 대비해 미리 줄여주는 것이다. 또한 카메라의 시야각(FOV)에 따라 출력되는 것이 달라지므로 시야각이 달라지는 것을 대비해야 한다. 최대 tan(θ/2) 크기를 가질 수 있는 것을 크기 1까지 줄여야하므로 tan(θ/2)로 나누어준다.


행렬로 표현하면 (x,y,z,1)에 왼쪽 행렬을 곱하면 오른쪽 행렬이 나온다. 그런데 오른쪽 행렬의 세번째에 z를 보관할 수 없다. 왜냐하면 Depth Stencil 정보가 세번째에 저장되기 때문이다.

그래서 z값을 4번째 1이 있는 곳에 저장하기 위해 별도 처리를 진행해야 한다. 그래서 왼쪽 행렬의 세번째 행 네번째 열을 1로 만들면 곱셈 과정에서 4번째에 z가 저장된다. 그리고 카메라의 near과 far을 depth의 0,1로 맞춰주기 위해 세번째 행 세번째 열을 A 네번째 행 세번째 열을 B로 지정하고 계산하면 결과물의 세번째 값은 A*Z + B가 된다. 그러면 레스터라이즈 단계에서 행렬을 z(네번째 요소)로 나누기 때문에 Depth 식은 A + B/Z 가 된다. g(Z) = A+ B/Z에 대하여 g(n) = 0, g(f) = 1이므로 이것을 계산하면 A = f/(f-n), B = -nf(f-n) 이다.
Screen 변환 행렬

Screen으로 변환할 부분에 대해서 x좌표 y좌표 모두 -1에서 1까지 범위를 가진다. 그래서 실제 Screen으로 변환하는 것은 Screen의 Left, Top위치에 변환 전 비율과 해상도(Width, Height)를 곱한 것을 더한 것이 된다. y는 내려가는 것을 -로 표현한다.

행렬로 표현하면 위와 같다. Z값도 조정할 수가 있는데, MinDepth와 MaxDepth로 최소, 최대 깊이를 정할 수 있다. near일 때 Depth가 0, far일 때 Depth가 1이였는데 이것을 다시 한번 변환해서 MinDepth와 MaxDepth로 최소 깊이와 최대 깊이를 다시 정해줄 수 있다. 식으로는 Z= MinD + Z(MaxD-MinD) 이다.
'그래픽스' 카테고리의 다른 글
| [DX12] Frustum Culling (0) | 2022.02.28 |
|---|---|
| [DX12] Normal Mapping (0) | 2022.02.28 |
| [DX12] World, View 변환 행렬 (0) | 2022.02.26 |
| [DX12] 좌표계 변환 행렬 (0) | 2022.02.25 |
| [DX12] 삼각형 그리기 (0) | 2022.02.24 |