이 시리즈는 “계산한 빛을 어디에 저장할까?”라는 질문으로 시작했다. UV texel, voxel, probe, surfel을 살펴봤고, 6편에서는 계산 결과를 얼마나 오래 믿어도 되는지까지 확장했다.
이제 각 기법을 외우는 대신 공통 질문으로 비교할 수 있다. 저장 위치, 저장 내용, 조회 방식, 갱신 정책을 분리해서 보면 새로운 GI 기술의 역할도 더 명확해진다.
글 제목의 “GI는 캐시 문제다”는 물리적인 정의가 아니라 이 시리즈의 설계 관점이다. GI의 본질은 빛 전달(light transport)이며, 모든 알고리즘이 조명 cache를 쓰는 것은 아니다. 다만 제한된 시간 안에서 그 결과를 공유하려면 cache의 설계가 품질과 비용을 크게 좌우한다.
질문 1: 어디에 저장하는가?
먼저 조명 샘플의 영역과 주소를 찾는다.
surface sample
+-- UV / texel address
+-- position + normal / surfel
spatial sample
+-- cell / voxel
+-- point / probe
screen sample
+-- pixel + history mapping
여기에 실제 저장 구조는 텍스처(texture), 격자(grid), 희소 구조(sparse structure), 해시 테이블(hash table) 등으로 달라질 수 있다. Surfel은 무엇을 대표하는 샘플인지, hash table은 그 샘플을 어떻게 주소화하는지를 설명하는 말이다. 같은 분류 단계가 아니다.
또 3D texture에 저장되어 있다고 꼭 voxel GI는 아니다. Probe 데이터를 3D texture로 배열할 수도 있다. 내부 자료구조의 형태보다 샘플이 대표하는 물리적 의미를 먼저 확인해야 한다.
질문 2: 무엇을 저장하는가?
대표적인 두 양을 다시 보자.
RGB 하나라도 의미는 다르다. 고정된 표면 법선(normal)의 복사조도(irradiance)일 수 있고, 특정 방향으로 나오는 방사휘도(radiance)일 수도 있다. 여기에 알베도(albedo)가 이미 포함되어 있는지, 발광(emission)이나 직접광(direct lighting)을 포함하는지도 확인해야 한다.
가시성(visibility) 데이터도 저장 내용이다. 거리나 깊이 모멘트(depth moment)는 조명값 자체는 아니지만, 그 값을 다른 위치에서 읽어도 되는지 결정한다. 캐시의 메모리 비용을 비교할 때 조명 RGB만 계산하면 이 부분을 놓친다.
질문 3: 어떻게 조회(query)하고 재구성(reconstruction)하는가?
Cache가 있다고 정확한 값이 바로 나오는 것은 아니다. 현재 표면과 관련된 샘플을 찾아서 재구성(reconstruction)해야 한다.
| 조회 | 중요한 관계 |
|---|---|
| Lightmap texture lookup | UV 대응, texel density, chart 경계 |
| Voxel traversal / cone tracing | 공간 해상도(spatial resolution), 계층 필터링(hierarchical filtering), 불투명도(opacity) |
| Probe interpolation | 위치, 법선 방향, 가시성 |
| Surfel filtering | 대표 반지름, 표면 방향, 가시성 |
| History reprojection | 이전 화면의 같은 표면인지 여부 |
필터를 넓히면 noise나 빈 영역을 줄일 수 있지만 조명 detail도 섞인다. 실제 geometry가 분리한 영역을 필터가 연결하면 빛 누출(light leaking)이 생긴다. Cache가 얼마나 정확하게 계산되었는지만큼 누가 그 값을 읽도록 허용하는가도 중요하다.
질문 4: 언제 갱신(update)하고 언제 무효화(invalidation)하는가?
Lightmap이나 probe 같은 이름만으로 정적·동적 여부가 결정되지는 않는다. Baked probe도 있고 ray-traced probe도 있다. Texture-space 조명도 실행 중에 갱신할 수 있다.
따라서 저장 표현과 별도로 다음을 확인한다.
- 조명은 bake하는가, 실행 중 계산하는가?
- 모든 샘플을 매 프레임 갱신하는가, 일부만 갱신하는가?
- 이전 값을 어떻게 누적하고 변화에 어떻게 반응하는가?
- 샘플의 identity가 바뀌거나 budget이 부족하면 무엇을 버리는가?
평균적인 장면의 품질과 초기 상태(cold start)의 품질도 다를 수 있다. 한 곳에 오래 서 있을 때의 수렴 화면만 보면 이동 중 새 영역의 노이즈(noise)와 반응 지연(lag)을 놓치기 쉽다.
지금까지의 기법을 같은 표에 놓으면
아래는 대표적인 구성의 비교다. 모든 구현의 고정된 정의는 아니다.
| 구성 | 저장 영역 | 저장 내용의 예 | 조회 | 수명·갱신의 예 |
|---|---|---|---|---|
| Baked lightmap | 표면의 UV texel | Irradiance, 방향성 조명 | 텍스처 filtering | Bake된 상태를 장기간 유지 |
| Voxel cone tracing | 계층적 공간 셀 | Opacity, 반사 radiance | Cone에 따른 계층 탐색 | Geometry와 조명 변경 시 갱신 |
| Baked light probe | 공간의 측정점 | SH 계수 등 | 공간 보간(spatial interpolation)과 법선 평가 | 정적 조명을 런타임에 재사용 |
| DDGI probe | 공간의 측정점 | 방향별 irradiance와 거리 moment | 가시성 기반 보간 | 광선 추적(ray tracing)과 시간 누적(temporal accumulation) |
| GIBS surfel | 표면의 대표 영역 | Irradiance와 지역 깊이 정보 등 | 표면·가시성 필터 | Persistent cache, 적응적 갱신 |
| Screen-space GI history | 화면의 표면 표본 | 간접광 추정치 등 | Reprojection과 filter | History 검사와 갱신 |
| Radiance cache | 구현마다 다름 | 특정 위치·방향의 빛 추정 | Cache query / 함수 평가 | 구현에 따른 재측정·누적 |
각 방법의 세부는 앞선 글에서 다룬 voxel cone tracing, DDGI, GIBS 자료를 참고할 수 있다. 이 표에서 성능 순위를 읽기보다는, 같은 결과를 서로 다른 표현과 갱신 정책으로 근사한다는 점을 보면 된다.
Radiance Cache는 다음 세대의 저장 위치일까?
Texel, voxel, probe, surfel 다음에 radiance cache를 나란히 적으면 새 자료구조처럼 보인다. 하지만 앞의 용어와 분류 기준이 다르다.
Radiance cache는 주로 저장하거나 근사하는 빛의 양을 가리킨다. Probe가 radiance를 저장할 수도 있고, 표면의 샘플이나 공간 hash가 radiance cache의 일부가 될 수도 있다. 반대로 같은 자료구조에 irradiance를 저장할 수도 있다.
따라서 이것은 다음과 같은 발전 순서가 아니다.
Lightmap --> Voxel --> Probe --> Surfel --> Radiance cache
더 정확하게는 선택 축을 조합한다.
domain : surface / volume / screen
quantity : irradiance / radiance / directional coefficients
representation : texture / sample set / hierarchy / learned function
lifetime : baked / frame-local / persistent
시리즈 첫머리에서의 “어디에”라는 질문에 “무엇을”과 “어떻게 표현하는가”를 더해야 하는 이유다.
광선 경로(light path)의 남은 계산을 캐시로 대신할 수 있다
Radiance cache의 용도를 이해하기 위해 경로 추적(path tracing) 중간에서의 조회를 생각해보자.
camera --> surface x0 --> surface x1 --> surface x2 --> ... --> light
|
+-- x1 이후의 빛을 cache로 근사
모든 표본에서 긴 path를 끝까지 계산하는 대신, 어떤 지점에서 남은 빛 전달을 cache 값으로 근사할 수 있다. 예를 들어 출사 radiance를 표현하는 단순한 모델은 다음과 같다.
실제 query에는 법선, 재질 파라미터 등이 더 필요할 수 있다. 입사 radiance를 저장하는 시스템이라면 query와 BRDF 적용 순서도 달라진다. 따라서 “radiance를 캐싱한다”는 설명만으로 정확한 수식과 사용 위치를 알 수는 없다.
Cache를 이용해 path를 조기에 끝내면 비용과 noise를 줄일 수 있지만, cache 근사로 인한 편향(bias)이 들어간다. 이를 별도의 보정 없이 반복 평균한다고 항상 정확한 경로 추적(path tracing) 해로 수렴하는 것은 아니다.
Radiance는 방향 의존성(direction dependence)이 강할 수 있다. 매끈한 반사의 좁은 하이라이트를 거친 공간·방향 해상도로 재사용하면 다른 표면이나 다른 시점에 맞지 않을 수 있다. 어떤 재질과 어느 bounce에서 cache를 사용할지도 설계의 일부다.
신경망 방사휘도 캐시(Neural Radiance Cache): 조명값 대신 함수의 파라미터를 유지한다
명시적인 샘플 배열 대신 신경망(neural network)으로 빛의 함수를 근사할 수도 있다. 개념적으로는 다음과 같다.
명시적 cache는 위치 주변의 값을 찾아 보간한다. 신경망 표현에서는 입력을 평가해 값을 얻고, 조명 정보를 모델 파라미터 $\theta$에 담는다. 입력의 구성과 예측 대상은 구현에 따라 달라지므로 위 식은 일반적인 설명 모델이다.
Müller 등의 Real-time Neural Radiance Caching for Path Tracing은 렌더링 도중 온라인 학습(online training)으로 cache를 적응시키는 접근을 제시한다. 모든 동적 장면(dynamic scene)을 사전 학습하는 대신 현재 장면의 표본으로 갱신한다는 점이 핵심이다.

