광선 추적(Ray Tracing)은 가상적인 광선이 물체의 표면에서 반사되어, 카메라를 거쳐 다시 돌아오는 경로를 계산하는 것이다.
위키피디아에선 광선 추적을 위와 같이 설명하고 있다.
아래는 디즈니 유튜브에서 가져온 광선 추적을 표현한 그림
광선 추적에 대해 알아보기 전에 간단하게 조명(lighting)에 대한 설명
게임 또는 컴퓨터 그래픽에서 현실 세계를 반영하기 위해 빼 놓을 수 없는 요소 중 하나가 조명(lighting)이다. 빛이라는 것은 크게 두 종류로 나뉜다. 태양이나 전구와 같은 광원이 방사하는 빛이 물체에 직접적으로 닿을 경우 이 빛을 직접광 혹은 직접 조명(Direct illumination)이라고 한다. 위의 그림을 예로 들면 4번 지점이 5번의 광원으로부터 받는 빛이 직접광이다.
그런데 빛은 어떤 물체에 닿으면 반사되거나 굴절된다. 만약 반사 또는 굴절된 빛이 다른 물체에 닿으면 그 물체가 받는 빛을 간접광 혹은 간접 조명(Indirect illumination)이라고 한다. 위의 예에선 3,2,1이 받는 빛이 간접광에 해당된다.
직접광은 광원과 물체와의 관계를 통해 간단하게 카메라에서 보는 물체의 색상을 결정할 수 있다.
하지만 간접광은 광원과의 직접적인 관계가 아니다. 그러므로 어디로부터 반사된 간접광인지 계산할 필요가 있다.
광선 추적 배경 및 개념
하지만 현실 세계에서 반사는 아래와 같이 무수히 많은 물체들과 충돌하기 때문에 현실을 표현하려면 그 계산량이 방대하다. 물론 아래 그림도 간소화된 것이다. 기본적으로 1개의 광선은 1개의 픽셀에 대응된다.
어찌됐든 우리는 픽셀의 색상을 결정하기 위해 이 픽셀이 받은 간접광이 어디로부터 온 것인지, 어떠한 물체들을 거쳤는지 알 필요가 있다. 이러한 것들이 중요한 이유는 빛이 물체에 닿을 때마다 물체의 재질, 색상 등을 고려하여 색상이 결정되고 이 색상은 다음 반사에 영향을 미치기 때문이다.
이를 조사하기 위해 역으로 카메라로부터 광선을 발사시킨다. (만약 광원으로부터 카메라까지 도달하는 빛을 조사한다면 비효율적일 것이다. 수많은 빛 중 카메라로 들어가는 빛만을 또 찾아내야 하기 때문에..)
카메라로부터 나가는 광선은 물체에 닿거나 계속 나아가 카메라 시야를 벗어날 것이다. 물체에 닿는다면 반사되거나 굴절될 것이다. 반사되거나 굴절되어 나가는 광선은 또 다른 물체에 닿거나 시야를 벗어난다.
이러한 동작을 재귀적으로 반복하여 결국은 광원에 도달하거나 시야에 벗어날 때까지 반복한다. 광원에 도달한다면 빛의 시작점을 찾은 것이므로 그 광원으로부터 다시 카메라로 들어오는 경로를 계산하여 픽셀의 색상을 결정한다. 이처럼 빛이 어디로부터 반사되어 오는지 역으로 경로를 계산하는 기법을 광선 추적(Ray tracing)이라 한다.
광선 추적의 원리를 그림으로 자세하게 표현하면 다음과 같다.
광선 추적 알고리즘
불투명한 노란색 구체와 반투명한 연두색 구체가 있고, 카메라와 물체들 사이에 투영 평면이 놓인다. 투영 평면은 물체들이 그려질 스크린 공간의 뷰포트의 해상도와 동일하다고 생각하자. 광선 추적을 위해 카메라에서 광선을 발사한다. 이 광선을 1차 광선이라고 하자. 이전에 말했듯이 카메라에서 발사되는 1개의 광선은 1개의 픽셀에 대응된다. 1차 광선이 범위 내의 어떤 물체와도 닿지 않을 경우 해당 픽셀로 들어오는 간접광은 없다고 판단한다. 이 경우 장면의 배경색으로 해당 픽셀 색상을 결정한다.
만약 위 그림과 같이 광선이 물체에 닿게 되면 그 지점(p1)이 그림자에 가려지는지 확인해야 한다. 이를 판별하기 위해 해당 지점에서 각 광원으로 또 다른 광선을 발사한다. 이 광선은 그림자 광선(shadow ray)이라 한다. 위에선 광원이 1개이므로 하나의 광원을 향해 그림자 광선(s1)을 발사한다. 만약 이 그림자 광선이 광원에 도달하면 그림자에 가려지지 않는 것이고, 다른 물체에 부딪히면 그림자에 가려지는 것이다. 만약 가려지지 않았다면 p1은 광원으로부터 직접광을 받는 것이므로 직접광 루틴대로 해당 지점의 픽셀 색상을 결정하면 된다. 위 그림에선 보라색 구에 부딪히므로 p1은 그림자에 가려진다고 판정된다.
이와 별개로 1차 광선이 닿은 p1 지점에서 반사(reflection) 광선과 굴절(refraction) 광선 또한 발사된다. 반사 광선은 p1의 노멀(n1)을 기준으로 입사각과 반사각이 동일하므로 쉽게 구할 수 있다. 따라서 반사 광선은 r1이 된다. 검산하듯이 역으로 생각해보면 이해하기 쉽고 당연한 과정이다.
굴절 광선은 부딪힌 물체가 불투명하지 않을 경우에만 발생된다. 1차 광선이 부딪힌 물체는 반투명하므로 굴절 광선이 발사된다. 굴절 광선은 마찬가지로 p1에서 시작하여 굴절되어 구를 통과해 나간다. 그 결과 p3에 부딪히게 된다.
여기서 알게 되는 것은 1차 광선이 생성한 r1과 t1 모두 (물체에 부딪힌다면) 1차 광선과 동일하게 또다른 그림자 광선, 반사 광선, 굴절 광선을 생성해낸다. 따라서 이러한 과정들은 각 광선들이 어떠한 물체에도 부딪히지 않고 범위를 벗어날 때까지 재귀적으로 반복된다.
위 과정이 끝나면 t1과 r1의 역으로 들어온 픽셀 색상을 계산할 수 있다. 이를 s1을 통해 계산한 픽셀 색상과 더하면 p1의 최종 픽셀 색상이 된다.
기존 실시간 광선 추적의 한계점 및 극복
이처럼 광선 추적의 알고리즘 자체는 엄청나게 복잡하진 않지만, 그 계산량이 매우 많아 실시간 렌더링 분야 보단 애니메이션과 같이 오프라인 렌더링을 이용하는 분야에서 주로 사용되었다. 기존에는 CUDA와 Compute Shader와 같은 GPGPU 기법을 통해 기술적으로 실시간 레이 트레이싱 구현이 가능'은' 했다고 한다. (GPGPU는 CPU를 가지고 하던 일반적인 계산을 병렬 처리에 특화된 GPU에서 수행하는 방식을 말함)
광선 추적의 주 병목 지점은 광선과 물체가 충돌하는 지점(intersection point)를 검출해 내는 교차 검사(intersection testing)이다. 여기엔 K-D tree, BVH(Bounding Volume Hierarchy)와 같은 자료 구조를 통한 공간 혹은 오브젝트 분할이 요구 되는데, 이러한 트리를 탐색(traversal) 하는 것을 SW로 수행하는 데엔 한계가 있다.
이를 위해 그래픽 카드 제조사인 NVIDIA에서 RTX라는 그래픽 카드를 출시한다. RTX 시리즈는 Ray Tracing의 병목 지점을 하드웨어로 구현하여 실시간 Ray Tracing이 실현되도록 하였다. 이 하드웨어를 제어할 수 있는 API가 DX12이다. DX12에 그 API가 구현되어 있다. 따라서 더 lower해졌다는 DX12를 배워야하는 이유가 생겼다..
RTX 시리즈엔 Ray Tracing의 일부를 담당하는 RT core 등이 있는데 여기부턴 다음 포스팅에..
woo-dev.tistory.com/243?category=915972
https://devblogs.microsoft.com/directx/wp-content/uploads/sites/42/2018/03/GDC_DXR_deck.pdf
'게임 공부 > Computer graphics' 카테고리의 다른 글
쿼터니언은 벡터로도 사용 가능 (0) | 2021.08.19 |
---|---|
광선 추적(Ray Tracing)은 무엇인가? - (2) (0) | 2021.04.27 |
조명(Lighting) 기초 (0) | 2021.03.12 |
5 - 출력 병합(Output merging) (0) | 2020.08.13 |
4 - 프래그먼트 처리(Fragment processing) (0) | 2020.08.10 |
댓글