본문 바로가기

공부/Open GL ES를 이용한 3차원 컴퓨터 그래픽스 입문

[Open GL ES를 이용한 3차원 컴퓨터 그래픽스 입문] 챕터 5 - 정점 처리

728x90
반응형

GPU 렌더링 파이프라인

  • 이 그림에서 파란색으로 보이는 쉐이더 부분은 프로그램과 동의어이다.
  • 즉, 우리는 GPU 렌더링을 위해서 정점 쉐이더(vertex shader)프래그먼트 쉐이더(fragment shader)라는 두 가지 프로그램을 작성해야 한다.
  • 반면, 래스터라이저(rasterizer)출력 병합기(output merger)는 하드웨어로 고정된 단계로, 정해진 연산과 기능만을 수행한다.

 

  • 정점 쉐이더는 정점 배열에 저장된 모든 정점에 대해서 변환(transform)을 비롯한 다양한 연산을 수행한다.
  • 래스터라이저는 변환된 정점들로 삼각형들을 조립한 후, 각 삼각형 내부를 차지하는 프래그먼트(fragment)를 생성한다.
  • 프래그먼트는 컬러 버퍼의 한 픽셀을 갱신하는 데 필요한 데이터를 총칭하는 것이다.

 

  • 래스터라이저가 출력한 프래그먼트는 하나하나 프래그먼트 쉐이더로 입력되어, 라이팅과 텍스처링 등의 작업을 거쳐 색상이 결정된다.
  • 출력 병합기는 이러한 프래그먼트와 현재 컬러 버퍼에 저장된 픽셀 중 하나를 선택하거나 혹은 이들의 색을 결합하여 컬러 버퍼를 갱신한다.

 

정점 쉐이더가 수행하는 변환 세 가지

  • 월드 변환의 절반은 4장에서 설명했으며, 이번 5장에서는 절반과 나머지 두개를 설명한다.

 

 


 

 

5.1 노멀의 월드 변환

  • 월드 변환은 아핀 변환들로만 구성되었다면 [L | t]로 표기할 수 있다.
  • L은 '누적된 선형 변환'을, t는 '누적된 이동'을 표현하는데, 노멀 변환에 있어 t는 무시해도 된다. 벡터는 이동에 의해 영향 받지 않기 때문에 생각을 안해도 된다.

 

노멀 변환, 정점과 노멀 모두 동일한 행렬 L에 의해 변환되었다.
정점은 L에 의해 변환되지만, 노멀은 L^T에 의해 변환되어야한다.

  • 위 그림에서 L을 노멀에 적용했을 때 문제가 발생했던 것은 L이 비균등 축소확대였기 때문이다.
    → 만약 L이 비균등 축소확대를 포함하지 않는다면, 즉 L이 회전, 이동, 균등 축소 확대 중 하나이거나 이들이 결합된 경우라면, 노멀에 L을 적용해도 된다.
  • 하지만, 알고리즘을 단순화하기 위해, L이 비균등 축소확대를 포함하건 말건 노멀 변환에는 무조건 L^-T를 사용할 것이다.
    → 굳이 조건을 하나 더 달아 노멀에 L을 적용하지 말고 모든 경우에 L^-T를 사용하는 게 좋기 때문이다.
  • 이해를 돕기 위하여 위 그림에서는 삼각형 노멀을 사용했지만, 폴리곤 메시 렌더링에 실제로 사용되는 것은 정점 노멀이다. 월드 공간 정점 노멀 계산에도 L^-T가 그대로 쓰인다.

 

 


 

 

5.2 뷰 변환

  • 월드 변환이 완료되어 모든 물체가 월드 공간에 모아졌다고 가정하자. 월드 공간의 특정 영역을 스크린에 렌더링하기 위해서는 가상 카메라의 위치와 방향을 설정해야 한다.

 

5.2.1 카메라 공간

EYE, AT, UP으로부터 카메라 공간이 정의된다.

  • EYE는 월드 공간에서의 카메라 위치이다.
  • AT은 월드 공간에서 카메라가 바라보는 기준점이다.
  • UP은 카메라의 상단이 가리키는 방향을 대략적으로 묘사하는 벡터이다.
    → 이들 파라미터를 이용해 카메라 공간(camera space)이 정의되는 데, 그 원점은 EYE에 놓여진다.

 

  • 카메라 공간으 ㅣ기저를 {u, v, n}으로 표기하자. 가운데 상자는 EYE, AT, UP을 사용해 어떻게 {u, v, n}이 계산되는지 보여준다.
  • 우리는 카메라 공간을 {u, v, n, EYE}로 표기한다.

 

 

 


 

 

 

