본문 바로가기

Library/Computer Graphics

Viewport Transformation

뷰포트 변환(viewport transformation)은 전 단계의 투영 변환의 결과를 이용하여 출력 장치 좌표계로 매핑하여 실제 장치에 출력된 2D 영상을 만들어내는 단계이다. 뷰포트 변환은 투영 방식에 상관없이 장치 좌표계로 변환할 수 있는데, 이것은 이미 투영 변환에서 투영 방식을 고려하여 정규화했기 때문이다. 화면에 최종적으로 출력하기 위해 필요한 것은 (x, y) 한 쌍의 좌표값이며, z = 0 평면에 무엇이 위치해야 할지는 z-버퍼(z-buffer) 검사에 의해 결정된다.

뷰포트 변환에서는, 출력할 윈도우(window)와 윈도우 내에서의 출력 공간을 지정하는 뷰포트(viewport)가 필요하다. 윈도우 크기와 뷰포트 크기가 동일할 때도 있지만, 언제나 그런 것은 아니다. 뷰포트 변환 행렬은, 정규화된 체적(canonical view volume) 내에서의 물체들의 위치와 뷰포트에 출력할 물체들의 위치의 비가 동일하다는 점을 이용하여 형성된다. 여기서 뷰포트의 좌표축은 그래픽 시스템에 따라 달라질 수 있는데, 예를 들어 OpenGL은 윈도우의 좌하단이 원점이 되지만, 윈도우즈는 뷰포트의 좌상단이 원점이다. OpenGL을 기준으로 한다면, 정규화된 체적에서의 각 물체를 뷰포트로 매핑하는 식은 다음과 같을 것이다.

P(x, y) : 정규화된 체적 내에서의 물체의 위치
P'(x', y') : 뷰포트에 위치할 물체의 위치(구하는 값)
left : 윈도우 내에서 뷰포트가 위치하는 좌측값
bottom : 윈도우 좌하단에서 뷰포트가 위치하는 하단값
width : 뷰포트의 길이
height : 뷰포트의 높이

x - (-1) : x' - left = 1 - (-1) : width
(x' - left) * (1 - (-1)) = (x - (-1)) * width
x' = (x - (-1)) * width / (1 - (-1)) + left

y'에 대해서도 동일하게 적용되며, z 값은 0이므로 고려할 필요가 없다. 또, 이 변환은 선형변환이기 때문에 동차 좌표계의 행렬곱으로 표현할 수 있다. 그러나, 뷰포트 변환 행렬은 특이행렬(sigular matrix)이기 때문에 역변환이 존재하지 않는다. 즉, 뷰포트 변환 뒤에 z 값은 완전히 소실된다.

대부분의 그래픽 시스템은 z 값을 재정규화하는데, [-1, 1] 사이의 z 값을 [0, 1] 사이의 값으로 재정규화한다. 부호 없는 정수형의 대소 비교가 조금 더 빠르기 때문이다. 재정규화를 하더라도 물체의 상대적인 깊이는 유지되며, 재정규화 하기 위해서는 z축 방향으로 1 / 2 만큼 축소한 뒤, z 방향으로 1 / 2 만큼 이동하면 된다. 물론, 이 때는 행렬식에서 z값에 해당하는 행이 0으로만 구성되어 있지 않다.

마지막으로 고려할 문제는, 정규화된 체적의 종횡비와 뷰포트의 종횡비의 일치 여부이다. 둘의 비율이 맞지 않는다면, 영상의 왜곡이 일어나게 된다.