본문 바로가기
코딩테스트 및 개인공부/3D 그래픽스(게임수학)

[2] 렌더링 파이프라인 - 1.정점 처리 단계

by JJPearl 2022. 6. 10.
반응형

[Index]

  • 렌더링 파이프라인
  • 정점 처리(Vertex Processing)
    • 선형 변환, 아핀 변환, 동차 좌표, 오일러 변환 -> 월드 변환, 뷰 변환
    • 월드 변환 : 월드 행렬, 월드 공간, 노멀벡터 변환
    • 뷰 변환 : 카메라 공간(뷰 공간)
    • 뷰 프러스텀
    • 투영 변환 : 클립 공간, 클리핑

 

- 렌더링 파이프라인

*파이프라인 : 한단계의 출력이 다음 단계의 입력으로 사용되는 일련의 데이터 처리구조

GPU의 렌더링 파이프라인은 

주로 폴리곤으로 구성된 3차원 장면을 입력으로 받아서

-> 각각의 폴리곤을 2차원 형태로 바꾸고

-> 2차원 폴리곤 내부를 차지하는 픽셀(pixel)의 색깔을 결정하여

-> 3차원 장면의 최종 영상 생성

 

! GPU 렌더링 파이프라인을 구성하는 네 가지 주요 요소

정점 처리(Vertex processing) -> 래스터화(Rasterization) -> 프래그먼트 처리(Fragment processing) -> 출력 병합(Output merging)

정점 처리, 프래그먼트 처리 단계는 프로그래밍 가능

래스터화, 출력 병합 단계는 고정되어 있다.

 

  1. 정점 처리 : 변환을 비롯해 애니메이션,조명(조명은 주로 프래그먼트 처리단계에서 처리하긴 함) 등 다양한 정점별 연산을 수행
  2. 래스터화 : 변환된 정점에 의해 정의된 폴리곤(프리미티브)의 내부를 차지하는 프래그먼트를 생성
    - 픽셀 : 화면을 구성하는 최소 단위. 컬러 버퍼라는 메모리 공간에 저장됨. 한 화면을 생성하기 위해 컬러 버퍼는 여러 차례 수정되고 이 때 수정 과정이 픽셀별로 진행된다.
    - 프래그먼트 : 현재 컬러 버퍼에 저장된 픽셀을 수정하는데 필요한 데이터 모음
  3. 프래그먼트 처리 : 래스터화에서 생성된 프래그먼트들이 입력되어 텍스처링 등의 작업을 거쳐 프래그먼트의 색상이 결정.
  4. 출력 병합 : 이러한 프래그먼트현재 컬러 버퍼에 저장된 픽셀 중 하나를 선택 / 이들의 색상을 결합하여 컬러 버퍼를 수정.

 

 


 

- 정점 처리 단계

오브젝트 공간 --- 월드 변환 ---> 월드 공간 --- 뷰 변환 ---> 카메라 공간 --- 투영변환 ---> 클립 공간

- 월드 변환

- 월드 변환: 렌더링 파이프 라인의 첫번 째 작업.

개개의 물체들을 자기 자신의 오브젝트 공간(로컬 공간) 에서 단일 공간인 월드 공간으로 모으는 것.

 

월드 변환, 뷰 변환은

축소확대(Scaling), 회전(Rotation), 이동(Translation) 등과 같은 기본 적인 변환들을 조합해서 만든다.

- 선형 변환 : 축소확대, 회전

- 아핀 변환 : 이동 => 선형 변환 + 상수 더하기

 

[선형 변환]

- 3차원 축소확대 행렬

벡터 (x,y,z)는 다음과 같이 행렬 곱셈을 통해 축소확대 된다.

Sx,Sy,Sz는 각각 x,y,z 축 별 축소확대 인자. 1보다 작으면 축소/ 1보다 크면 확대

- 3차원 회전 행렬

벡터의 2차원 회전에 대해서 먼저 보자면

벡터 p는 Θ 만큼 회전하여 새로운 벡터 p'가 된다.
열벡터를 사용하는 OpenGL 기준 2차원 회전행렬. (코마신신코)

-> 3차원 회전은 회전축을 필요로 한다.

