5편의 GIBS는 surfel을 여러 프레임 동안 유지하고, 새 ray 표본으로 조명을 갱신했다. 한 프레임에 충분한 표본을 모두 계산하지 않고 시간을 이용하는 방식이다.
이전 프레임의 빛은 현재 상태를 여전히 잘 나타낼 때 재사용할 수 있다. 문제는 그 조건이 항상 성립하지 않는다는 것이다. 광원이 꺼지거나 문이 열리면 저장된 조명은 즉시 오래된 정보가 된다. 캐시가 오래 살수록 이 판단이 중요해진다.
캐시의 유지(persistence)와 시간 누적(temporal accumulation)은 다르다
프레임 간 유지되는 캐시(persistent cache)와 시간 누적(temporal accumulation)은 함께 등장하지만 같은 개념은 아니다.
Persistent cache
같은 표면 샘플의 identity와 저장소를 여러 프레임 유지한다.
Temporal accumulation
이전 조명 추정치와 새 표본을 결합한다.
같은 surfel 저장소를 계속 쓰면서 조명값은 매 프레임 새로 덮어쓸 수 있다. 반대로 화면의 이력 버퍼(history buffer)를 재투영(reprojection)해서 누적하면, surfel 없이도 시간 재사용(temporal reuse)이 가능하다.
첫 번째 질문은 어떤 샘플이 같은 샘플인가이고, 두 번째 질문은 그 샘플의 이전 값에 얼마나 의존할 것인가다.
EMA는 노이즈(noise)와 반응 속도(responsiveness)를 맞바꾼다
현재 프레임의 복사조도(irradiance) 추정치를 $\widehat E_t$, 누적 결과를 $\overline E_t$라 하자. 지수 이동 평균(Exponential Moving Average, EMA)은 다음과 같다.
이 글에서 $\alpha$는 새 값의 비중이다. 구현에서 history 비중을 히스테리시스(hysteresis)로 표시하면 그 값은 $1-\alpha$에 대응하므로, 변수 이름만 보고 크기를 비교하면 안 된다.
alpha가 작음: 이전 결과의 비중이 큼 --> 안정적, 변화에 느림
alpha가 큼: 새 표본의 비중이 큼 --> 빠른 반응, noise가 잘 보임
빛이 변하지 않고 표본(sample)이 충분히 독립적이라면 누적은 분산(variance)을 낮추는 데 도움이 된다. 하지만 새 표본이 이미 이전 cache를 참조하거나, 같은 방향을 반복해서 사용하면 독립성이 약해진다. 프레임을 100개 누적했다고 독립적인 ray 100개와 동일한 품질을 얻는 것은 아니다.
불을 껐는데 왜 벽이 한동안 밝을까?
설명용으로 어떤 표면의 실제 irradiance가 1.0에서 0.2로 순간적으로 바뀌었다고 하자. 매 프레임 새 표본은 정확히 0.2를 반환하고, $\alpha=0.1$로 누적한다고 가정한다.
| 변화 후 프레임 수 $k$ | 누적 irradiance |
|---|---|
| 0 | 1.000 |
| 1 | 0.920 |
| 10 | 약 0.479 |
| 30 | 약 0.234 |
새 표본은 정확해도 이전 값이 남아 화면이 서서히 어두워진다. Noise가 없어도 생기는 시간 지연(temporal lag)이다.
이전 값의 영향이 처음의 5% 이하가 되려면 다음 조건이 필요하다.
$\alpha=0.1$이면 약 29프레임, 60 fps에서 약 0.48초다. $\alpha=0.02$이면 약 149프레임, 약 2.48초다. 이는 고정된 EMA의 산술 예이며, 실제 GI의 수렴 시간 측정이 아니다. 여러 bounce의 전달 지연까지 있으면 반응은 더 복잡해진다.
프레임 수보다 시간을 기준으로 정할 수도 있다
같은 혼합 계수(blend factor)라도 30 fps와 120 fps에서는 초 단위 반응이 다르다. 목표 시간 상수(time constant) $\tau$와 프레임 간격 $\Delta t$를 사용하면 다음처럼 새 값의 비중을 정할 수 있다.
단, 실제로 캐시가 갱신된 간격을 사용해야 한다. 어떤 surfel을 몇 프레임 건너뛰어 갱신하는데 렌더링 프레임 간격만 넣으면 같은 시간 응답을 유지하지 못한다.
화면 공간 이력(screen-space history)은 같은 표면을 다시 찾아야 한다
화면의 픽셀 좌표는 표면 식별자(surface identity)가 아니다. 카메라가 움직이면 같은 픽셀에 다른 물체가 나타날 수 있다.
frame t-1 frame t
pixel (u,v) --> 벽 pixel (u,v) --> 캐릭터
같은 좌표의 history를 그대로 읽으면 다른 표면의 빛이 섞인다.
그래서 모션 벡터(motion vector)나 이전 변환(transform)을 이용해 현재 표면이 이전 화면의 어디에 있었는지 찾는다. 이것이 재투영(reprojection)이다. 이어서 깊이(depth), 법선(normal), 객체 식별자(object identity) 등의 일치 여부를 확인해 history를 거부하거나 비중을 줄인다.
가려져 있던 벽이 새로 나타나는 가림 해제(disocclusion)에서는 대응하는 이전 픽셀이 없을 수 있다. 이때 오래된 다른 표면의 값을 가져오면 잔상(ghosting)이 생긴다.
SVGF는 시간 누적과 휘도 분산(luminance variance)을 이용한 화면 공간 필터(screen-space filter)를 결합하는 대표적인 사례다. 원 논문 소개에서 적은 path 표본을 시간과 공간에 걸쳐 재구성하는 목표를 확인할 수 있다.

