Ray Tracing이란?

레이트레이싱이란 넓은 범위에서,
원점(origin)과 방향(direction)을 가진 반직선(ray)을 장면에 대해 질의(query)하여
primitives의 교차(interesection) 여부를 검사하는 방법론이다.
실제 렌더링 과정에서는 각 픽셀에 대해 카메라에서 scene 방향으로 ray를 생성하고,
그 ray가 scene 안의 어떤 물체와 교차하는지 질의한다.
일반적으로 교차가 발생하면 해당 표면의 위치에 대해서 normal, material 정보를 통해 shading을 수행하고,
아무것도 맞지 않으면 background 또는 environment의 색상값을 사용한다.
Path Tracing vs Ray Tracing
여기서 헷갈리지 말아야 할 점은 ray tracing과 path tracing이 서로 동일한 의미를 뜻하지 않는다는 점이다.
Ray tracing은 기본적으로 넓은 범위로써 광선과 scene에 대한 교차 질의(query)를 수행하는 방법이다.
흔히 FPS,TPS에서의 총의 발사나 씬의 오브젝트를 마우스 클릭을 통해 선택할 때 사용하는 RayCast 또한
Ray Tracing의 일종이라고 볼 수 있다.
반면, path tracing은 ray tracing 질의를 반복적으로 사용해서 빛의 경로를 샘플링하고,
렌더링 방정식의 적분을 Monte Carlo 방식으로 근사하는 렌더링 알고리즘이다.

자세히 살펴본다면, Kajiya가 고안한 렌더링 방정식을 살펴보면 다음과 같은데,
빛의 input 에 대한 Li에 대해서 해당 source에 대해서
Path Tracing을 통해 입력받고 이를 적분한다.
Rasterizer에서는 Lighting Soruce에 대해 Directional Light, Spot Light, Point Light 등을 수동적으로 대입하여
렌더링을 수행했다면 Path Tracing은 카메라로부터 뻣어 나간 광선에 대해서 재귀적인 충돌 질의를 하고 해당 충돌 점에서
뻣어 나가는 광선에 대해 일부분에 대해서만 랜덤으로 샘플링 하여 몬테 카를로 적으로 방정식의 해를 구하는 것이다.
Raytracing은 기본적으로 카메라에서 ray를 쏘는 방식이다.

