본문 바로가기
그래픽스ㆍDirectX

렌더링 파이프라인 - 정점 조립과 정점 변환

by imagineer_jinny 2022. 5. 20.

유니티 셰이더&렌더링 에센스 E03 : 렌더링 파이프라인 (2/3) - 정점 조립과 버텍스 셰이더의 변환 행렬 - YouTube

 

렌더링 파이프라인 - 정점 조립

 

정점 조립

- 정점 버퍼의 요소들을 정점 구조체로 조립

 

우리가 쉽게 인식할 수 없는 스트림 형태의 데이터를 우리가 쉽게 이해할 수 있는 정점 구조체 단위로 조립

정점 조립과정을 거치게 되면 삼각형에 대한 정점들에 대한 버텍스 버퍼 데이터들이 세개의 정점으로 구성되고 

이 세개의 정점은 버텍스 셰이더에 대해 각각 병렬로 처리되어서 또 다른 형태의 정점으로 표현됨

 

 

정점 조립 단계를 거치고 버텍스 셰이더 단계로 진입

 

렌더링 파이프라인 - 버텍스 셰이더

- 정점을 입력받아 다른 형태의 정점으로 변환

- 3D 공간 상의 정점의 위치를 클립 공간으로 옮기는 것 = 투영

 

즉 정점의 위치를 절대적인 world에서의 위치에서 카메라 화면을 통해 바라봤을때의 기준의 위치로 옮겨주는 것

 

 

가장 먼저 각 정점들은 모델 행렬에 의해서 변환이 이루어짐

모델 행렬의 변환을 거치기 전의 정점들은 오브젝트(모델) 공간에 존재하게 됨

 

 

오브젝트(모델) 공간

- 스스로가 세상의 중심

- 3D 모델의 피벗이 원점

- 모든 정점의 위치는 피벗에서 얼마나 떨어져있냐로 결정됨

원숭이 얼굴 모델의 원점은 그 오브젝트, 이 모델의 피벗 포인트임

그리고 각 정점의 위치는 실제 세상에서 원숭이 얼굴 모델이 어디에 배치되어있는지는 신경쓰지 않고 

이 3D 모델의 피벗 포인트에서 얼만큼 떨어져있냐로 위치가 결정됨

 

그런데 이 오브젝트 공간에 위치한 정점들에 모델 행렬을 곱해주면 월드 공간을 기준으로 배치된 정점들로 변환됨

 

모델 행렬

오브젝트의 정점들을 월드 상의 위치로 옮김

 

모델 행렬을 곱해준 다음에 뷰 행렬을 곱해줘야 함

 

뷰 행렬

월드 상의 정점들이 카메라의 상대적인 위치로 옮김

 

즉 카메라가 원점에 있다고 가정을 하고 모든 것들의 위치를 재편성하게 되는데 

이렇게 카메라가 원점에 있다고 가정한 공간을 카메라 공간이라고 함

 

카메라 공간

카메라의 위치와 방향이 세상의 중심

 

이런게 필요한 이유?

같은 위치에 있는 물건도, 카메라의 위치에 따라 다르게 보임

매번 카메라의 위치와 회전을 고려하는 것보다, 카메라는 원점(0,0,0)에 두고 오브젝트를 상대적으로 배치하는게 간결

 

 

 

 

투영 행렬은 카메라의 위치를 기준으로 한 정점을 카메라 시야 기준(화면 기준)의 정점으로 바꿔줌

 

투영 행렬

카메라 좌표계의 정점을 카메라의 시야를 기준으로 한 정점으로 옮김

카메라 좌표계의 정점들을 클립 공간으로 옮김

깊이와 원근감을 표현할 수 있게함

 

 

클립 공간

카메라가 보는 영역

카메라 공간: 카메라 위치를 원점으로 삼은 공간 -> 시야와 원근감이 없음

클립 공간: 카메라의 시점을 반영한 공간 -> 시야와 원근감이 존재

 

카메라가 보는 영역(뷰포트)을 직육면체(or 큐브)로 압축한 공간

X,Y의 범위: (-1 ~ 1)

Z의 범위: (0 ~ 1)

 

클립핑: 클립 공간 외부의 폴리곤은 NDC로 변환되는 과정에서 잘려나감

 

정규화된 기기 좌표계 (NDC)

  • 공간의 모든 x,y,z 범위가 (-1~+1 또는 0~1로) 정규화된 좌표계
  • 다음 절차를 통해 생성
    • 클립 공간 외부의 좌표를 잘라냄
    • 동차좌표계(4차원)을 "w 나누기"를 실행하여 3차원으로 변환

 

