ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [컴퓨터 그래픽스] Rasterizer
    컴퓨터그래픽스 2024. 2. 16. 13:48

    6과에 OpenGl ES와 쉐이더에 관한 내용은 약간 프로그래밍 언어? 적인 느낌이라 일단 넘어가려고 한다. 이제까지 정리했던 vertex processing을 코드로 구현하는 내용인데 뒤에 꼭 정리할 것이다!!

    바쁜 일이 끝났으니 다시 달려보도록 하자.

    ​

    저번 글에선 vertex processing에 관한 내용을 다루었다. 다양한 변환들을 거친 결과물이 rasterizer로 넘어 와서 어떤 변화를 거치는지 설명하려고 한다!

    ​

    1. 클리핑

    우리가 rpg게임을 할 때 캐릭터를 움직이다 보면 처음에는 시야에 들어오지 않았던 물체들이 움직임에 따라 시야에 들어오게 되는 경험을 할 수 있다. 현실 세계에서 우리가 눈, 또는 카메라로 보는 화면은 이론상 무한대의 시야를 가지고 있다. 하지만 컴퓨터는 연산량의 한계가 있기 때문에 일정 범위를 넘어서 존재하는 물체까지 모두 표현하기엔 무리가 있다. 그래서 잘라낸다.

    책에서는 뷰 볼륨 대신 뷰 프러스텀으로 설명하고 있다. t1같은 경우는 뷰 프러스텀에서 벗어났기 때문에 그냥 배제된다. t2는 안정적으로 모든 부분이 뷰 프러스텀 내에 들어와 있기 때문에 잘린 부분이 없다. t3의 경우 일부분만 들어와 있는데, 그림과 같이 일정한 처리를 통해 새로운 정점을 만들어 일부분만 뷰 프러스텀 내로 들어오게 된다. 카메라 시야를 변경함과 동시에 계속 클리핑 처리를 해서 런타임에 업데이트 한다.

    ​

    ​

    2. 원근 나눗셈

    Mporj 행렬은 저번시간에 다뤘던 투영 행렬이고, 그 식을 카메라 공간의 한 점(x, y, z, 1)에 적용한 결과이다. (행렬의 차원을 맞추기 위해 마지막에 1이 추가된 것이다) 예전에도 강조하는 내용인데, 투영 행렬은 아핀 행렬이 아니다. 때문에 카메라 공간의 한 점에 투영 행렬을 적용한 결과에서 w 부분이 -z 인 것을 볼 수 있다. 이를 1로 만들기 위해 결과를 모두 -z로 나눠주게 되면 최종 식이 나오는데, 여기서 원근법이 구현된다.

    ​

    카메라로부터 멀리 떨어져 있는 정점은 투영 변환 행렬을 적용했을 때 w(-z)값이 크게 나온다. 그렇다면 최종적으로 w로 나눗셈을 진행할 때 멀리 있는 정점은 더 큰 값으로 나눠주게 되고, 결과 값을 작게 만든다. 즉, 멀리 덜어진 물체를 작게 만드는 것이다. 때문에 w로 나누는 나눗셈을 원근 나눗셈(perspective division)이라 한다. 원근 나눗셈까지 적용한 공간을 NDC라 한다

    ​

    ​

    3. 뒷면 제거

    우리가 달의 뒷면을 볼 수 없듯이 카메라도 불투명한 물체의 뒷면을 볼 수 없다. (반투명한 물체의 경우 나중에 빛에 대해 설명할 때 더 생각해보자)

    보이지 않는 물체의 뒷면까지 처리하는 것은 효율적이지 못하므로, 이를 제거하게 된다.

    각 폴리곤에서 뻗어있는 normal ( n1, n2. n3)과 카메라와 정점을 연결하는 벡터 ( c1. c2. c3)를 내적하면 그 값은 양수 또는 음수 또는 0이 된다.

    양수인 경우 보이는 부분, 음수인 경우 안보이는 부분, 0인 경우 polygon의 한 변만 보이는 경우다. 실은 내적보다 더 간단한 방법이 있는데, 이는 2차원으로 투영된 삼각형(polygon)의 정점 배열을 확인해서 이것이 시계 방향 정렬이면 뒷면, 반시계 방향 정렬이면 앞면으로 판단하는 것이다.

    ​

    물체가 겹쳐 있을 때는 앞면이라 해서 항상 보이는 것은 아니다. 당연히 카메라와 더 가까운 물체의 앞면이 보여야 할 것이다. 이는 z-버퍼링(후에 설명함)이라는 연산으로 처리할 수 있다. 또한 아까 설명했듯이 반투명한 물체의 경우 뒷면을 날려선 안된다. 때문에 이런 모든 경우들을 처리하는 알고리즘이 필요한데, 이는 레스터라이저 내부에서 하드웨어로 구현되어 있다.

    ​

    4. 뷰포트 변환

    왼쪽은 우리가 아는 2X2X2 NDC이다.(정확히 말하면 NDC로 표현된 뷰 볼륨) 이를 우리가 보는 스크린(스크린 공간)에 맞게 바꾸는 봐정을 뷰포트 변환이라 한다. 뷰포트는 뷰 볼륨 안의 내용이 최종적으로 그려질 스크린 공간을 말한다.

    ​

    스크린 공간은 얼핏 보면 2차원 처럼 보이지만 실은 z축까지 있는 3차원 공간이다. z값은 z-버퍼링 등 다양한 연산에 따로 이용된다.

    뷰포트 행렬은 다음과 같다. w와 h는 각각 뷰포트 너비와 높이 이다. 또한 왼쪽 식에서 minX와 minY를 각각 0으로 설정해주면 오른쪽과 같은 결과가 나온다. 보는 바와 같이, 이 행렬식은 아핀 행렬이다!

    ​

    5. 스캔 전환

    이제 저 삼각형 매쉬들을 스크린 공간으로 옮겼으면, 래스터라이저의 마지막 단계인 스캔 전환(Scan conversion)이 남았다. 스캔 전환에서 삼각형 내부를 채우는 프래그먼트(픽셀과는 살짝 다른 개념이다) 를 생성한다.

    그 사진은 정말 복잡해 보이는데 사실 계산은 되게 간단하다. (시험볼때는 ? 간단했다) 구현하려면 조금 까다로울순 있겠다. 기본적으로 삼각형의 변을 따라 선형 보간을 하는 방식이다. 근데 이 선형 보간이 한번으로 끝나진 않는다. 먼저 변을 따라 선형 보간이 되고, 보간된 변으로 내부를 선형보간 한다. 이를 겹선형 보간이라 한다.

    겹선형 보간 방식으로 R G B 값을 계산하면 프래그먼트별 색상을 얻을 수 있다.

    색상만 보간하면 끝인게 아니라, normal또한 보간해줘야 한다. 그래픽스는 참 공부하면 공부할수록 까다로운 분야다. 보간 원리는 색상 보간과 동일하다.

Designed by Tistory.