ray tracing의 의미를 생각하면 광원에서 빛이 뻗어나가고,
그 빛이 카메라에 들어오는 경로를 그대로 추적한다고 생각하기 쉽다.
하지만 일반적인 이미지 렌더링에서는 보통 반대로 계산한다.
광원에서 모든 방향으로 ray를 뿌리면, 그중 대부분은 카메라에 도달하지 않아 최종 이미지에 기여하지 않을 수 있다.
그래서 카메라의 각 픽셀에서 scene 방향으로 ray를 쏘고,
카메라에 실제로 보이는 정보만을 중심으로 계산하는 방식이 효율적이다.
기본 흐름은 다음과 같다.
Camera -> Pixel Dispatch -> Scene -> Surface Hit or Miss -> Sampling or Secondary Loop
다만, 모든 ray tracing 방식이 항상 카메라에서만 출발하는 것은 아니다.
light tracing이나 bidirectional path tracing처럼 광원에서 출발하는 방식도 존재한다.
Rasterization 렌더링과 Ray Tracing의 차이
Rasterization은 scene의 geometry를 screen space로 투영하고,
삼각형이 덮는 pixel 또는 fragment를 만들어 shading하는 방식이다.
Rasterizer방법은 일반적으로 real time rendering 분야에서 빠르고 효율적으로 Scene을 구성할 수 있기 때문에
현재까지도 게임 그래픽스에서 기본 default로 쓰이는 방식이며 지금까지 블로그에서 정리한 모든 Scene은
전부 Rasterizer를 통한 렌더링으로 장면들이 구성되었다.
Rasterizer의 한계는 Reflection이나 Global Illumination에서 두각된다.
Rasterization 자체는 빠르고 효율적이지만,
화면에 보이지 않는 정보나 scene 전체의 visibility를 직접 질의하기 어렵다.
그래서 reflection, GI, AO 같은 효과는 SSR, environment map, lightmap, probe,
PRT, SSAO, HBAO 같은 보조 기법을 통해 근사하는 경우가 많다.
해당 방식은 일종의 Trick을 통한 장면의 구성 방법이기 때문에 절차가 복잡하고 정보를 미리 저장해야 하기 때문에
텍스쳐 메모리 사용이 늘어나고 screen space 기반의 방법에서는 화면구성을 벗어나거나
bake의 경우 static이 아닌 장면 구성에서 명백한 한계점을 가지게 된다.
반면, Ray Tracing은 단순하게 화면의 각 픽셀에서 scene 방향으로
ray를 쏘고, 그 ray가 어떤 geometry와 교차(intersection)하는지 질의(query)한다.
따라서, rastserizer에서 장면을 구성하기 위해 여러 trick을 사용하는 것과는 달리 raytracing에서는
핵심 로직 자체가 직관적이고 아이디어가 단순하다.
실제로 컴퓨터 그래픽스에서 RayTracing을 통한 렌더링 방법은
비교적 최근 RTR분야에서 화제되고 있는 것과는 다르게 상당히 오래된 방법이다.
다만 ray tracing은 광선과 scene geometry 사이의 intersection test를 매우 많이 수행해야 하므로 계산 비용이 크다.
특히, 비실시간 렌더링의 영화 산업에서 사용되는 path tracing 기반의 offline rendering은
영상 한 프레임을 렌더링하는 데도 많은 시간과 렌더팜 자원이 필요하며
이 때문에 과거에는 실시간 게임 렌더링에 그대로 적용하기 어려웠다.
과거 Disney와 같은 3D 영화 산업 등에서 한 장면을 렌더링 하는데
회사 컴퓨터들이 몇번이나 정전되고 하였다는 일화는 유명한 만큼 하드웨어 제약이 크다.

최근 하드웨어에서는 NVIDA의 RTCore를 통해 acceleration structure인 BVH(Bounding Voluem Hierarchy)
을 순회하여 triangle ray intersection 검사에 특화된 프로세서가 발전되어가고 있는 만큼
실시간 환경에서 Ray Tracing을 사용할 수 있도록 많은 변화가 일어나고 있다.
Hybrid Rendering(Rasterizer + Raytracing)
Ray Tracing은 Rasterizer렌더링의 한계인
반사, 그림자, 굴절, ambient occlusion, global illumination 같은 효과를
비교적 간단한 철학과 알고리즘을 통해 자연스럽게 표현할 수 있다.
하지만 한 장면에서 많은 ray intersection과 secondary ray 계산을 요구하기 때문에 하드웨어적 비용이 크다.
그래서 최근의 실시간 렌더링에서는 모든 장면을 ray tracing만으로 처리하기보다는,
rasterization을 기본 렌더링 방식으로 사용하고,
일부 효과만을 ray tracing으로 보완하는 하이브리드 렌더링을 많이 사용한다.
예를 들어,
Rasterization에서는 기본적으로
geometry rendering, G-buffer, direct lighting 등을 통한 surface 표현을 한다면,
Ray tracing을 통해 해당 구성된 장면에 대해서
reflection, shadow, ambient occlusion, global illumination의 효과를 보조하게 된다.
즉 실시간 게임에서의 ray tracing은 rasterizer를 완전히 대체한다기보다는,
rasterization이 약한 부분을 보완하는 방식으로 사용되는 경우가 많다.
Acceleration Structure와 BVH(Bounding Volume Hierarchy)
Ray tracing에서 가장 큰 비용 중 하나는 ray가 scene의 어떤 geometry와 교차하는지 찾는 것이다.
만약 모든 ray가 scene 안의 모든 triangle을 검사한다면 비용이 너무 커진다.
따라서 ray tracing에서는 acceleration structure를 사용해 불필요한 intersection test를 줄인다.
대표적인 구조가 BVH, 즉 Bounding Volume Hierarchy이다.
BVH는 scene의 primitive들을 bounding box 계층 구조로 묶어두고,
ray가 어떤 bounding box와 교차하지 않으면 그 안의 geometry들은 검사하지 않는 방식으로 탐색 비용을 줄인다.
즉, 장면에 대한 모든 primitves에 대해서 선형적으로 검사하지 않기 위해 사용하는 자료구조로써 사용하게 된다.
처음에는 BVH가 완전 탐색 비용인 O(n)복잡도를 O(log n)으로 줄인다고 단순하게 생각하였는데,
엄밀하게는 scene 구조, BVH 구조의 품질, ray 방향, 각 bounding volume의 overlap된 정도에 따라 성능이 달라진다고 한다.