벡터 (x,y,z)가 z축을 중심으로 회전하여 (x',y',z')로 변환된다면, 

z축을 중심으로 하는 회전이므로 벡터의 z 좌표는 회전행렬에 의해 변화되지 않는다.

z축을 중심으로 하는 회전. 3X3 행렬이 z축 중심 3차원 회전 행렬.
x축 중심 3차원 회전 행렬
y축 중심 3차원 회전 행렬

 

 

[아핀 변환 : 이동]

원래 이동 변환은 다음과 같이 벡터 덧셈으로 표현된다.

하지만 동차 좌표를 사용해 축소확대, 회전 처럼 이동 역시 행렬 곱셈 형태로 표현할 수 있다.

- 동차 좌표: 차원을 하나 높인 것

 e.g.) 한 점의 3차원 카테시안 좌표 (x,y,z) -> 이 점의 동차 좌표 (x,y,z,1)

- 이동을 행렬 곱셈으로 나타내는 이유?

 축소확대,회전 등 변환을 여러번 할 경우 축소확대 행렬, 회전 행렬 끼리 곱해서 복합 행렬 만든 뒤 정점에 한번만 곱한다.

 -> 이동 변환도 행렬이면 곱할 수 있다 

 => 이동을 동차좌표계에서 4X4 행렬로 표현 했으므로 축소확대, 회전 행렬도 4X4로 확장해서 적용

 

4X4 이동변환 행렬. 동차 좌표계에서의 이동 변환. 행렬 곱셈을 통해 한 점의 동차 좌표에 적용된다.
4X4 축소확대 행렬. 선형변환인 축소확대 변환도 4X4 행렬로 확장.

-> 동차 좌표의 네 번째 원소가 항상 1이어야 되는 것은 아님.

동차좌표 (x,y,z,w)는 카테시안 좌표 (x/w, y/w, z/w)에 해당.

e.g.) (1,2,3,1), (2,4,6,2), (3,6,9,3) => 모두 카테시안 좌표(1,2,3) 에 해당

=> 즉, (x,y,z,1)은 카테시안 좌표 (x,y,z)에 해당하는 무한히 많은 동차 좌표들 중 하나임.

 

[월드 행렬]

자신의 오브젝트 공간에서 정의된 구와 주전자가 축소확대,회전+이동 변환을 통해 월드 공간으로 모아진다.
주전자에 적용된 월드 변환 두 단계. 1.y축 중심으로 90도 회전 후 2.x축 따라 7만큼 이동. => 월드 행렬은 (0,2,3)을 (10,2,0)으로 한번에 변환.
행렬 곱셈 할 때는 먼저 한 변환의 행렬을 오른쪽에. 오른쪽이 회전행렬, 왼쪽이 이동행렬임.
오브젝트 공간(0,2,3)의 좌표를 가진 주전자 주둥이가 월드 행렬에 의해 월드 공간 (10,2,0)으로 변환됨.

동차 좌표 사용해서 선형 변환(위 예시에선 회전)과 이동이 하나의 4X4 아핀 행렬로 결합될 수 있다.

아핀 변환 범주에 속하는 축소확대,회전,이동 등이 수없이 많이 결합되도 결과는 하나의 4X4 행렬로 표현됨.

 

 

- 시계 / 반시계 방향 회전

오른손 좌표계(OpenGL) 기준 회전각이 양수라면 반시계 방향으로 회전 / 음수라면 시계 방향으로 그 각의 절대값 만큼 회전

* 왼손좌표계(Direct3D)에서는 회전각이 양수일 때 시계 방향 회전 / 음수일 때 반시계 방향 회전.

아래 행렬은 y축 중심으로 한 -90도 회전을 표현한다.

-@라는 회전각은 2PI-@와 동일함. -> -90도 회전은 270도 회전이랑 동일.

오른손 좌표계 기준 y축 중심 -90도 회전 행렬

 

 

[오일러 변환]

한 물체를 xyz축 중심으로 순차적으로 회전하면 그 물체는 특정한 방향을 가지게 된다.

세축 중심의 회전각 (@x,@y,@z) 는 오일러 각이라 부른다. 이는 한 물체의 방향을 표현하는데 쓰임.

-> 세 개의 회전이 결합 된 것이 오일러 변환

