Skip to content

Latest commit

 

History

History
120 lines (87 loc) · 6.5 KB

mandatory_README.md

File metadata and controls

120 lines (87 loc) · 6.5 KB

MiniRT

  • mandatory 파트만 수행
  • 폴리곤 메쉬 사용
  • 행렬 사용
  • 퐁 조명 모델 사용

메인 로직 (Main Logic)

  1. scene 파싱 작업 및 초기화, 전처리 작업
  2. scene의 정보를 사용해 픽셀 하나 단위로 image를 렌더링
  3. window에 지금까지 완성된 image를 put

렌더링이 전부 완료되기 전까지 2,3의 과정을 반복한다.

  • 레이 트레이싱(Ray tracing) 방식을 사용하므로 단 하나의 이미지를 렌더링하는데도 시간이 오래 걸릴 수 있다. 전부 다 렌더링되기 이전에도 window에 image를 지속적으로 put하여 현황을 확인하게끔 하고 싶으므로 loop_hookrender_to_window 함수를 등록하여 반복 실행한다.

  • 본격적인 렌더링 작업에 들어가기 이전, 매 픽셀의 계산(렌더링)에서 반복되는 연산에 대해 전처리(preprocess) 하고 이를 저장해둠으로써 불필요하게 동일한 연산이 반복해서 실행되는 일을 막도록 한다.

  • 이미지를 윈도우에 put하는 작업은 상당한 시간이 소요되므로, put 작업의 간격(interval)을 두고 그만큼 진행이 되었을 때마다 put하도록 한다.

렌더링 (Rendering)

가상의 3차원 공간을 2차원 디스플레이에 출력하기 위해, 크게 두 가지 작업이 필요하다.

  • 가시성(visibility) 판단
  • 음영(shading)

카메라 레이와 오브젝트 간의 교차(intersection) 검사를 통해 가시성 판단이 이루어지며, 카메라로부터 가장 가까운 교차 지점에 대해 phong 조명 모델을 기반으로 shading 작업을 수행한다.

카메라 레이 방향 벡터를 보다 효율적으로 구하기 위해, 전처리 작업에서 미리 구해둔 image plane의 모서리(corner)의 네 점의 world space 좌표를 선형 보간(linear interpolate)하여 현재 구하고 싶은 픽셀의 world space 좌표를 구하고 이에 카메라의 좌표를 빼서 구한다.

Visibility (가시성)

intersection check (교차 검사)

한 오브젝트를 이루는 삼각형 폴리곤의 배열을 돌면서 교차 검사를 수행한다.

레이-폴리곤(삼각형) 교차 검사:

  1. 삼각형의 평면과 레이가 교차하는지 확인한다
  2. 만약 그렇다면, 그 교차지점이 삼각형 내부에 있는지 확인한다
  • 평면: (p-p0) * n = 0
  • 레이: l0 + l * t = p

두 식을 연립하면, t = (p0 - l0) * n / (n * l)

n과 l의 방향이 다를 때(n * l < 0), 즉 레이와 평면의

  • n과 l의 방향이 같을 시(n * l > 0), 즉 레이가 평면의 뒷면과 교차하는 경우 false
  • n과 l이 평행할 시(n * l = 0), 즉 평면과 직선이 수직할시 false

MVP matrix

  • Model matrix : 로컬 공간 -> 월드 공간 매핑
    T, R, S 세 개의 행렬을 compose하면 된다.

  • View matrix : 월드 공간 -> 뷰 공간 매핑
    뷰 공간은 카메라의 세 개의 방향벡터가 이루는 공간이므로, 이미 알고있는 카메라 방향벡터를 그대로 행벡터로 삼으면 된다. 세 개의 축이 직교하는 유클리드 공간끼리의 매핑이므로 간단하게 기저벡터의 전환으로 생각할 수 있다.
    (right - x축, up - y축, forward - z축)
    뷰 공간으로 매핑하기 위해서는 먼저 중심을 카메라 기준으로 옮기고(이동변환), 그 다음 회전변환을 하면 된다. 뷰 행렬 = (회전 변환 행렬) * (이동 변환 행렬)

  • Projection matrix
    : 뷰 공간 -> 클립 공간 매핑