Ray Tracing의 Acceleration Strucure의 Intersection 검사에 대해서는 세부적으로
BLAS(Bottom Level Acceleration Structure)
TLAS(Top Level Acceleration Structure)
가 있다.
BLAS는 하나의 mesh 또는 geometry group 내부의 triangle, AABB primitives들을 가속하기 위한 구조이고,
TLAS는 scene에 배치된 instance들을 관리하는 상위 구조이다.
TLAS의 각 instance는 해당 mesh의 특정 BLAS를 참조하고,
transform, instance ID, 등의 정보를 가진다.
즉, 실질적으로 Scene의 Acceleration Strucure에서 검사하는 대상은 TLAS로써
Ray가 primitives에 intersection 했는지에 대한 검사를 가속화 하여 ray tracing의 성능을 향상시킨다.
Ray Tracing Pipline
필자는 RayTracing의 기본 베이스를 DXR(DirectX Raytracing)를 통해서 공부하므로
Vulkan API 등에서 사용하는 각 단계의 명칭과는 다를 수 있음을 먼저 인지하기를 바란다.
DXR은 DirectX 12 위에서 하드웨어 가속 ray tracing 구조를 사용할 수 있도록 추가된 API이다.
당연하게도 Windows 운영체제에서만 사용할 수 있으며
DXR를 사용 하기 위한 기능이 현재 사용하고 있는 GPU와 호환이 되어야 한다.
각 API와는 무관하게 Ray Tracing의 기본적인 shader 흐름은 다음과 같이 정리할 수 있다.