오일러 각을 사용하여 순차적으로 회전하면 특정한 방향 얻게 됨.
행렬 곱 오른쪽 부터 순서대로.

위 주전자 그림 기준 Rx는 Pitch(끄덕각), Ry는 Yaw(도리각), Rz는 Roll(갸웃각)

 

=> 오일러 변환은 짐벌락 현상 문제를 갖고 있다( 추후 따로 정리 예정 )

 

 

[노멀 벡터 변환]

폴리곤 메쉬 정점에 적용되는 변환 행렬을 M 이라 할 때,

M이 회전, 이동, 균등한 축소확대 중 하나거나 / 이들이 결합한 경우라면 노멀 변환에 사용 가능하겠지만

M이 비균등 축소확대를 포함하는 경우 M은 노멀 변환을 위해 사용 불가하다. 

-> 노멀은 M의 역행렬의 전치행렬 사용해 변환해야 함.

* 역행렬 : 두 정사각형 행렬 AB 곱해서 단위행렬 나올 때 B는 A의 역행렬.

* 전치행렬: A의 주 대각선 중심으로 대칭 위치에 존재하는 두 원소의 위치를 바꿔놓은 행렬.

(b)가 (M^-1)^T 이용한 제대로 된 노멀 변환. 변환 후에도 노멀은 삼각형과 수직관계 유지.

 

 


 

 

- 뷰 변환

뷰 변환: 월드 공간 좌표를 카메라 좌표계로 변환한다. = 카메라 변환

월드 변환 통해 모든 물체가 월드 공간에 모아지면

원하는 시점에서 월드 공간 관찰하기 위해 카메라 파라미터를 설정하고 카메라 공간을 정의.

월드 공간의 모든 물체는 카메라 공간으로 변환된다.

(카메라 공간에서 보다 효율적인 렌더링 알고리즘을 설계 구현할 수 있기 때문)

 

[카메라 공간]

카메라 공간의 기저 {u,v,n}. 카메라 파라미터 EYE,AT,UP을 사용해 계산.

  • EYE : 월드 공간에서 카메라 위치
  • AT : 월드 공간에서 카메라가 바라보는 기준점
  • UP : 카메라 상단이 가리키는 방향 대략적 묘사하는 벡터. 대부분 경우 UP은 월드 공간의 Y축으로 설정됨.

카메라 공간의 원점은 EYE. 원점과 기저 {u,v,n}으로 정의됨. 

=> 카메라 공간은 {EYE, u, v, n}으로 표기.

카메라 공간 기준으로 볼 때 카메라는 원점에 위치하고 -n 방향의 시선을 가짐. 

카메라 공간의 기저 {u,v.n}은 직교 정규 성질을 가짐.

* 직교 정규 기저 : 3차원 공간 기저를 구성하는 벡터가 모두 단위 벡터이고 서로 수직.

 

[뷰 행렬]

카메라 공간 {EYE,u,v,n}이 월드 공간 {O,e1,e2,e3}에 포개지려면 이동과 회전이 필요하다.

이 두변환이 결합된 것이 뷰변환. 

하지만 회전각을 계산할 필요는 없고 카메라 공간의 기저 벡터를 차례대로 행에 배치해 회전 행렬을 얻는다.

(단, 카메라 공간 기저가 직교 정규여야 한다는 조건)

 

- 회전각 계산할 필요 없는 이유 :

{u,v,n}이 직교 정규 기저이므로  

u · u = 1, u · v = 0, u  · n = 0 이 성립한다 (내적 -> a와 b가 수직이라면 a · b = 0)

마찬가지로 Rv= e2, Rn = e3가 되므로 R은 u,v,n을 회전시켜 각각 e1,e2,e3에 포개는 행렬임이 증명.

 

 

- 뷰 변환 행렬 : 이동 행렬과 회전행렬을 결합한 4X4 행렬

OpenGL 기준 뷰행렬.   · 은 내적

e.g.) Eye (20,3,0) 이라면 내적 공식에 의해서

*-Eyex = -Eye · u = -20*1 + -3*0 + 0*0 = -20


 

-투영 변환

투영 변환 : 카메라 공간의 모든 물체를 클리핑을 위한 클립 공간으로 변환.

