본문 바로가기
개발 (Game)/Unity

[Shader] Rendering PipeLine - 버텍스 셰이더

by 진현개발일기 2021. 9. 1.

[2021. 09. 01, Wed]

 

  ■ 버텍스 셰이더
       - 정점을 입력받아 다른 형태의 정점으로 변환해주는 단계이다.
       
       - 주요 역할
         : 3D 공간 상의 정점의 위치를 절대적인 월드의 위치에서 카메라 화면을 통해 바라보았을 때의 기준의 위치(즉, 클립 공간)로 옮겨주는 것이다. 
           (이는 정점을 어떠한 공간에서 다른 공간으로 '투영' 해준다는 얘기이다)
            쉽게 예를 들면 '그림자 연극'을 떠올리면 된다 -> 3D 사물들이 빛에 의한 투영으로 하나의 2D 스크린 공간에 그림자가 모이게 되는 것.
         
       - 정점을 위치로 옮기기 위해서 '변환 행렬'을 사용한다.
       
       * 변환 행렬의 구조
       [오브젝트 공간] -모델 행렬-> [월드 공간] -뷰 행렬-> [카메라 공간] -투영 행렬-> [클립 공간]

       모델 행렬 : 모델 공간에 위치한 오브젝트들의 정점들을 월드 상의 위치로 옮겨줌.

       뷰 행렬 : 월드 상의 정점들을 카메라의 상대적인 위치로 옮겨줌.
       (뷰 행렬이 필요한 이유는 같은 위치에 있는 물건도 카메라의 위치에 따라 다르게 보이기 때문)

       투영 행렬 : 카메라의 위치로 기준으로 된 정점을 카메라의 '시야'의 기준의 정점으로 바꿔준다.
       (투영 행렬은 카메라 좌표계의 정점들을 클립 공간으로 옮김 여기서 깊이와 원근감을 표현 해준다.)


 위 과정으로 버텍스 셰이더에서 정점 3개를 클립 공간의 정점 3개로 변환을 한 다음에 Rendering Pipeline의 세 번째 단계인 래스터라이저에 넘겨준다.

    (+카메라의 시야를 뷰포트라고 말하는데 이는 Near Clip Plane, Far Clip Plane으로 구성된 Frustum 도형을 영역으로 한다.) 

 

Clipping Planes를 보면 Near Clip과 Far Clip이 있다.

 

원근 투영(Perspective) -> 직교 투영(Orthographic)
NearClip과 FarClip의 카메라와의 거리(?)를 조절할 수 있다. 


 ====================
        * 카메라 공간
         : 카메라 위치를 원점으로 삼은 공간 (시야와 원근감이 없음)
       
     ■클립 공간
         - 카메라가 보는 영역 (시야와 원근감이 존재)
          (카메라가 보는 영역(Viewport)을 직육면체(or 큐브)로 압축한 공간이다.)
         - X, Y의 범위 : (-1 ~ 1)
         - Z의 범위 : (0 ~ 1)
       
         클립 공간 외부의 폴리곤은 NDC로 변환되는 과정에서 잘려나간다.

     ■ NDC (정규화된 기기 좌표계)
       - 공간의 모든 x, y, z 범위가 (-1 ~ +1 또는 0 ~ 1)로 정규화(normalized)된 좌표계
       
       * 순서
         1. 클립 공간 외부의 좌표를 잘라냄
         2. 동차좌표계(4차원)을 "w 나누기"를 실행하여 3차원으로 변환 <- 이건 솔직히 뭔소린지 모르겠음. 나중에 지식이 더 쌓이면 그때 공부해보자
            * 동차좌표계 : 3차원의 공간과 좌표를 다루지만 4차원을 빌려서 계산하는 방식

 NDC는 클립 공간에서 클립핑이 한 번 실행되고 4차원에서 3차원으로 w나누기 연산을 실행해서 변환된 것이라고 생각하자 

     ■ NDC와 클립 공간은 종종 하나로 묶여 설명이된다. 
         - 둘다 뷰포트를 (2x2x1) 직육면체로 쪼끄라뜨린 공간이다. (공통점)
         (차이점) 1. 하지만 클립 공간은 계산 편의를 위해 4차원(동차 좌표계)에 존재한다.
                    2. NDC는 (클립핑 실행 후) 원래 의도된 3차원 공간으로 변환된 것이다.

     * 원근감이 생기는 이유
       : Frustum도형을 정규화하는 과정에 직육면체로 찌뿌러 뜨릴 때 
         Near Clip 단면 쪽은 덜 축소하고 
         Far Clip 단면 쪽은 더 많이 축소 시키기 때문이다. 

         (Near Clip이 제일 작은 단면이니 정규화(-1 ~ +1)할때 축소할 값이 매우 작다 반면에 Far Clip은 -1~+1로 도달할려면
         상대적으로 Near Clip보다 더 많이 축소시켜야한다.) 

 

▼ 영상 15:28초 참고

https://www.youtube.com/watch?v=aYTJY_DneSY&list=RDCMUCRWq4MPqifkmT2GyL2d2ZAQ&index=1

 

지금은 어려우니깐 사실상 클립 공간와 NDC는 같은 모습을 띄우고 있기 때문에 같은 것이라고 생각을 하자. 
========================  


요약 : 
     [정점 조립] 단계에서는 CPU에서 전달 받은 데이터 버퍼(정점의 위치, 컬러)들을 하나의 구조체 단위로 묶어주고
     [버텍스 셰이더] 에서는 정점 조립 단계를 거친 정점 묶음을 클립 공간의 정점으로 변환을 해준다

728x90