[게임 수학] 뷰 행렬, 원근 투영 행렬 (View Matrix, Projection Matrix)

구교승·2025년 6월 5일

[게임 수학]

목록 보기
9/9

View Matrix (뷰 행렬)

카메라와 좌표계

  • 월드 좌표계와 카메라 좌표계는 서로 반대 방향
  • 서로 반대되는 좌표계로 인해 x와 y값이 반대로 뒤집힘
  • 원래 좌표계를 사용하고 싶다면 카메라를 180도 회전시켜 +z축이 카메라 뒤편을 향하도록 설정
  • 카메라는 크기 변환이 없으므로 이동(Translation)과 회전(Rotation)만 고려

뷰 행렬 변환

  • 카메라 좌표를 t(t1, t2, t3)로 가정
  • 이동 행렬 T와 회전 행렬 R은 아래와 같음
  • 회전 행렬 R은 직교행렬이므로 회전행렬 R의 전치는 역행렬과 동일
  • 이동 행렬 T도 마찬가지로 전치를 통해 역행렬 계산
  • 위의 두 행렬을 곱한 최종 뷰 행렬 변환

뷰 행렬의 계산 순서

  • 기존 변환과 반대로 이동의 역행렬 적용 후 회전의 역행렬 적용
  • 모든 좌표는 카메라 중심으로 이동한 후 회전되어야 함
  • 최종적으로 3D 장면을 2D 평면에 표현

Perspective Projection Transformation (원근 투영 변환)

최종적으로 2차원 평면에서 3차원 공간감을 느낄 수 있도록 변환
원근 투영 변환 : 눈이 세상을 보는 방식으로 공간 변환

투시 원근법과 시야각

  • 투시 원근법 : 모든 점이 한 소실점을 향해 수렴하는 방식
  • 3차원 공간에 투시 원근법을 적용하기 위해 공간의 모든 점이 한 점을 향해 모이는 형태로 변환
  • 화각 (Field of View) : 원근 투영 변환을 설계하기 위해 시야 범위 설정
  • 카메라에 화각 생성시, 상하좌우가 균등한 사각뿔 영역 생성
  • 원근 투영 변환 : 뷰 공간을 카메라의 한 점으로 모이는 사각뿔 형태를 가진 공간으로 변환하는 작업

투영 평면과 초점 거리

  • 투영 평면 : 물체의 상이 맺히는 가상의 평면
  • 투영 평면의 크기는 카메라와 멀어질수록 더 커짐
  • 초점 거리 (Focal Length) : 카메라에서 투영 평면까지의 거리
  • 화각 : theta, 초점 거리 : d
  • 원근 투영을 계산하기 위해 투영 평면의 위치를 먼저 지정해야 함
  • 일반적으로 계산의 편의를 위해 위, 아래 크기가 1이 되는 지점으로 결정
  • 상하좌우의 화각이 동일하므로 투영 평면은 [-1, 1]의 범위를 갖는 정사각형
  • NDC (Normalized Device Coordinate)
    • 2차원 투영 평면의 좌표 시스템
    • 화면에 출력되기 직전 단계의 좌표계
    • 위에서 설명한 [-1, 1]의 범위로 정규화된 3차원 공간
    • 클립 좌표 단계에서 투영 변환을 거친 후 동차 좌표를 w값으로 나누어 생성

NDC와 투영 평면의 관계

  • 투영 평면에 대응하는 NDC가 일정한 값을 가져야 한다면 카메라의 화각이 변할때 초점 거리 또한 달라짐
  • 화각이 커질수록 초점 거리는 가까워짐
  • 화각과 초점 거리의 관계는 tan함수로 설정
  • tan함수로 초점 거리를 구한 후, 뷰 공간의 점을 투영 평면 위의 점으로 대응시키는 원근 투영 변환 설계

투영 변환의 기하학적 해석

  • 유클리드 공간 : 3차원 공간에서 세 축이 직교하는 공간 (로컬, 월드, 카메라 공간)
  • 정육면체의 유클리드 공간은 원근 투영 변환에 따라 사각뿔 형태로 전환 (사영 공간, Projection Space)
  • 사영 공간의 x,y축은 여전히 직교, z축은 x축과 y축에 모두 영향
  • 초점 거리에 따라 x축과 y축이 만들어내는 투영 평면의 면적이 달라지는 이유
  • 비례식을 통한 투영 좌표 유도
    • 유클리드 공간이 사영 공간으로 변환되며 축이 직교하는 체계가 달라지기 때문에 표준 기저 벡터의 변화를 관찰하는 방법으로는 생성 불가
    • x축을 배제한 y축과 z축으로 공간 설정, 삼각형의 닮은 꼴 성질로부터 비례식 생성
    • 위의 비례식으로 아래의 식 성립
    • x축과 y축은 서로 같은 시야각, 서로 직교하므로 x축도 동일
    • 투영된 최종 좌표
    • 좌표를 계산했다면 모니터의 최종 화면 구성, NDC 좌표를 화면 해상도만큼 가로와 세로를 늘려줌
    • 대부분의 경우 최종 화면이 1:1 비율이 아닌 가로가 더 긴 비율 사용 => 물체가 찌그러짐
    • 이를 방지하기 위해 종횡비(가로 세로의 비율)를 미리 파악해 NDC 영역에서 미리 찌그러트린 후에 펼침