SVGF의 입력(1 path/pixel), 재구성 결과, 기준 영상 비교. 시간 누적과 공간 필터를 함께 사용해 적은 표본의 노이즈를 줄인다. 오른쪽 확대 영역에서 세부 형태가 얼마나 남는지 비교할 수 있다.
월드 공간 캐시(world-space cache)도 조명의 유효성을 확인해야 한다
월드 공간 캐시(world-space cache)는 카메라가 바뀌어도 같은 벽의 저장소를 찾기 쉽다. 하지만 저장소를 찾았다는 사실과 조명이 맞는다는 사실은 다르다.
| 변화 | 캐시에서 확인할 것 |
|---|---|
| 카메라만 이동 | 기존 표면 조명은 유효할 수 있지만 새로 보이는 영역의 coverage가 필요함 |
| 광원 밝기·방향 변경 | 영향받는 표면의 기존 조명을 더 빨리 갱신해야 함 |
| 문이 열림·geometry 파괴 | 가시성 정보와 주변 조명이 함께 달라질 수 있음 |
| 물체 이동·변형 | 샘플 위치·법선을 추적하고 새 환경의 조명을 계산해야 함 |
| 재질·발광 변경 | 해당 표면에서 나오는 빛과 다른 표면의 간접광이 달라질 수 있음 |
특히 간접광(indirect lighting)의 영향은 바뀐 물체에서 끝나지 않는다. 빨간 벽의 albedo를 파란색으로 바꾸면 다른 바닥의 색 번짐(color bleeding)도 달라진다. 문은 자기 표면뿐 아니라 방 안으로 들어오는 경로까지 바꾼다.
따라서 캐시 무효화(invalidation)를 단순히 “움직인 물체의 cache를 지운다”로 끝내기 어렵다. 변화 감지, 영역별 변경 표시(dirty flag), 주기적인 재측정 등으로 영향을 확인해야 한다.
버릴지, 덜 믿을지, 더 계산할지
이전 결과의 신뢰도를 낮추는 방법은 여러 가지다.
| 처리 | 적합한 상황 | 비용과 한계 |
|---|---|---|
| History reset | 다른 표면으로 바뀌거나 identity가 끊긴 경우 | 빠르게 과거 값을 버리지만 noise와 cold start가 커짐 |
| Blend factor 증가 | 같은 표면의 조명이 바뀐 경우 | 반응이 빨라지지만 새 표본의 noise가 드러남 |
| History clamping | 주변 범위와 크게 어긋나는 history | Ghosting을 줄일 수 있지만 실제 밝은 값을 잘라낼 수 있음 |
| Ray budget 증가 | 새 샘플이나 변화가 큰 영역 | 새 값의 품질이 좋아지지만 계산량이 증가함 |
서로 배타적인 선택은 아니다. 같은 표면의 조명이 바뀌었다면 storage는 유지하고 blend factor와 표본 수를 함께 늘릴 수 있다. 다른 표면의 샘플로 재활용했다면 identity와 history를 새로 초기화해야 한다.
다음은 그런 정책을 설명하는 의사코드다. 실제 GIBS 코드는 아니다.
if sample identity changed:
reset lighting and visibility history
request initialization samples
else:
compare recent estimates with long-term history
adjust the weight of new estimates
request more samples where change or noise is large
allocate requests within the global budget
retain some measurements for detecting later changes
GIBS의 2021 발표는 장기 평균과 단기 평균·분산을 이용한 adaptive integration, 그리고 variance 등에 따른 ray 배분을 설명한다. 실제 구현 설명은 발표 PDF의 74–79쪽을 참고할 수 있다.
변화 감지를 멈추면 캐시가 잠들어버린다
안정된 표면에 적은 ray를 배분하는 것은 합리적이다. 하지만 완전히 측정을 멈추면, 문이 열리거나 광원이 바뀐 것을 알아차릴 방법도 사라질 수 있다.
안정된 값 --> 갱신 중단 --> 환경 변화 --> 감지 실패 --> 오래된 값 유지
따라서 광선 기반 변화 감지(ray-based change detection)를 사용하는 시스템은 일정한 재측정 기회를 남기거나, 외부 dirty 신호를 받아야 한다. 갱신 주기와 계산 우선순위는 cache freshness를 결정한다.
전체 비용을 고정하려면 각 샘플의 요청량을 제한된 예산에 맞춰 배분한다. 이때 현재 화면에 보이는 표면만 우선하면 그 표면에 빛을 전달하는 화면 밖 cache가 늦게 갱신될 수도 있다. 최종 shading의 중요도와 빛 전달에 필요한 중요도가 항상 같지는 않다.
DDGI 역시 이전 프레임의 조명으로 여러 bounce를 반복하며 time lag가 생길 수 있다고 원 논문의 5.3절에서 설명한다. 시간 재사용의 반응 문제는 surfel에만 한정되지 않는다.
캐시 수명(cache lifetime)은 정확도 설정의 일부다
좋은 temporal reuse는 이전 값의 안정성과 현재 값의 반응성을 함께 다룬다. 동일한 표면인지 확인하고, 조명이 변했는지 측정하고, 유효한 history의 비중과 새 계산량을 조절해야 한다.
캐시의 수명은 단순한 메모리 관리 옵션이 아니다. 얼마나 오래된 조명을 화면에서 허용할지 정하는 정확도 설정이기도 하다.
마지막 글 「결국 GI는 캐시 문제다: Lightmap부터 Radiance Cache까지」에서는 공간 표현과 시간 정책을 하나의 틀로 묶어, 새로운 GI 기법을 읽을 때 사용할 질문들을 정리한다.
References
- Christoph Schied et al., Spatiotemporal Variance-Guided Filtering, HPG 2017. 시간 누적과 variance 기반 화면 필터.
- EA SEED / Frostbite, Global Illumination Based on Surfels, 발표 PDF, SIGGRAPH 2021, PDF 74–79쪽. Adaptive integration과 ray budget.
- Zander Majercik et al., Dynamic Diffuse Global Illumination with Ray-Traced Irradiance Fields, JCGT, 2019, 5.3절. 프레임 간 multiple-bounce 갱신과 지연.