Ray Generation Shader
Ray Generation Shader는 DXR dispatch의 시작점이다.
dispatch란 보내다, 배치하다, 충돌시키다라는 뜻인데,
GPU에게 정해진 크기의 병렬 작업 묶음을 실행하라고 지시하는 명령이다.
Rasterizer 구조에서
DrawIndexed 함수가 verex shader에서 index buffer를 통해 삼각형 primitives를 그리라는 명령이라면
Raytracing에서
Dispatch의 의미는 각 Pixel에 대해서 해당 크기의 thread, grid 작업을 실행해라라는 명령이다.
앞서 언급하였듯이 RayTracing 구조는
카메라에서 각 픽셀들의 방향으로 광선을 생성하여 발사하여 질의를 처리하는 방식이기 때문에,
예를 들어 1920×1080 해상도라면 DispatchRays 명령을 통해
1920×1080×1 크기의 RayGen shader가 실행된다.
RayGen shader는 현재 pixel 위치를 기준으로 camera ray를 만들고,
광선에 대한 정보를 담고 있는 RayDesc 구조체와 Payload를 초기화한 뒤 TraceRay 함수를 호출한다.
RayGen의 역할은 다음과 같이 정리할 수 있다.
1. 현재 pixel dispatch grid의 위치 계산
2. 각 픽셀마다 camera ray 생성
3. 광선 정보를 담고 있는 RayDesc 구조체 생성
4. 광선 intersection query에 대한 결과 값인 Payload 초기화
5. TraceRay 함수 호출
6. intersectionPayload 결과를 Output Texture에 기록
TraceRay
TraceRay함수는 DXR에서 ray traversal을 시작하기 위한 HLSL 함수이다.
RayGen shader에서 TraceRay 함수를 호출하면,
DXR은 acceleration structure(TLAS, BLAS)를 기반으로 ray와 scene geometry의 intersection을 탐색한다.
DispatchRays는
각 필셀에서 RayGen shader들을 실행시키는 명령을 의미한다면
TraceRay 함수는
RayGen 안에서 실제 ray traversal을 시작하는 함수를 의미한다.
RayDesc
RayDesc는 ray의 기하학적인 정보를 담는 구조체이다.
주요 구성 요소는 다음과 같다.
Origin - ray의 시작 위치
Direction - ray의 방향
TMin - hit로 인정할 최소 거리
TMax - hit로 인정할 최대 거리
여기서 생소한 부분은 TMin과 TMax일 것인데,
TMin은 rasterizer에서 shadow map 처리시 마진을 준 것과 같은 원리로
광선에 대해서 self intersection과 shadow acne 등의 문제를 해결하기 위한 하한값을 설정한 것이라고 보면 된다.
TMax는 질의를 하기 위한 Ray의 종류에 따라서 상한선이 다르기 때문에 설정한 해당 범위 까지 질의를 수행하기 위한 장치라고 볼 수 있다.
예를 들어, 그림자 생성을 위한 ray tracing의 경우에는
오브젝트에 대해서 차폐가 되었을 시에 표면에서 광원까지의 거리로 제한할 수 있다.
각 오브젝트 표면의 머터리얼 색상을 계산하기 위한 primary ray에 대해서는 TMax를 큰값으로 설정하여 부딪힌 지점에서 오브젝트의 색상에 대해서 반환을 하거나 충돌하지 않았을 경우 background 색상을 반환할 수 있도록 처리한다.
Payload
Payload는 TraceRay 함수에 전달되는 사용자 정의 구조체이다.
RayGen shader가 payload를 초기화하고, TraceRay 과정에서 실행되는 Any hit, Closest hit, Miss shader가
해당 payload를 읽거나 수정한다.
TraceRay함수 실행이 끝나면 수정된 payload는 다시 호출자인 RayGen shader로 돌아온다.
예를 들어 다음과 같은 간단한 payload를 생각해 볼 수 있다.
struct Payload
{
float3 color;
bool hit;
};
즉, Payload는 각 DXR shader들 사이에서 결과를 전달하기 위한 데이터 집합이라고 볼 수 있다.
Any hit Shader
Any hit shader는 traversal 중 발견된 후보 intersection에 대해 호출될 수 있는 shader이다.
중요한 점은 Any hit이 최종 hit를 처리하는 shader가 아니라, 후보 hit를 필터링하는 shader라는 점이다.
대표적인 예시는 alpha test이다.
나뭇잎, 풀, 철망 같은 오브젝트는 실제로 quad mesh 일 수 있지만,
texture card의 alpha 값에 따라서 투명한 부분은 hit로 인정하면 안 된다.
따라서 Any hit shader는
hit 후보의 intersection에 대한 유효성 검사를 위한 필터처리 단계라고 볼 수 있다 .
shadow ray에서는 특정 불투명 물체를 만나는 순간 더 이상 탐색할 필요가 없으므로,
Any hit shader 단계에서 조기로 탐색을 종료하는 식의 처리 등을 할 수도 있다.
Closest hit Shader
Closest hit shader는 Any hit 등에 의해 reject되지 않은 유효 hit들 중
가장 가까운 hit에 대해 호출된다.
Closest hit shader의 주요 역할은 해당 표면의 shading 정보를 계산하고 payload에 기록하는 것이다.
예를 들면 다음과 같은 식이다.
struct Payload
{
float3 color;
bool hit;
};
Payload payload;
payload.color = materialColor;
payload.hit = true;
즉 Closest hit shader는
최종적으로 이 ray가 맞은 표면을 어떻게 보이게 할 것인가?
를 결정하는 shader라고 볼 수 있다.
Rasterizer의 fragment shader에서 각 materal의 색상 정보를 반환하는 단계와 유사한 단계라고 볼 수 있다.
Miss Shader
Miss shader는 RayDesc의 TMin ~ TMax 범위 안에서 유효한 hit를 찾지 못했을 때 호출된다.
주로 background, skybox, environment lighting 값을 payload에 기록한다.
예를 들어 다음과 같은 식이다.
struct Payload
{
float3 color;
bool hit;
};
Payload payload;
payload.color = skyColor;
payload.hit = false;
정리
이번 챕터에서 가장 중요하게 정리한 내용은 다음과 같다.
1. Ray tracing은 광선의 충돌(intersection) 질의(query) 기반 기술이다.
2. Path tracing은 ray tracing을 이용해 rendering equation의 light transport를 Monte Carlo 방식으로 추정하여
방정식의 해를 구하는 알고리즘이다.
3. 일반적인 이미지 렌더링에서는 카메라에서 ray를 시작하는 경우가 많다.
4. BVH는 모든 primitive를 선형 검사하지 않도록 돕는 acceleration structure이다.
5. RT Core는 BVH traversal과 ray triangle intersection test를 가속한다.
6. DispatchRays는 RayGen shader grid를 실행하는 명령이다.
7. RayGen은 RayDesc와 Payload를 만들고 TraceRay함수를 호출한다.
8. Any hit은 최종 hit shader가 아니라 후보 hit 필터이다.
9. Closest hit은 유효 hit중 가장 가까운 hit에 대해 호출된다.
10. Miss shader는 유효한 hit가 없을 때 background 값을 payload에 기록한다.
DXR에서 RayGen shader는 각 pixel 또는 sample에 대한 ray를 생성하고 TraceRay 함수를 호출한다.
TraceRay는 TLAS를 기반으로 acceleration structure traversal을 수행하며,
traversal 중 후보 hit에 대해 Any hit shader가 필터링을 수행할 수 있다.
유효한 hit가 존재하면 Closest hit shader가 호출되어 surface shading 결과를 payload에 기록하고,
유효한 hit가 없으면 Miss shader가 호출되어 background 값을 payload에 기록한다.
최종적으로 payload는 TraceRay의 호출자인 RayGen shader로 반환되어 output texture에 저장된다.
다음 공부할 부분
Ray Tracing에서의 기본적인 Pipline 흐름인
RayGen, TraceRay, Payload, Hit, Miss shader의 각 과정과 역할에 대해서는 어느 정도 정리되었다.
다음으로 공부할 부분은 Shader Table이다.
현재까지의 흐름에서는 TraceRay가 hit을 찾으면 Closest hit shader 또는 Any hit shader가 실행된다고 정리했다.
그런데 실제 scene에는 여러 object와 여러 material이 존재한다.
그렇다면 DXR은 ray가 어떤 object를 맞았을 때 어떤 Closest hit shader를 실행해야 하는지, 어떤 material data를 사용해야 하는지 어떻게 알 수 있을까?
이 연결을 담당하는 구조가 Shader Table이다.
다음 글에서는 다음 내용을 정리해볼 예정이다.
1. Shader Table이 왜 필요한가?
2. Hit Group이란 무엇인가?
3. Shader Record는 무엇을 담는가?
4. Shader Identifier와 DX의 Local Root Signature 는 어떤 역할을 하는가?
5. TLAS, BLAS Acceleration Structure와 Shader Table은 어떻게 연결되는가?
이번 글은 DXR의 ray가 생성되고, scene을 질의하고,
payload를 통해 결과가 돌아오는 흐름을 이해하는 데 초점을 맞췄다.
다음 단계에서는 해당 ray가 어떤 shader와 material로 연결되는가를 이해하기 위해
Shader Table로 넘어가면 될 것 같다.
어느정도 RayTracing과 PathTracing에 대한 기술적 특성이 파악이 되고,
Rendering Equation과의 상호 관계가 정리되면
실제 상용 게임 엔진에서 RayTracing이 어떤식으로 적용 될 수 있는지를 살펴볼 예정이다.
'Ray Tracing' 카테고리의 다른 글
| Ray Tracing(3-1) - Radiometry (0) | 2026.07.09 |
|---|---|
| Ray Tracing(2) - Shader Table, Root Signature, RTPSO (0) | 2026.06.20 |
| Before Studing Ray Tracing (0) | 2026.06.02 |