Aspect Ratio (종횡비)

  • 좌우로 찌그러트리려면 x축 값 변경, 종횡비의 역수를 곱하면 가능 (1/a)
  • 최종 NDC 값을 계산하는 원근 투영 행렬
  • 원근 투영 행렬을 사용할때 변환할 점의 z값이 행렬에 사용되기 때문에 변환할 점마다 항상 새롭게 계산해야 함
    • 모든 변환의 행렬을 미리 곱해둔 행렬을 적용해 반복되는 연산량 감소의 이점 사라짐
    • 따라서 원근 투영 행렬을 구성할 때 점의 값을 사용하지 않고 카메라 설정만으로 행렬 제작
  • 위의 투영 행렬의 구성 요소는 모두 -v(z)값을 분모로 가지므로 행렬에서 값 제거 후 결과값에 -v(z)를 나누어줌
  • 최적화를 적용한 NDC 값을 만드는 과정
    • 행렬 곱에서 생성된 벡터는 최종 NDC 좌표와는 다르지만 원근 투영 행렬 P점과 무관하게 카메라 설정 값으로만 구성
    • 클립 좌표 : 원근 투영 행렬 P로 변환되는 좌표계
    • 클립 좌표 점 P의 요소를 P의 세번째 값인 -v(z)값으로 나눔

Depth vs Distance (깊이 vs 거리)

깊이값과 거리

  • 원근 투영에서는 한 점(x,y,z)이 Near Clipping Plane 위의 점(x',y',z')으로 투영
  • 3차원 공간상에 있는 물체에 의해 (x',y',z') 위치에 있는 픽셀의 색 결정
  • 픽셀의 깊이 값 : z-near
  • 카메라와 물체 사이의 거리 : sqrt(x^2 + y^2 + z^2), 카메라의 좌표가 (0,0,0)일 경우
  • 깊이로부터 거리 계산 가능

깊이값 (행렬 유도)

  • 3차원 공간에서 다수의 물체를 그릴 때에는 어떤 물체가 앞에 있는지 확인하기 위해 그리는 순서 고려
  • 물체가 카메라로부터 얼마나 떨어져 있는지에 대한 정보 기록
  • 앞에 있는 물체를 나중에 그리도록 설정
  • 카메라에 부여한 시야각은 깊이값과 무관하기 때문에 카메라에 추가 속성 부여 (근평면, 원평면)
  • 근평면 (Near Plane), 원평면 (Far Plane)
  • 절두체 : 카메라 시야를 구성하는 사영 공간을 근평면과 원평면으로 잘라준 형태
  • NDC 깊이값은 멀어질수록 증가, NDC 공간은 왼손 좌표계
  • DirectX에서는 0~1 사용
  • 기존 행렬에서 쓸모 없던 한 행을 사용해 깊이 값까지 구할 수 있는 최종 행렬 도출
  • 깊이 값을 활용하는 3행은 4개의 미지수 i, j, k, l
    • 깊이 값은 뷰 좌표계의 x축과 y축에 각각 직교하므로 영향 없음
    • 따라서 i, j = 0
    • k와 l을 구하기 위해서는 2개의 샘플 데이터 필요
    • 카메라로부터 근평면까지의 거리 n, 원평면까지의 거리 f로 가정
    • 근평면의 점을 p1, 원평면의 점을 p2라고 할때 다음과 같이 계산
    • 클립 좌표의 네번째 요소로 모든 요소를 나눈 값은 NDC 좌표, NDC 좌표의 z값은 각각 -1, 1
    • 따라서 근평면의 클립 좌표는 (0, 0, -n, n), 원평면의 클립 좌표는 (0, 0, f, f)
    • 이로부터 연립 방정식 도출 가능
      • kn + l = -1
      • kf + l = f
    • 최종 투영 행렬

참고 및 출처:
게임 개발을 위한 수학

profile
Face the fear, Build the future

1개의 댓글

comment-user-thumbnail
2025년 6월 5일

oh.

답글 달기