5.2.2 공간 이전과 뷰 행렬

카메라 좌표계를 월드 좌표계에 포개 놓기 위함

  • 하나의 공간에서 정의된 물체를 다른 공간으로 옮기는 것을 일반적으로 공간 이전(space change)이라고 부르는데, 월드 공간에서 카메라 공간으로의 이전은 카메라 좌표계 {u, v, n, EYE}를 월드 좌표계 {e1, e2, e3, O}에 포개 놓는 과정으로 묘사될 수 있다.
  • 이를 위해서는 EYE를 먼저 O로 '이동'시킨 뒤 {u, v, n}을 {e1, e2, e3}와 일치하도록 '회전'시키면 된다.
  • 이 과정에서 모든 물체는 카메라 좌표계를 따라 같이 움직인다.

 

'이동'과 '회전'이 필요하고, 이 두 변환이 결합된 것이 뷰 변환인데, 이는 월드 공간의 물체를 카메라 공간으로 옮긴다.

  • 월드 공간 좌표가 (10, 2, 0)이던 주둥이 끝 정점도 이동과 회전을 거쳐 (0, 0, -10)의 좌표를 가지게 되었는데, 이제 월드 공간과 카메라 공간이 동일해졌으므로, 이 월드 공간의 좌표 (0, 0, -10)을 그대로 카메라 공간 좌표로 취하면 된다.
  • 월드 공간에서 카메라 공간으로의 이전을 뷰 변환(view transform)혹은 카메라 변환(camera transform)이라 부른다.

 

회전 변환
월드 공간의 모든 물체에 적용된다.

  • 이동에 의하여 월드 공간과 카메라 공간은 원점을 공유하게 된다.
  • 따라서, 기저{u, v, n}은 회전을 통하여 {e1, e2, e3}에 포개질 수 있다.
  • 이 회전은 카메라 공간의 기저 {u, v, n}을 행으로 가지는 행렬로 정의된다.
  • 결국 물체들은 R에 의해 회전되어 공간 이전이 완료된다.
  • 공간 이전을 구성하는 이러한 회전은 기저 이전(basis change)이라고 부른다.

 

 

 

공간 이전은 앞으로 여러번 언급되고 중요한 내용이니 완벽하게 이해해야한다.

 

 

 


 

 

 

5.3 오른손 좌표계와 왼손 좌표계

오른손 좌표계와 왼손 좌표계

  • 3차원 카테시안 좌표계는 오른손 좌표계왼손 좌표계로 나뉜다.
  • Direct3D는 왼손 좌표계를 사용하지만, OpenGL과 OpenGL ES는 오른손 좌표계를 사용한다.
    → 따라서, 이 책도 기본적으로 오른손 좌표계를 사용한다.

 

오른손 좌표계에서 왼손 좌표계로의 포팅 [1/2]
오른손 좌표계에서 왼손 좌표계로의 포팅 [2/2]

  • 예를 들어, OpenGL에서 모델링한 물체를 Direct3D로 포팅하는 경우가 이에 해당한다.
  • (a), (b)처럼 좌우가 뒤바뀌어졌음을 알 수 있다.

 

 

 

해결 방법은 간단하다. 포팅 시 물체와 카메라 파라미터의 z좌표의 부호를 바꾸면 된다.

 

 

 

  • z좌표의 부호를 바꾸는 것은, (a)에서 (c)로 넘어오는 과정이 직관적으로 보여주는 것처럼, z축을 반대 방향으로 돌리는 것으로 생각하면 이해가 쉬울 것이다.

 

 


 

 

5.4 투영 변환

  • 월드 공간에서 정의된 EYE, AT, UP을 카메라의 '외부'파라미터라고 본다면, 이제 카메라의 렌즈를 선택하고 줌인/줌아웃을 조절하는 것에 해당하는 '내부'파라미터를 정의할 차례이다.

 

 

5.4.1 뷰 프러스텀

