Clip Space
간단히 말해서, 클립 공간은 프리즘으로 모델링되고, 이것을 클립 볼륨이라고 합니다. 만약 Primitive의 정점들이 이 공간 밖에 있다면 그 정점들은 GPU에 의해 클리핑됩니다. 어쨌든 우리는 그 정점들을 볼 수 없기 때문에 이는 불필요한 계산을 피하기 위한 절차입니다.
클립 볼륨은 다음 두 위치로 경계된 상자로 정의됩니다:
$$ (-w, -w, 0), (w, w, w) $$
여기서 w는 정점의 추가적인 차원이며 정점을 동차좌표계로 만드는 역할을 합니다.
GPU에 의해 클리핑되지 않기 위해 클리핑 공간에서 \(x)\, \(y)\, \(z)\ 좌표는 다음 조건이 되어야 합니다.
$$ -w \leq x \leq w $$
$$ -w \leq y \leq w $$
$$ 0 \leq z \leq w $$
Clip Space로의 변환
모델 좌표계에 정의된 정점을 클립 공간으로 변환하는 곳이 바로 Vertex Shader입니다. Vertex Shader의 output이 클립 공간의 input이 되는 것이죠.
Vertex Shader에서 변환된 좌표를 반환하는 일반적인 공식:
$$ out.position = projectionMatrix * viewMatrix * modelMatrix * inputModelSpacePosition $$
(Row Major 임에 주의하세요. Projection 변환이 가장 나중에 수행되어야 합니다.)
- inputPosition - 모델 좌표계에서의 4차원 정점 위치 (동차좌표계)
- modelMatrix - 모델 좌표계의 정점들을 월드 좌표계로 변환하는 4x4 행렬
- viewMatrix - 월드 좌표계의 정점들을 카메라 공간으로 변환하는 4x4 행렬
- projectionMatrix - 카메라 공간의 정점들을 클립 공간의 투영 좌표로 변환하는 4x4 행렬
참고) 클립 볼륨 외부에 있는 Primitive가 Clip 되는 방식
Clip은 GPU에서 알고리즘을 통해 적절하게 Primitive를 분리하여 볼륨을 벗어난 부분을 제거하는 것입니다. 반면 Culling은 Primitive가 아닌 Object를 제거하는 것입니다. Clip 이후에는 저렇게 새로운 정점들이 생긴 것을 볼 수 있습니다.
NDC (Normalized Device Coordinates)
클립 볼륨 외부에 있는 정점을 클리핑한 후 나머지 정점의 위치는 NDC(Normalized Device Coordinates)라는 공통 좌표계로 정규화됩니다.
GPU는 모든 정점 성분을 \(w)\ 성분으로 나누는 원근법 분할이라는 연산을 수행하여 이 좌표계로 들어가는 작업을 수행합니다.
\[ \begin{pmatrix} x_{ndc} \\ y_{ndc} \\ z_{ndc} \end{pmatrix} = \begin{pmatrix} \frac{x_c}{w_c} \\ \frac{y_c}{w_c} \\ \frac{z_c}{w_c} \end{pmatrix} \]
우리는 방금 \(w)\차원 프리즘 밖에 있는 모든 정점들을 잘라냈다는 것을 기억하세요. 따라서 \(x)\와 \(y)\성분을 \(w)\성분으로 나누어 정규화한 후에 각 성분은 -1과 1 사이가 되어야 합니다. \(z)\성분의 경우 정규화된 좌표는 0과 1 사이가 될 것입니다.
각각의 그래픽 API는 다르며 사용하고 있는 그래픽 API에 대해서는 설명서를 참조해야 하지만, WebGPU와 Direct X의 경우 NDC는 (-1, -1, 0)과 (1, 1, 1) 사이에 있는 반면, OpenGL의 \(z)\좌표는 -1과 1사이로 정의됩니다.
출처
https://carmencincotti.com/2022-05-02/homogeneous-coordinates-clip-space-ndc/
'Computer Graphics' 카테고리의 다른 글
깊이 버퍼(depth buffer)와 스텐실 버퍼(stencil buffer) (0) | 2024.02.28 |
---|