클립 공간과 NDC는 종종 하나로 묶여 설명

사실상 서로 같은 모습: 둘다 뷰포트를 (2 x 2 x 1) 직육면체로 쪼그라뜨린 공간

하지만 클립 공간은 계산 편의를 위해 4차원(동차 좌표계)에 존재

NDC는 (클립핑 실행후) 원래 의도된 3차원 공간으로 변환된 것

 

 

쉬운 설명을 위해 클립 공간과 NDC를 같은 것으로 설명

 

투영행렬이 하는 일은 카메라가 보고 있는 영역인 뷰포트를 직육면체의 클립 공간으로 바꿔주는 것

이 과정에서 카메라가 렌더할 영역이 결정되고 원근감이 생기게 됨

 

 

 

 

뷰포트란, frustum이라는 이름으로 부르기도 하는데

기본적으로 카메라가 가지고 있는 시야, 카메라가 그리게 될 영역을 지정하게 됨

 

world상의 모든 오브젝트를 그리게 되면 성능을 너무 많이 낭비하게 되기 때문에

카메라의 뷰포트는 near clip과 far clip으로 구성되게 되는데 

near clip은 near clip보다 더 카메라에 가까이에 있는 폴리곤들을 잘라내게 되는 단면이고

far clip은 far clip보다 더 멀리있는 폴리곤들을 잘라내게 된 단면

 

그리고 near clip과 far clip으로 구성된 도형이 피라미드의 머리 부분에 잘라낸 도형과 같다고 해서 frustum이라고 부름

원근감이 존재할 경우에는 이렇게 flustum 도형을 띄게 되는데

 

원근감이 존재하지 않는 직교 카메라인 경우에는 뷰포트가 직육면체를 띄게 된다

 

어느쪽이든 카메라는 카메라가 보게 되는 시야의 뷰포트를 가지게 되는데 

이런 뷰포트의 영역을 투영 행렬을 통해서 x, y의 길이가 2고 z 길이가 1인 직육면체로 정규화를 할 수가 있음

즉 카메라가 보는 모든 영역이 아래의 클립 공간으로 찌그러뜨려진다고 생각하면 됨

 

 

 

x의 -1은 화면의 최 좌측, x의 +1은 화면의 최 우측

y의 -1은 화면의 최 하단, y의 +1은 화면의 최 상단

 

z 값은 카메라에서 떨어진 정도이자 화면 상의 깊이

 

이때 카메라 공간 상에서 뷰포트 밖에 있는 오브젝트, 정점들이 있을 것임

 

정규화를 할 때 정규화 과정에서 뷰포트가 직육면체로 찌그러뜨려질 때

당연히 공간 전체에 있던 오브젝트들이 영향을 받을 테니까 

뷰포트 외부에 있던 오브젝트들도 형태가 변형이 될 것임

 

하지만 이와는 별개로 변형 전과 변형 후에도 뷰포트 외부에 있던 오브젝트는 

투영행렬이 적용된 이후에도 여전히 뷰포트가 정규화되어서 만들어진 직육면체 외부에 존재할 것임

그래서 이것만 감지해서 다 짤라낼 수 있음

 

기본적으로 소실점이 존재하는 perspective뷰 카메라에서는 뷰포트가 frustum 도형으로 생겼고 

이 도형에서 near clip은 작고 far clip은 크다

이렇게 생긴 frustum 도형을 직육면체로 찌그러뜨리게 되면 near clip의 가까운 단면들은 덜 찌그러듦

반대로 far clip에 있는 단면들은 상대적으로 많이 찌그러듦

즉 far clip에 가까운 화상들은 상대적으로 더 많이 찌그러들기 때문에 멀리 있는 물체는 작게보이고 가까이 있는 물체는 크게 보이는 것

 

* 정리 * 

버텍스 셰이더는 행렬 변환을 통해서 3D 공간 상의 정점을 클립 공간의 정점으로 옮기게 되는데

그 변환 과정을 풀어 설명하면 

모델 행렬을 곱해서 오브젝트 공간에서 월드 공간으로 점들을 옮기고 

뷰 행렬을 곱해서 월드 공간에서 카메라 공간으로 옮기고

투영 행렬을 곱해서 카메라 공간에서 클립 공간으로 점들을 옮겨서 변환된 정점을 다음 단계에 넘겨줌

 

 

오브젝트 공간

 

 

모델행렬 곱한 후 월드 공간

 

뷰 행렬로 변환

 

 

투영 행렬 변환 

 

 

댓글