피라미드 모양의 뷰 프러스텀 바깥의 폴리곤은 최종 스크린에 나타나지 못한다. [1/2]
피라미드 모양의 뷰 프러스텀 바깥의 폴리곤은 최종 스크린에 나타나지 못한다. [2/2]

  • 일반적으로 카메라의 시야(Field of view; fov)는 제한되어 있기 때문에 카메라 공간의 모든 물체를 스크린에 담아낼 수 없다.
  • 카메라의 가시 영역을 뷰 볼륨(veiw voilume)이라 부르는데, 이는 fovy, aspect, n, f 네 가지 파라미터를 사용해 결정된다.

 

 

fovy : field of view y-axis (y축 기준의 시야각)
aspect : 뷰 볼륨의 종횡비(가로세로 비율 = width/height)

 

 

  • fovyaspect에 의해 정의된 뷰 볼륨은 꼭지점을 원점에 두고 -z축을 중심축으로 가진 무한한 크기의 피라미드가 된다.
  • 뷰 볼륨을 정의하는 나머지 파라미터 n과 f는 각각 원점으로부터 전방 평면(near plane)후방 평면(far plane)까지의 거리를 나타낸다.

 

fovy와 aspect에 의해 정의된 무한한 크기의 뷰 볼륨은 z축에 수직인 전방 평면 z = -n과 후방 평면 z= -f에 의해 절단되어 유한한 크기의 뷰 볼륨으로 바뀐다.
  • 이를 뷰 프러스텀(view frustum) 혹은 절두체라고 부른다.
  • 원통 및 구와 같이 뷰 프러스텀 바깥에 놓인 물체는 대개 미리 걸러져서 GPU 파이프라인에 들어가지 못하게 한다. (=culling)

폴리곤이 뷰 프러스텀의 경계에 걸치는 경우 그림의 빨간색으로 표시된 부분은 잘라져 버려진다. 이를 클리핑이라 한다.

 

 

 


 

 

 

5.4.2 투영 행렬

  • 투영 변환(projection transform)은 한 마디로 말하자면, 피라미드 모양의 뷰 프러스텀을 좌표계의 주축에 나란한 2x2x2 크기의 정육면체 뷰 볼륨으로 변형하는 것이다.
  • 카메라 공간 물체는 이렇게 투영 변환을 거친 뒤, 2x2x2 크기의 정육면체에 대해 클리핑된다.
  • 이런 점에서, 투영 변환 이후에 물체가 놓이는 공간을 클립 공간(clip space)이라고 따로 부른다.

 

투영 변환, 뷰 프러스텀을 정육면체로 변형하는 투영 변환이 카메라 공간의 물체에 적용되었다. [1/2]
투영 변환, 이 단면도는 투영 변환이 원근법을 구현함을 보여준다.

  • 뷰 프러스텀은 원점에 위치한 카메라로 수렴하는 투영선(projection lines)들의 집합으로 이해할 수 있다.
  • 3차원 공간에서는 l1이 l2보다 길지만 투영 평면에서 이들은 동일한 길이를 가지게 된다. 즉 멀리 있는 물체가 작게 보이게 되는데 이것이 바로 원근법이다.
  • 투영 변환의 결과, 모든 투영선들은 서로 평행해져 z축에 나란해졌다. 즉, 단일한 투영 방향을 가지게 되었다.
  • 투영 변환은 정점 쉐이어가 수행하는 마지막 연산이다. 투영 변환된 물체는 이제 하드웨어로 고정된 래스터라이저로 들어갈 것이다.

 

투영 행렬

  • 뷰 프러스텀을 2x2x2 크기의 정육면체로 변형하는 투영 행렬은 다음과 같다.

 

모든 정점의 z좌표 부호가 바뀌었다. 개념적으로 이는 물체를 고정한 채 좌표계의 z축을 반전시킨 것과 동일하다.

  • 클립 공간의 물체는 래스터라이저로 입력된다. 클립 공간은 '오른손'좌표계이다.
  • 그런데 래스터라이저는 모든 물체가 '왼손' 클립 공간에서 정의되어 있다는 가정에서 설계되어있다.
  • 따라서 우리는 래스터라이저로 진입하기 위하여 오른손 좌표계를 왼손 좌표계로 변환해야 한다.
    → 이를 위해서는 정점 z좌표의 부호를 변경하면 된다.
  • 따라서 v'의 z좌표 부호를 바꾸기 위해서는 세 번째 행의 모든 원소의 부호를 바꾸면 된다.

 

ㅚ종적으로 오른손 카메라 공간의 물체가 왼손 클립 공간으로 변환된 것을 보여준다.

 

 


 

 

출처

[OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문]을 보고 공부하고 정리한 내용입니다.

728x90