TRS matrix

  • Translate matrix
  • Rotate matrix : 유니티와 동일하게 z, x, y 순서로 적용 (roll-pitch-yaw)
  • Scale matrix

Shading (음영)

phong 조명 모델을 사용한다.

  • Color = Ambient(환경광) + Diffuse(난반사) + Specular(정반사)
    (오브젝트의 재질에 따라 난반사와 정반사 항의 비율을 조정, 그 합은 1)

각 항별 파라미터

  • ambient: 배경색상 (지역조명 모델이므로 매우 간단)
  • diffuse: 빛의 입사벡터, 교차지점 노말벡터
  • specular: 빛의 반사벡터, 시선벡터

교차지점의 노말을 어떻게 설정하냐에 따라 shading의 결과를 Flat 혹은 Smooth하게 만들 수 있다.

  • 폴리곤의 법선벡터(face normal) 사용 -> Flat shading
  • Barycentric(무게중심) 좌표를 사용해 폴리곤을 이루는 세 점의 정점 노말들을 보간(interpolate)하여 얻어낸 노말 사용 -> Smooth shading

이를 사용자가 세팅할 수 있도록 SMOOTH_SHADING 환경변수를 마련해두었다. (디폴트 값: 1)

전처리 (Preprocess)

Object

오브젝트에 저장되어있는 변환 정보(이동, 회전, 스케일) 및 모델링 원형(메쉬)를 토대로 정점, 정점 노말, 삼각형 배열을 미리 구해 채워넣는다.

Camera

레이 트레이싱에서 카메라의 파라미터들은 결국 카메라 레이 방향벡터를 구하는데 쓰인다. 카메라 레이 방향 벡터는 현재 색상을 구하려는 픽셀의 월드 공간 기준 좌표에서 카메라 좌표를 빼서 구하는데, 월드 공간 기준 좌표를 구하기 위해 매 픽셀마다 PV의 역행렬을 구하는 건 비효율적이므로 보다 효율적인 실행을 위해 전처리 작업으로서 image plane의 모서리(corner)의 네 점의 world space 기준 좌표를 미리 구해두고 후에 이를 보간하여 사용한다.

pixel_to_world_space

그래픽스 파이프라인의 좌표계 매핑 과정 world -> view -> clip -> NDC -> screen 을 반대로 이행함으로써 screen 공간 상의 좌표를 world 공간 기준으로 매핑한다.

<screen 공간 상의 좌표를 world 공간으로 매핑하기>

  1. NDC 공간 좌표로 변환 (=[-1,1] 범위로 매핑)
  2. clip 공간 좌표로 변환 (=전체 성분에 depth 알맞게 반영)
  3. world 공간 좌표로 변환 (=투영 행렬(P) 및 카메라 행렬(V)의 역행렬 적용)

이때, 2차원 평면에서 3차원 공간으로의 매핑이기에 임의의 depth를 설정해야한다. 편의상 near plane 기준 좌표를 구하도록 한다. (ndc.z = -1, clip.w = NEAR, view.z = NEAR)

스크린 공간 -> NDC 공간 변환

: 원점이 좌측 상단이고 x, y의 범위가 각각 [0, width), [0, height)인 2차원 평면 상의 좌표를 원점이 좌측 하단이고 x, y, z의 범위가 [-1, 1]인 3차원 정육면체 공간으로 매핑한다.

클립 공간 -> 월드 공간 변환

: 투영 행렬(P) 및 카메라 행렬(V)의 역행렬을 적용하고, 전체 성분을 w로 나눠준다. (동차좌표계에서 3D좌표로 해석될 수 있도록 w=1로 만들어주어야하기 때문)