레이 트레이싱 구현기 2-3. 광선과 좌표계

Plato·2023년 6월 4일
0

서론

시리즈의 이전 글에서 3차원 실공간을 2차원 평면인 캔버스에 맵핑하는 방법을 다뤘다. 이번 글에서는, 캔버스에 맵핑된 점과 카메라를 지나는 광선을 카메라 로컬 좌표계에서 생성하고 이를 글로벌 좌표계로 변환하는 과정을 다룰 것이다.

본론

카메라 로컬 좌표계

저번 글에서 계산을 단순화하기 위해서 캔버스를 카메라의 z축으로부터 1만큼 떨어지게 위치시켰고 (0,0)이 캔버스의 중앙을 나타내도록 만들었다. 그렇다는 것은, 캔버스의 좌표 (x, y)를 (x, y, 1)로 표현하면 그대로 카메라의 로컬 좌표계에서의 캔버스 좌표가 됨을 알 수 있다.

광선 생성

선은 선 위의 점과 방향으로 표현할 수 있다. 광선은 시작점과 방향을 가져야하기 때문에 선 위의 임의의 점이 아닌 시작점과 방향으로 표현할 것이다.
P=O+tR\vec{P} = O + t\vec{R} 여기에서 O\vec{O}는 시작점 그리고 R\vec{R}은 방향을 나타낸다. O\vec{O}는 시작점이기 때문에 카메라의 위치(0, 0, 0)가 되고 R\vec{R}은 캔버스에 맵핑된 점의 좌표랑 구성 성분이 동일할 것이다. 위에서 말했듯이 광선은 카메라와 캔버스의 점을 지날 것이기 때문이다. R\vec{R}은 방향을 나타내는 벡터이기 때문에, 길이로 나누어서 단위 벡터로 만들어줄 것이다.

로컬 좌표계 -> 글로벌 좌표계

우리가 렌더링할 3차원 대상은 글로벌 좌표계에서 표현된다. 하지만 위에서 생성한 광선은 로컬 좌표계에서의 광선이기 때문에 이를 글로벌 좌표계에서의 광선으로 바꿔줄 필요가 있다. 선형 변환을 좌표계의 변환으로 표현할 수 있고 카메라에서 글로벌 좌표계로의 변환은 선형적이기 때문에 행렬로 쉽게 표현될 것이다. 언뜻 보면 단순히 벡터인 광선을 적절한 행렬로 곱하면 글로벌 좌표계로 변환할 수 있을 것 같지만 실상은 그렇지 않다. 실제로 해당 방법으로 계산을 해보면 기대한 결과와 다른 결과를 얻는다는 것을 쉽게 확인할 수 있다. 우리의 광선은 방향 벡터를 포함하고 있는데, 직관적으로 생각했을 때 방향 벡터는 이동 변환에 영향을 받으면 안된다. 하지만 카메라 행렬은 이동 변환을 포함하고 있기 때문에 방향 벡터가 이동 변환에 영향을 받게되는 것이다. 원인이 명확하고 단순하기 때문에 이를 해결하는 방법도 쉽게 떠올릴 수 있다. 필자가 생각하기에 제일 직관적인 방법은, 방향 벡터위를 지나는 두 점을 찾고 이를 행렬 변환한 새로운 두 점을 잇는 방향 벡터를 만드는 것이다. 물론 방향 벡터이기 때문에 크기로 나누어서 단위 벡터로 만들어준다.

마무리

픽셀을 렌더링하기 위해 픽셀을 캔버스에 맵핑하여 얻어낸 점과 카메라를 지나는 광선을 생성하고 이를 글로벌 좌표계의 광선으로 변환하는 방법에 대해 알아봤다. 다음 글에서는 렌더링의 두 가지 큰 토픽인 visibility와 shading에 대해 알아보자.

0개의 댓글