피라미드 공간의 뷰 프러스텀 -> 좌표계의 기본 축에 나란한 2X2X1 크기의 직육면체 뷰 볼륨 클립 공간으로 변형.

 

[뷰 프러스텀]

뷰 볼륨 : 카메라의 가시 영역

뷰 프러스텀 : 뷰 볼륨을 절단한 유한한 크기의 뷰 볼륨

 

- 뷰 프러스텀 컬링

뷰 프러스텀 컬링 :  뷰 프러스텀 바깥에 놓인 물체를 미리 골라내어 GPU 파이프라인에 들어가지 못하게 하는 전처리.

=> 전체적인 렌더링 성능 높임.

뷰 프러스텀 컬링 알고리즘은 CPU에서 실행된다.

폴리곤 메쉬를 감싸는 바운딩볼륨이 뷰 프러스텀 바깥에 있다면 폴리곤 메쉬를 GPU 파이프라인으로 보내지 않음.

* 바운딩 볼륨: 미리 계산한 개별 폴리곤 메쉬를 감싸는 직육면체 혹은 구

=> 약간의 CPU 비용 지불로 GPU 비용 절감 효과

뷰 프러스텀 바깥의 폴리곤은 최종 화면에 나타나지 못함.

*fovy: 수직시야각 / aspect : 종횡비(가로세로 비율)

 

-> 그림의 주전자와 같이 폴리곤이 뷰 프러스텀과 교차한다면?

바깥의 폴리곤 잘라지고 프러스텀 안 쪽 부분만 GPU 파이프라인 다음 단계로 넘어감.

=> 클리핑 : 폴리곤을 자르는 작업

 

[클립 공간]

- 클립 공간 : 투영 변환에 의해 카메라 공간 -> 클립 공간으로 변환. 클립 공간에서 클리핑이 수행된다.

클립 공간은 왼손 좌표계 기준 정의되어 있다.

(래스터화 단계가 모든 물체가 왼손 좌표계 클립 공간에서 정의되어 있다는 가정으로 설계되어 있음.)

이 단면도는 투영 변환이 원근법을 구현함을 보여준다.

 

뷰 프러스텀은 원점에 위치한 카메라로 수렴하는 투영선의 집합. 원점은 COP(투영 중심).

뷰 프러스텀과 COP 사이면서 z축에 수직인 가상의 투평 평면(projection plane)을 생각해보면

투영선은 투영 평면에 영상을 형성.

하나의 투영선 상에 존재하는 모든 3차원 점은 투영 평면의 한 점에 맺힌다.

-> 3차원 공간에서는 l2가 l1 보다 길지만, 투영 평면에서는 동일한 길이 갖게됨

=> 멀리 있는 물체가 작게 보이게 됨 : 원근법

 

[투영 행렬]

뷰 프러스텀을 2X2X1크기의 직육면체 뷰볼륨으로 변형하는 투영 행렬

투영 행렬의 중요한 특징 중 하나는 아핀 변환을 위한 행렬과 달리 

마지막 행이 (0 0 0 1) 이 아니다.

그 결과, 정점 (x,y,z,1)이 투영변환 되면 그 w 좌표는 -z 가 된다. 

대개의 경우 이 값은 1이 아니다.

=> 추후 래스터화에서 원근감을 갖도록 w가 1이 되게 나눠주는 원근 나눗셈을 한다.

 

-> 래스터화 단계로 진입하기 위해 오른손 좌표계(카메라 공간)의 물체들을 왼손 좌표계(클립 공간)로 변환해야 한다.

(래스터화 단계가 모든 물체가 왼손 좌표계 클립 공간에서 정의되어 있다는 가정으로 설계되어 있음.)

오른손 카메라 공간에서 정의된 뷰 프러스텀을 왼손 클립 공간에서 정의된 2X2X1 크기 직육면체 뷰 볼륨으로 변환한다. xy범위는 변화가 없고 z범위만 [-1,0]에서 [0,1]로 바뀌었다.

z범위만 바뀌었으므로 z좌표에 영향을 미치는 행인 세 번째 행의 모든 원소의 부호를 바꿔주면

카메라 공간 정점을 왼손 클립 공간으로 옮기는 투영 행렬이 된다.

반응형