두 장면의 path tracing, ReSTIR 추가, NRC 추가, 기준 영상 비교. 확대 영역에서는 NRC가 남은 빛 전달을 근사해 노이즈를 줄이는 효과를 볼 수 있다. 이미지의 성능 수치는 논문의 해당 실험 조건에 대한 결과다.
explicit cache learned cache
주소 --> 저장된 샘플 --> 보간 입력 --> f_theta --> radiance 추정
^ ^
| |
새 ray 표본으로 갱신 새 표본으로 online training
여기서도 이전 글의 질문은 그대로 남는다. 모델이 밝은 영역을 충분히 관측했는지, 바뀐 조명에 얼마나 빨리 적응하는지, 표현 해상도와 학습이 어떤 detail을 놓치는지 확인해야 한다. 값 배열을 함수로 바꾼다고 관측과 freshness의 문제가 자동으로 사라지지는 않는다.
비용을 볼 때는 갱신과 조회를 함께 본다
Light caching을 쓰는 단순한 비용 모델을 세워보자.
갱신하는 샘플 수와 샘플당 ray 비용, 현재 화면에서의 조회 수와 필터 비용, 배치·검색 구조·재활용 등의 관리 비용을 나눠 생각한 것이다. 실제 GPU에서는 병렬성(parallelism)과 메모리 접근(memory access), pass 간 의존성도 중요하지만 비교의 출발점으로 쓸 수 있다.
샘플을 줄이면 update 비용은 내려갈 수 있다. 대신 재구성(reconstruction)이 복잡해지거나 detail이 사라질 수 있다. 캐시를 오래 유지하면 재계산은 줄지만 변화에 대한 lag가 늘 수 있다. 조회에 큰 이웃 집합을 사용하면 ray를 절약한 효과 일부가 query 비용으로 옮겨갈 수도 있다.
따라서 “한 픽셀당 ray 수가 줄었다”만으로 전체 성능을 판단하기 어렵다. 새 영역의 초기화와 빠른 장면 변화까지 포함한 비용을 봐야 한다.
새로운 논문을 읽을 때의 순서
새 GI 시스템을 만났다면 다음 순서로 메모해보자.
- 대상 빛 전달: Diffuse인가 specular인가? 직접광·발광·몇 번의 bounce를 포함하는가?
- 샘플 영역과 주소: 표면, 공간, 화면 중 어디에 놓이고 어떻게 찾는가?
- 저장량과 표현: Radiance, irradiance, 방향 계수, 가시성 중 무엇을 유지하는가?
- 조회와 재구성: 어떤 이웃을 섞고, geometry가 분리한 영역을 어떻게 구분하는가?
- 갱신과 수명: 초기화, temporal reuse, invalidation, 재활용을 어떻게 처리하는가?
- 오차와 비용: 어떤 detail을 포기하며, cold start와 빠른 변화에서 무엇이 보이는가?
예를 들어 “표면의 irradiance를 ray로 갱신하고, 가까운 샘플을 가시성에 따라 섞으며, 이전 결과를 유지한다”는 설명을 읽으면 이름을 몰라도 surfel 계열의 설계와 연결해볼 수 있다. 공간의 방향별 조명과 거리 통계를 유지한다면 probe 계열의 질문을 적용할 수 있다.
빛을 저장하는 위치에서 재사용의 조건까지
Lightmap은 UV로 주소를 붙이고, probe는 공간의 대표 위치에서 측정하며, surfel은 표면 영역을 직접 대표한다. Voxel은 공간의 셀과 계층을 이용하고, radiance cache는 더 일반적인 빛의 함수를 근사할 수 있다.
이 표현들을 하나의 정답으로 줄일 필요는 없다. 장면의 규모, 동적 변화, 필요한 detail, 하드웨어 예산에 따라 조합이 달라진다.
이 시리즈를 관통하는 질문은 다음과 같다.
한 번 계산한 빛을 다른 위치나 다음 프레임에서도 사용하려면, 무엇이 같아야 하고 무엇이 달라지면 다시 계산해야 할까?
저장 위치는 공유할 이웃을 정한다. 저장 내용은 보존할 방향 정보를 정한다. 조회 방식은 어떤 근사를 허용할지 정하고, 갱신 정책은 얼마나 오래된 결과를 믿을지 정한다. 이 네 선택을 함께 보면, 낯선 GI 기법도 빛의 계산과 재사용을 연결하는 설계로 읽을 수 있다.
References
- Cyril Crassin et al., Interactive Indirect Illumination Using Voxel Cone Tracing, 2011.
- Zander Majercik et al., Dynamic Diffuse Global Illumination with Ray-Traced Irradiance Fields, JCGT, 2019.
- EA SEED, SIGGRAPH 21: Global Illumination Based on Surfels, 2021.
- Thomas Müller et al., Real-time Neural Radiance Caching for Path Tracing, ACM Transactions on Graphics, 2021. Online training을 이용한 radiance cache.