
요약 (Abstract):
빠른 템포의 멀티플레이어 슈팅 게임에서 실시간 레이 트레이싱(Real-time Ray Tracing)을 구현하는 것은 매우 까다로운 과제입니다. 극도로 타이트한 프레임 타임 예산(Frame Time Budget) 내에서, 급격한 카메라 전환과 역동적인 오브젝트 움직임 속에서도 렌더링 품질이 흔들림 없이 안정적으로 유지되어야 하기 때문입니다. 《콜 오브 듀티: 모던 워페어 4(Call of Duty: Modern Warfare 4)》에서는 스크린 스페이스 디노이징을 적용하는 기존의 고정 레이트(Fixed-rate) 레이 트레이싱 방식이 한계를 드러냈습니다. 치열한 경쟁 플레이 환경에서 디스어클루전(Disocclusion) 아티팩트와 템포럴 래그(Temporal Lag, 시간적 잔상)는 플레이어의 시야를 크게 방해하기 때문입니다.
본 발표에서는 결정론적 성능(Deterministic Performance)을 희생하지 않으면서도 일관된 비주얼 품질을 제공하도록 설계된, 실제 프로덕션 검증을 거친 가변 레이트 레이 트레이싱(Variable Rate Ray Tracing, VRRT) 시스템을 소개합니다.
저희 접근 방식은 픽셀마다 레이 예산(Ray Budget)을 동적으로 할당하여, 1 미만 spp(sub-1 sample-per-pixel) 트레이싱(공간적 언더샘플링 및 시간적 재구성)과 안정성이 핵심적인 영역에서의 선택적 슈퍼샘플링(>1 spp)을 모두 지원합니다. 템포럴 그래디언트 프리패스(Temporal Gradient Pre-pass)와 명시적 디스어클루전 감지를 활용해 불안정해질 픽셀을 사전에 감지하고, 아티팩트가 드러나기 전에 선제적으로 샘플링 수를 늘립니다. 여기에 더해, 프레임당 총 레이 수를 일정하게 유지하면서 레이를 화면 공간상에 재분배하는 완전 GPU 주도형(Fully GPU-driven) 프레임 레벨 스케줄러를 도입했습니다. 이를 통해 급격한 카메라 회전이나 대규모 동적 연출이 발생하는 순간에도 GPU 연산 비용을 일정하게 유지하고 성능 스파이크(Performance Spike)를 원천적으로 방지합니다.
발표자 소개 (Speaker Bio):

미하우 올레이니크(Michał Olejnik)는 인피니티 워드 폴란드(Infinity Ward Poland)의 시니어 엑스퍼트 렌더링 엔지니어(Senior Expert Rendering Engineer)로, 실시간 레이 트레이싱 및 패스 트레이싱 연구개발 팀을 이끌고 있습니다. 데모씬(Demoscene) 출신의 인디 스튜디오 Plastic에서 그래픽스 커리어를 시작하여 PlayStation 4 독점작인 실험적 타이틀 Bound 개발에 참여했습니다. 2017년 설립된 Infinity Ward Poland에 합류한 이후 레이 트레이싱 R&D에 집중해 왔습니다. Modern Warfare (2019) 및 Black Ops 7 (2025)을 비롯한 《콜 오브 듀티》 프랜차이즈 전반의 다양한 레이 트레이싱 시스템 개발을 주도했으며, *Modern Warfare III (2023)*에서는 프로토타입 실시간 패스 트레이서 개발을 담당했습니다. 현재는 차세대 실시간 레이 트레이싱 기술 고도화에 주력하고 있습니다.

안녕하세요, 저는 미하우이고 Infinity Ward Poland에서 시니어 엑스퍼트 엔지니어로 일하고 있습니다. 또한 Call of Duty 프랜차이즈의 레이 트레이싱 리드 엔지니어이기도 합니다.
오늘은 제가 무려 7년 동안 틈틈이(사실 대부분은 손을 놓고 있었지만) 작업해 온 것을 여러분께 소개하려 합니다. 2021년에 완전한 프로토타입을 만든 뒤, 5년이 지나서야 마침내 모든 것을 Call of Duty 엔진에 통합할 시간을 냈습니다.
자, 보시죠...

… 가변 레이트 레이 트레이싱(Variable Rate Ray Tracing).
혹시 "아, 그러니까 가변 레이트 셰이딩(variable rate shading)을 레이 트레이싱에 적용한 거?"라고 생각하셨다면,
그 이상입니다.
VRRT는 포괄적인 용어로, 화면 공간 디노이징에서 흔히 발생하는 문제를 해결하기 위해 광선을 재분배하는 여러 기능을 아우르기 위해 제가 쓰는 표현입니다. 이 발표는 레이 트레이싱만큼이나 디노이징에 관한 내용이기도 합니다.
일관된 이미지 품질과 성능은 역동적인 멀티플레이어 액션 게임의 궁극적인 목표입니다. 디노이징에 익숙하신 분이라면 제가 어디로 향하고 있는지 이미 짐작하셨을 겁니다. 그렇지 않더라도 발표 내내 많은 영상과 함께 자세히 설명하겠습니다!

맥락을 설정하는 것이 중요합니다 – 왜 우리가 특정 문제를 해결하는 데 신경 쓰는지, 그리고 어떻게 우리의 해법을 떠올렸는지 말이죠. 저는 이 맥락을 두 가지 방식으로 설정하겠습니다.
첫째, 시간순으로 초기 Call of Duty 엔진 의 레이 트레이싱 및 디노이징 실험과, 가변 레이트 셰이딩 및 레이 트레이싱이 그것들에 어떻게 들어맞는지 살펴보겠습니다.
둘째, 우리가 실험 중에 마주친 모든 디노이징 문제를 분석하고, 왜 그것들을 고쳐야 하는지 보여드리겠습니다.
마지막으로, 우리 VRRT 솔루션의 4가지 핵심 축을 살펴보겠습니다.


첫 번째 시도에서 우리는 프랜차이즈의 미래를 위해 레이 트레이싱의 실현 가능성을 평가하고자 했습니다. 로컬 광원 그림자를 선택한 이유는 두 가지입니다. 광원별 TLAS 덕분에 BVH를 단순하게 유지할 수 있었고, 셰이딩이 필요 없었기 때문입니다. 셰이딩은 우리 F+ 엔진에 바인드리스 지원이 없어 대규모 재작업이 필요했을 것입니다.
기존 최신 기술에 대한 우리의 가장 주목할 만한 추가 요소는 아마도 GPU 로드 밸런서였을 것입니다. 이전에는(그리고 우리 타이틀 출시 후 몇 년 동안에도) 광원당 디노이저 하나로 레이트레이스 그림자를 처리하는 것이 업계 표준이었고, 이는 화면에 광원이 둘 이상일 때 스파이크와 성능 저하를 의미했습니다. 저는 이를 고전적인 디퍼드 라이팅에 비유하고, 우리 방식은 타일 기반 광원 컬링의 레이트레이스 버전에 해당한다고 봅니다. 디노이저는 픽셀당 4개의 그림자 신호(즉 픽셀당 4개의 광원, 다만 픽셀마다 다른 광원이거나 순서가 다를 수 있음)를 추적할 수 있었고, 우리는 광원 컬링 출력을 사용해 전체 화면에서 픽셀당 평균 광원 수를 세고 광원당 광선 수를 결정했습니다.
더 자세한 내용은 2020년 제 발표를 참고하시면 됩니다. 결국 이 광원 로드 밸런서는 실제로 VRRT의 핵심 축 중 하나인 보다 일반화된 로드 밸런서의 기반이 되었습니다 (슬라이드에서는 이 축들을 하늘색으로 표시하고 있습니다) – 곧 더 자세히 논의하겠습니다.

같은 시기에 Call of Duty: Black Ops Cold War의 개발이 Treyarch 주도로 병행되고 있었습니다. 우리는 비슷한 제약과 성능 목표 아래 비슷한 기능을 출시하게 되었습니다. 이때가 현세대 콘솔의 첫해이기도 했습니다.
저는 이 프로젝트의 막바지에 도움을 요청받았습니다. 저는 곧 콘솔에서의 raygen 성능이 Call of Duty: Modern Warfare에서보다 조금 더 병목이라는 것을 깨달았습니다. 우리는 실효 광선 수를 줄이기 위해 가변 레이트 셰이딩의 원리를 레이 트레이싱에 적용한다는 아이디어를 냈습니다. 이미 성공적인 VRS 구현이 Call of Duty: Modern Warfare에 있었기 때문에(2020년 이 코스에서 Michał Drobot가 발표했습니다), 그것이 VRRT 구현의 기반이 되었습니다.
안타깝게도 우리는 이미 1/4 해상도(1440p => 720p)에서 레이 트레이싱과 디노이징을 하고 있었고, 여기에 VRRT를 적용해 해상도/광선을 더 낮추자(720p => 360p) 동적 그림자에 대한 분산 기반 색상 클램핑에서 문제가 발생했습니다. 이에 대해서는 발표 내내 더 설명하겠지만, 중요한 요점은 VRRT가 성공하려면 더 신뢰할 수 있는 모션 감지 방법이 필요했다는 것입니다.

결국 주로 멀티플레이어 콘솔 타이틀로서, 우리는 레이 트레이싱을 핵심 엔진 렌더링 기술의 일부로 삼는 것을 정당화하기 어렵다는 것을 깨달았습니다. 이는 대체로 다음에 대한 우리의 높은 기준 때문이었습니다. 프레임레이트(120Hz 성능 모드 / 60Hz 품질 모드)와 해상도(교전 중 선명함을 위해 필요)에 대한 기준이죠. 레이트레이스 그림자와 AO는 좋았지만 큰 성능 대가가 따랐고, raygen/디노이징의 낮은 해상도 때문에 항상 그림자 맵보다 나은 것도 아니었습니다.
결국 우리는 하드웨어가 따라올 때까지 기다리면서 레이 트레이싱 백엔드를 천천히 구축하기로 했습니다. 우리의 주된 엔진 개발 방향은 바인드리스 머티리얼과 지오메트리를 추가해, 성능 좋은 광선 히트 셰이딩에 필요한 우버 셰이더 방식을 구현하는 것이었습니다. 이는 대부분의 다른 게임 엔진보다 우리에게 조금 더 어려웠습니다. 우리는 주로 F+ 파이프라인(디퍼드가 아님)이었기 때문에 셰이더 퍼뮤테이션에 의존하게 되었고, RT 히트 포인트 셰이딩과의 좋은 균형을 찾기 위해 대대적인 재작업이 필요했습니다. 또한 우리는 단순화된 바인드리스 셰이딩 구현에 만족하지 못했습니다. 우리는 완전한 머티리얼 기능 동등성을 원했는데, 가장 시급한 관심사가 라이팅 아티스트를 위한, 그리고 레퍼런스 렌더러로서의 패스 트레이싱이었기 때문입니다.
개인적으로 저는 그 두 프로젝트에서 마주친 화면 공간 디노이징 문제를 해결하는 데 집중하고 싶었습니다. 우리는 디노이징 아티팩트가 멀티플레이어 게임플레이의 선명함과 공정성에 미치는 영향에 대해 큰 우려가 있었습니다.
참고:
또한 짚고 넘어갈 점은, RTGI에 대한 우리의 필요가 그리 크지 않았다는 것입니다. 우리는 이미 2019년에 PS4에서 8x8km 배틀로얄을 1080p/60Hz로 성공적으로 출시했기 때문입니다. 네트워크를 통한 베이킹을 위해 방대한 서버 아키텍처를 활용해 완전히 베이크된 고품질 라이팅을 사용했습니다. 시간이 지나면서 이를 더욱 확장했습니다.
Precomputed lighting in Call Of Duty: Infinite Warfare
Indirect lighting is an important factor in creating a believable look of game worlds.
research.activision.com
Ray Guiding for Production Lightmap Baking
In this paper we present a ray guiding technique for improving the computation times in the context of production lightmap baking. Compared to state-of-the-art, our method has better scalability and lower variance.
research.activision.com
The Design and Evolution of the UberBake Light Baking System
We describe the design and evolution of UberBake, a global illumination system we have used in multiple AAA games, which supports dynamic lighting changes in response to certain player interactions.
research.activision.com
Large-Scale Global Illumination in Call of Duty
A presentation describing the key techniques behind the large-scale global illumination system in Call of Duty. Explained is a new precomputed lighting compression technique that enables high-performance and seamless reconstruction directly from the compre
research.activision.com
The Neural Light Grid: A Scalable Production-Ready Learned Irradiance Volume
Our system that precomputes and stores indirect diffuse lighting into a volume-based data structure of lighting probes for our large game scenes.
research.activision.com

그렇게 해서 우리는 장기적인 레이트레이싱 작업을 시작했습니다.
2021년, 다른 사람들이 바인드리스를 끝내기를 기다리는 동안 저는 VRRT 슈퍼샘플링(즉, 시간적 히스토리가 무효화된 픽셀에 대해 광선을 2개 이상 쏘는 것)을 연구하는 데 시간을 좀 썼고, 이를 예산 안에 유지하기 위한 일반화된 로드 밸런서도 포함했습니다. 또한 분산 기반 색상 클램핑을 대체하는, 동적 이벤트 감지를 위한 템포럴 그래디언트를 추가했습니다. 이 각 부분에 대해서는 나중에 자세히 논의하겠습니다.
이 프로토타입을 완성하면서, 저는 마침내 우리가 흔한 화면 공간 디노이징 문제를 해결할 수 있다고 스스로를 납득시킬 수 있었습니다. 덕분에 우리는 레이 트레이싱의 미래를 온전히 받아들일 수 있었습니다. 다만 이 모든 것은 제 프로토타이핑용 장난감 엔진에서 이루어졌고, Call of Duty 엔진에 완전히 구현하기까지는 수년이 걸렸습니다.
2022년, 바인드리스의 기본 구성 요소가 완성되면서 우리는 단순화된 패스 트레이서(단순 머티리얼 모델)와 비지빌리티 버퍼 셰이딩의 프로토타입을 만들었습니다(이것은 올해 마침내 Call of Duty: Modern Warfare 4에 출시되며, 이는 하이브리드 F+/V+ 래스터 파이프라인을 갖게 됨을 의미합니다).
2023년, Nvidia가 DLSS-RR(머신러닝 디노이저 + 업샘플러 조합)을 출시했고, 우리는 Call of Duty: Modern Warfare 3를 위한 작은 패스 트레이싱 실험에서 협업했습니다. 우리는 MP 로비를 준(準) 패스트레이스 포토 모드로 선택해, 제한된 환경에서 히어로 에셋(총기 + 캐릭터)에 이를 선보이면서 패스 트레이싱을 한계까지 밀어붙일 수 있었습니다. 결국 수년간 Activision 전역의 아티스트와 엔지니어가 렌더러에 쏟은 엄청난 노력 덕분에 패스 트레이싱이 시각적 향상을 그리 크게 더해주지 못한다는 것이 드러났고, 그래서 향후 출시작에서는 이를 포기하기로 했습니다.
패스 트레이서를 개선한 것은 여전히 내부 툴링에 큰 이점을 주었고, 2024년에 우리는 마침내 런타임 레이 트레이싱 기능에 착수할 시간을 갖게 되었습니다.
2025년, 우리는 마침내 PC에서 RT 리플렉션을 출시했으며, 전 범위의 광택도는 물론 투명 오브젝트(유리 등)의 반사까지 지원합니다. 여기에는 또한 언더샘플링과 시간적 재구성을 갖춘 VRRT의 첫 기본 버전이 함께 출시되었습니다 – 이것은 제가 처음에 Call of Duty: Black Ops Cold War(2020)에서 그림자에 대해 작동시키지 못했던 바로 그 작업입니다.
올해 우리는 그 위에 Call of Duty Modern Warfare 4를 위한 RTGI를 추가하고자 합니다. 이제 디노이저는 2021년 초기 프로토타입의 모든 축을 갖춘 완전한 VRRT를 지원합니다. 또한 멀티 신호 디노이징도 지원하는데, 이는 Call of Duty: Modern Warfare(2019)의 멀티 그림자 신호 디노이징과 유사하지만 더 많은 워크로드에 맞게 일반화되었습니다. 즉 리테일 타이틀 목적의 리플렉션 + GI뿐 아니라, 예컨대 내부 패스 트레이서를 위한 4개 신호(직접/간접 디퓨즈/스페큘러)에도 적용됩니다.
참고:
또한 언급할 가치가 있는 점은, 전체 베이크 라이팅을 대체하는 완전한 RTGI가 항상 100% 이득인 것은 아니라는 것입니다. 우리의 경우 베이크 라이팅을 활용해 직접 조명까지 분산 처리할 수 있었습니다. 예를 들어 우리는 정적 광원(성능 최적화를 위해 베이크 전용)과 잔여 라이팅이라는 개념을 갖고 있습니다. 가령 실시간에서는 광원의 범위가 유한하지만, 물리적으로 정확한 무한 1/r^2 감쇠는 라이트맵에 담습니다. 상당한 비용을 추가하지 않고서는 이를 RTGI로 안정적으로 재현할 수 없고 차이가 뚜렷하므로, 하이브리드 RTGI-베이크 솔루션을 예상하시기 바랍니다.

이것들이 제가 VRRT의 일부로 여기는 4가지 핵심 축이며, 모두 화면 공간 디노이징의 다양한 측면을 개선하는 것을 목표로 합니다:
제가 처음 SIGGRAPH에서 발표했을 때, 청중에게 템포럴 그래디언트가 무엇인지 아는 분이 있는지 물었는데 단 한 사람만 손을 들었습니다. 이것은 Christoph Schied가 Q2VKPT/Q2RTX를 위해 개발했으며, 원 논문은 첫 레이 트레이싱 하드웨어가 나오기 전에 발표되었습니다. 아마 이 때문에 주목받지 못했을 것입니다. 저는 이것이 동적 이벤트 감지를 위한 대단히 강력한 도구라고 생각합니다. 이것이 우리 업계에서 결코 보편화되지 못한 것은 안타까운 일입니다 – 저는 이것이 실수라고 생각하며, 디노이징을 진지하게 다룬다면 왜 한번 시도해 봐야 하는지 발표 마지막에 더 시간을 들여 설명하겠습니다.
하지만 먼저 할 것부터 하죠 – 이제 디노이징 기초와 흔한 아티팩트를 살펴본 뒤, VRRT가 그 문제들을 어떻게 해결하는지 논의하겠습니다.


[video] 이것은 RT 작업을 해본 적 없어도 아마 익숙할 것입니다 – 앰비언트 오클루전을 위한 가공되지 않고 노이즈가 많은, 중요도 샘플링된 신호 – 픽셀당 1 샘플이며, 이것을 시간적·공간적 필터로 부드럽게 만들어야 합니다. 모든 게임 엔진은 SSR이나 SSAO 같은 비(非)RT 기능에서 이미 이와 비슷한 것을 하고 있습니다. 레이 트레이싱과의 차이는 광선 추적 비용이 더 비싸다는 점이고, 그래서 보통 ~1spp로 제한됩니다 – 훨씬 더 노이즈가 심하죠.
중요한 요점은 중요도 샘플링을 위해 난수를 어떻게 평가하느냐입니다. 우리는 이것을 (카메라가 움직여도) 프로그레시브 렌더러로 취급하고, 시간에 걸쳐 난수 시퀀스를 평가합니다(rng 인덱스 = 프레임 인덱스). 각 픽셀은 (픽셀 xy 좌표로 결정되는) 서로 다른 시드를 가지므로, 각 픽셀은 서로 상관없는 다른 난수 시퀀스를 평가합니다. 이것은 사실상 화이트 노이즈이지만, 나중에 VRRT를 적용하기 쉽게 만들어 줍니다.
참고:
디노이징이 처음이라면 Dimitri Zhdan과 Christoph Schied의 연구부터 시작하기를 권합니다 – 서로 다른 두 디노이징 학파입니다. VRRT 자체는 Schied의 SVGF/ASVGF 논문에 기반했습니다. github에는 Q2VKPT/Q2RTX와 NRD용으로 공개된 디노이저도 있으니 공부해 보시기 바랍니다. 링크는 참고문헌을 참조하세요.

[video] 여기서 시간적 디노이징이 작동하는 것을 볼 수 있습니다
RT 라이팅 디노이징은 시간적 안티에일리어싱이나 업샘플링보다 간단한데, 엣지를 해결할 필요가 없기 때문입니다

[video] 그리고 여기는 작은 블러 반경을 사용한 공간적 디노이징입니다
물론 이것은 서로 다른 월드 공간 위치의 중요도 샘플링 데이터를 결합하는 것이므로 신호에 편향(bias)을 발생시킵니다.
참고:
이를 해결하려고 작은 공간적 윈도우(공간 필터 크기와 같은 반경)에서 반복 가능한 rng 시드를 사용할 수 있지만, 이는 다른 종류의 편향을 발생시킵니다.

[video] 공간 필터 반경을 늘릴 수 있지만, 이는 편향을 증가시킵니다. 여전히 불안정할 수 있지만, 보통 저주파 불안정성은 시간적 안티에일리어싱/업샘플링의 입력으로는 괜찮습니다.
참고:
공간적 처리 후에만 시간적 처리를 하는 것은 처음부터 픽셀별 디테일을 포기한다는 뜻이며 – 이것은 Call of Duty에서 우리가 원하는 것과 정반대이지만, GI처럼 저렴하게 계산하고 싶은 저주파 신호에는 여전히 쓸 만합니다. 이 접근법의 최신 기술은 작년에 Doom: The Dark Ages GI에서 이루어졌으며, 이후 SSAO와 결합해 잃어버린 디테일 일부를 되찾습니다 [Sousa25]

[video] 물론, 시간적 처리와 공간적 처리를 동시에 둘 다 할 수도 있습니다. 더 작은 공간 블러와 함께 시간적 누적을 하면, 디스오클루전 이후 처음 몇 프레임 동안에만 불안정성을 보게 됩니다.
이는 AO처럼 단순한 신호에서는 대체로 허용할 만합니다. 하지만 그럼에도 Call of Duty에서는 대부분의 액션이 무기 주변에서 일어나며, 무기는 끊임없이 환경과 적 플레이어를 디스오클루전시켜 시각적 선명함, 나아가 게임플레이에 부정적인 영향을 줍니다.

[video] 진정한 성배는 신호를 안정화하는 큰 공간 필터를 허용하면서도 동시에 고주파 디테일을 과도하게 블러 처리하지 않는 것입니다. 그리고 이것은 이미 2017년 – 즉 첫 레이 트레이싱 GPU 이전에 – Christoph Schied가 SVGF로 해결했으며, 이제는 업계 표준이 되었습니다.
자세한 내용은 곧 다루겠지만, 영상으로 어떻게 보이는지 먼저 봅시다 – 다소 벅찰 수 있으니 영상을 일시정지하고 여러 타임스탬프를 비교하시길 권합니다.
신호 분산을 추정하려면 여러 샘플이 필요하며, 그 추정은 시간적 히스토리를 분석해 시간에 걸쳐 이루어진다는 점에 유의하세요 – 왜 이것이 문제인지는 곧 설명하겠습니다.

분산과 모먼트에 대한 간단한 복습
분산을 계산하려면 신호와 신호^2를 추적해야 합니다.
여러분은 아마 기본적인 TAA 분산 기반 히스토리 색상 클램핑에 익숙할 것입니다. 우리는 현재 프레임 색상의 3x3 픽셀 영역을 분석해 분산을 계산하고, 재투영된 이전 프레임 신호를 3x3 평균 ± 표준편차(임의의 스케일을 곱한 값)로 클램핑합니다.
이는 사실상 TAA 고스팅을 1px 이웃으로 제한하게 되는데 – 이것은 마치 안티에일리어싱과 비슷합니다. 이 방식이 완벽하지는 않지만, 핵심 아이디어는 매우 우아합니다.

SVGF에서는 대신 시간적 분산 추정을 사용하는데, 이는 공간적 이웃 대신 시간에 걸쳐 m1/m2를 추적한다는 뜻입니다. 다행히 X 프레임의 히스토리를 추적할 필요 없이, 원신호에서 했던 것과 같은 방식으로 추가 모먼트를 하나 보간하기만 하면 되므로 메모리 효율적입니다.

엔진에 기존 공간 양방향 블러가 있다면, 분산 가중치는 고전적인 깊이/노멀 가중치 바로 옆에 자리하게 됩니다. 픽셀별 분산만 필요하며, 이는 시간적 텍스처에서 계산할 수 있습니다.
하드 그림자 엣지를 상상해 보세요. 엣지 한쪽의 픽셀에 대한 그림자 신호는 모두 0이고 반대쪽은 모두 1이 됩니다 => 분산은 0, 블러 가중치는 0 => 하드 그림자 엣지가 보존됩니다.
소프트 그림자라면 반영(penumbra) 내 픽셀은 0과 1의 조합을 가지므로 분산이 0보다 크고, 반영 내부 픽셀을 부드럽게 만듭니다.

[video] 이것이 SVGF가 작동하는 모습입니다.

[video] 그리고 여기 더 두드러진 예시로, 캐릭터 모델을 이리저리 움직여 화면을 아티팩트로 '칠할' 수 있습니다. Call of Duty 같은 1인칭 게임에서는 분명하게 드러납니다.

[video] 앞서 말했듯 – AO는 아마 디노이징하기 가장 쉬운 RT 기능입니다 – 사실 AO만을 위해서라면 SVGF가 꼭 필요하지도 않습니다.
하지만 그림자 같은 혼합 주파수 신호에서는 하드 그림자 엣지와 부드러운 반영을 모두 갖고자 하며, 그 오차들이 엄청나게 거슬리게 됩니다. 우리는 선명한 반사와 관련해 Call of Duty: Black Ops 7 (2025)에서 비슷한 문제를 겪었습니다.

명백한 해결책은 공간적 폴백을 활용하는 것입니다. 여기에 너무 오래 머물고 싶지는 않으니 – 그냥 엄청나게 어렵다고만 해두죠.
제가 이것을 튜닝할 때 쓰는 디버그 오버레이를 볼 수 있습니다 – 시간적/공간적 분산 추정치, 그 두 추정치를 혼합하는 데 쓰이는 시간적 신뢰도 계수, 그리고 각 공간 atrous 반복 이후의 분산과 (분산이 줄어들면서 반복마다 작아지는) 실효 블러 가중치를 추적합니다.
그런 도구가 있어도 사람이 튜닝하기에는 너무 벅찹니다. 바로 이 지점에서 머신러닝 기법이 빛을 발합니다. 하지만 ML 방식조차도 여전히 시간적 히스토리가 비어 있거나 짧다는 사실에 근본적으로 제약을 받습니다. 대신 그것을 고칠 수 있다면 어떨까요? 제가 그런 경우에 시간적 슈퍼샘플링을 사용하는 것을 언급했던 걸 기억하실 겁니다. 여기에 대해서는 곧 다루겠습니다.
여기서의 요점은 짧은 시간적 히스토리의 결과를 사실상 피할 수 없다는 것입니다
제가 SVGF에 대해 시간을 들여 이야기하는 이유는, 고전적 시공간 디노이저 위에 SVGF가 필요하다면 디노이징 아티팩트 해결에 신경 써야 할 또 하나의 엄청난 이유를 더하기 때문입니다.

우리는 디스오클루전에 대해 많이 이야기했지만, 시간적 히스토리는 움직이는 물체, 광원, 애니메이션 텍스처 같은 동적 이벤트를 감지할 때도 취소됩니다(정확히는: 취소되어야 합니다).
이것은 그림자와 반사에 결정적이며, AO/GI 같은 저주파 신호에는 다소 덜 중요합니다. 애니메이션 하늘의 시간적 지연은 완전히 무시해도 아무도 눈치채지 못하겠지만, 캐릭터와 환경 사이의 오클루전(특히 신발 근처)은 지연을 매우 눈에 띄게 만듭니다.
디스오클루전은 그래도 감지하기 쉬웠지만, 무효 히스토리는 추가 작업이 필요합니다. 그리고 이를 완벽하게 하지 못하면 오차가 디노이징 파이프라인 전체에 걸쳐 누적됩니다. 안타깝게도, 가장 잘 알려진 최신 기술은 그다지 인상적이지 않습니다.

고스팅을 막기 위한 TAA 히스토리 클램핑을 기억하시나요? 이 개념을 시간적 디노이징에 어떻게 적용할까요?

분산 분석 윈도우의 공간 반경을 늘리는 것 – 이것이 사실상 최신 기술입니다.
물론 약간의 뉘앙스와 분산 기반 색상 클램핑을 개선하는 다양한 기법이 있습니다. 하지만 궁극적으로 우리는 우리 문제(노이즈 신호의 시간적 누적)를 위해 원래 만들어진 것이 아닌 기법을 쓰고 있으며, 근본적인 한계에 부딪힙니다.
참고:
색상과 그 분산 정보에만 의존하는 것은 매우 제한적입니다. 생각해 보세요: 우리 게임 엔진에는 오브젝트별(심지어 삼각형별) 모션 정보가 있는데 – 왜 이를 디노이징에 활용하지 않을까요? 이 생각의 흐름은 나중에 템포럴 그래디언트 (VRRT 축 중 하나)로 다시 다루겠습니다.

[video] 제 디노이징 불만 중 하나를 볼 수 있습니다 – 캐릭터 신발 근처의 AO 지연입니다. 이것은 히스토리 기각을 전혀 하지 않은 상태입니다.

[video] 분산 기반 클램프를 적용할 수 있지만, 결코 100% 정확하게 맞출 수는 없습니다. 특히 군중이 등장하는 게임에서 흔합니다.
우리가 가진 유일한 조정 가능한 값(tunables)은 클램핑 윈도우의 공간 반경과 표준편차 스케일뿐이며 – 사람의 두뇌에 그리 친화적이지 않습니다.
이 슬라이드와 이전 슬라이드를 번갈아 보면 모션이 없는 영역에서도 약간의 차이를 알아챌 수 있습니다.

[video] 알고 보니 분산 클램프는 정적 신호조차 쉽게 과도하게 클램핑할 수 있습니다. 제가 클램프를 껐다 켰다 하는 영상에서 드러나듯, 결국 이것은 색상에만 작동하기 때문입니다. 여기서는 더 긴 시간적 히스토리 길이를 사용했습니다. 제대로 클램핑하려면 분산 분석 윈도우 크기를 히스토리 길이에 맞게 늘려야 하는데, 그것은 추가로 비쌉니다.
분산 기반 클램핑은 사실 무효 히스토리 감지 방식이라기보다 교정(rectification)입니다. SVGF에서는 두 번째 모먼트에 대해서도 무언가를 해야 합니다 – 클램핑에 사용한 공간 분산을 기반으로 이를 재계산할 수 있지만, 이 또한 다소 임의적인 휴리스틱입니다. 또한 교정이 (한 번이 아니라) 매 프레임 일어나기 때문에 히스토리 카운터를 재설정하거나 서서히 감쇠시킬 합리적인 방법이 없어, 어떤 히스토리 길이 클램핑 시도든 안정화하기 어렵게 만듭니다.
여기서의 핵심 요점은 업계 표준인 분산 기반 색상 클램핑은 그저 충분히 좋지 않다는 것입니다 – 그리고 신뢰할 수 있고 고품질인 시간적 디노이징을 달성하는 데 있어 큰 걸림돌입니다.

우리는 기초를 살펴봤습니다 – 고전적 시공간 디노이징 파이프라인의 아티팩트, SVGF가 어떻게 그것을 악화시킬 수 있는지, 그리고 분산 기반 클램핑이 얼마나 신뢰할 수 없는지 말이죠.
이제 우리는 다음을 더 명확히 볼 수 있습니다: VRRT 구성 요소들이 어떻게 함께 작동할지 말이죠.
따라서 고품질 무효 히스토리 감지는 VRRT에 결정적입니다 — 진정으로 일관된 품질을 강제하려면 말이죠. 그리고 일관된 성능을 위해서는 로드 밸런서가 필요합니다.
이제 모든 VRRT 축을 살펴봅시다, 슈퍼샘플링부터 시작해서요.


VRS와 달리, 우리는 고정된 래스터 픽셀 그리드에 제한되지 않으므로 VRRT는 완전한 '소프트웨어' 솔루션입니다.
디스오클루전된 영역을 어떻게 슈퍼샘플링할지 생각해 봅시다. 우리는 raygen 이전에 디스오클루전을 감지해야 하므로, 시간적 디노이저를 시간적 재투영 패스와 누적 패스로 분리해야 합니다. 이렇게 하면 재투영 중에 몇 개의 광선을 쏠지 결정하고 이 정보를 raygen에 전달할 수 있습니다. 가능한 가장 단순한 구현에서는 픽셀을 디스오클루전된 것으로 볼지 아닐지에 대한 이진 결정을 내린 다음, 완전한 시간적 히스토리에 도달하기에 충분한 광선을 요청합니다.
참고:
VRRT를 완전히 활용하려면, 재투영 풋프린트에 텍셀별 기각 가중치(예: 바이리니어)를 사용해 누적 신호 품질을 개선할 것을 권합니다(품질이 더 높으면 더 긴 히스토리를 유지할 수 있습니다). 깊이/노멀을 보간하지 말고, 각 텍셀을 포인트 샘플링으로 개별 처리하며 디스오클루전된 텍셀의 기여를 개별적으로 취소하세요. 이것은 커스텀 인코딩(예: RGB9E5)을 하고 여러 신호를 UINT 텍스처에 수동으로 패킹하는 경우에도 필요합니다 – 어차피 그것들을 수동으로 보간해야 하기 때문입니다.

VRS와 달리, 우리는 고정된 래스터 픽셀 그리드에 제한되지 않으므로 VRRT는 완전한 '소프트웨어' 솔루션입니다.
디스오클루전된 영역을 어떻게 슈퍼샘플링할지 생각해 봅시다. 우리는 raygen 이전에 디스오클루전을 감지해야 하므로, 시간적 디노이저를 시간적 재투영 패스와 누적 패스로 분리해야 합니다. 이렇게 하면 재투영 중에 몇 개의 광선을 쏠지 결정하고 이 정보를 raygen에 전달할 수 있습니다. 가능한 가장 단순한 구현에서는 픽셀을 디스오클루전된 것으로 볼지 아닐지에 대한 이진 결정을 내린 다음, 완전한 시간적 히스토리에 도달하기에 충분한 광선을 요청합니다.
참고:
VRRT를 완전히 활용하려면, 재투영 풋프린트에 텍셀별 기각 가중치(예: 바이리니어)를 사용해 누적 신호 품질을 개선할 것을 권합니다(품질이 더 높으면 더 긴 히스토리를 유지할 수 있습니다). 깊이/노멀을 보간하지 말고, 각 텍셀을 포인트 샘플링으로 개별 처리하며 디스오클루전된 텍셀의 기여를 개별적으로 취소하세요. 이것은 커스텀 인코딩(예: RGB9E5)을 하고 여러 신호를 UINT 텍스처에 수동으로 패킹하는 경우에도 필요합니다 – 어차피 그것들을 수동으로 보간해야 하기 때문입니다.

여기서 중요도 샘플링에 사용되는 rng와 관련해 다뤄야 할 한 가지 특이점이 있습니다(Christoph Schied의 A-SVGF / 템포럴 그래디언트 논문에서 확장된 아이디어입니다).
앞서 제안한 고전적 rng 방식 – 시간에 걸쳐 퍼진 시간적 패턴으로 '프로그레시브 렌더링'을 하는 방식 – 에서는 프레임 인덱스를 그 시간적 패턴 안의 rng 인덱스로 사용합니다(픽셀마다 다른 패턴). 이는 프레임마다 픽셀당 광선 수가 가변적이면 더 이상 유효하지 않은데, 같은 rng 출력을 재사용하기 시작하기 때문입니다(즉, 같은 광선을 두 번 쏘게 됨). 슬라이드의 애니메이션에서 볼 수 있습니다.
해결책은 간단합니다 – 우리는 rng 인덱스를 페이로드의 나머지(m1/m2/sampleCount)와 함께 재투영합니다. 이것은 프레임 인덱스로 시작할 수 있지만, 각 픽셀의 광선 수만큼 증가합니다(위 코드 참조). 우리는 rng 인덱스를 재투영 패스에서 raygen 및 누적 패스로 전달해야 합니다(요청된 광선 비율에 더해). '인덱스'에 바이리니어 보간을 하는 것은 전혀 말이 안 되므로 포인트 샘플링을 사용합니다 – 실제로 매우 잘 작동합니다(휴!).
카메라가 움직일 때는 기술적으로 시작 픽셀 xy 좌표도 재투영해야 하지만, 실제로는 생략할 수 있습니다. VRRT 이전의 원래 '프로그레시브' 방식도 움직이는 카메라에서는 기술적으로 정확하지 않았지만 잘 작동했고 업계 전반에서 널리 쓰입니다.
참고: 이상적으로는 이를 블루 노이즈 [Heitz19][Wolfe24]를 지원하도록 확장하고 싶습니다 – 제 TODO 목록에 있습니다.

[video] 먼저, 슈퍼샘플링 없이 AO의 시간적 출력을 봅시다 (64 샘플, 오차를 더 뚜렷하게 만들려고 AO 반경을 충분히 높여 사실상 스카이 오클루전이 되게 했습니다).

[video] 이제 시간적 슈퍼샘플링을 적용하면, 디스오클루전 영역이 거의 영향을 받지 않는 것을 볼 수 있습니다. 미세한 차이는 지수 이동 평균이 lerp 계수를 클램핑하더라도 기술적으로 '무한' 개수의 샘플을 (가중치가 0에 가까워지며) 누적한다는 사실에서 비롯됩니다.
화면 하단의 진행 막대도 볼 수 있습니다. 이는 전체 화면에서 몇 개의 광선이 요청되었는지(1.0 = 픽셀당 평균 1개), 그리고 몇 개가 추적되었는지를 보여줍니다(로드 밸런서가 없으면 둘은 같습니다). 빨간색이 되면 그 부분이 예산을 초과했다는 뜻입니다(여기서는 로드 밸런서가 없어서 발생합니다).

[video] 그리고 여기서는 VRRT 끄기 / 픽셀당 최대 16 광선 비율 요청 / 최대 64 광선 비율 요청을 오갑니다(시간적 길이는 항상 64, AO를 크게 과장함).오른쪽 오버레이에 주목하세요. VRRT가 켜지면 어떤 픽셀이 더 많은 광선을 요청하는지 볼 수 있습니다("Final shot rays"). 히스토리 길이의 히트맵도 볼 수 있습니다(재투영 후 및 누적 후). 완전한 VRRT에서는 "accumulated samples"가 가득 찬 상태를 유지합니다. ( 부분적 )

[video] 여기는 rng 인덱스 재투영을 비교한 것입니다(단, 픽셀
xy는 rng 시드에 사용하지 않음). 차이가 그리 크지는 않지만 눈에 띕니다. 일반적으로 이런 종류의 오차가 디노이징 파이프라인 전반에 누적되는 것을 원치 않으며, rng
인덱스는 페이로드에서 겨우 몇 비트에 불과하므로 항상 이렇게 하는 것을 권합니다.슈퍼샘플링 (최대 16 광선, 시간적 길이 64)이라도, 시간적 히스토리가 가득 차지 않아도 좋은 공간 필터와 SVGF에 여전히 충분합니다.

반대편 끝에는 언더샘플링 (<1spp)과 시간적 재구성(업샘플링)이 있습니다.
Call of Duty: Black Ops 7에서는 다음과 같은 언더샘플링 모드가 있었습니다:
Call of Duty: Modern Warfare 4에서는 각 픽셀이 '분수 광선 비율(fractional ray rate)', 즉 추적될 확률을 요청하도록 허용하는 보다 일반화된 방식을 출시하려 합니다 – 각 픽셀은 (앞선 '쿼드' 예시처럼) 이웃을 인식하지 않고 개별적으로 결정합니다.
우리는 블루 노이즈 텍스처를 임계값 처리에 사용해 주어진 광선을 쏠지 말지를 결정합니다. 분산 기반 광선 스킵 휴리스틱을 사용하는데, 시간적 히스토리 버퍼가 가득 찰 때까지 기다린 다음 분산에 따라 광선 비율 요청을 낮춥니다. 이를 통해 '안전한 영역'에서 광선을 건너뛸 수 있습니다. 이를 튜닝하는 데 4개의 버킷을 사용하지만, 곡선으로 일반화할 수도 있습니다. 이 방식의 좋은 점은 작년의 쿼터 레이트 모드를 0.25 확률로 간단히 달성할 수 있다는 것입니다. 물론 이 픽셀에 대해 VRS 마스크가 비활성이면 그냥 0% 확률을 사용합니다.

로드 밸런서가 슈퍼샘플링과 언더샘플링을 어떻게 결합하는지 살펴보기 전에, 우리의 시간적 재구성이 올바른지 확인합시다.
다행히 디노이징에서의 시간적 재구성은 엣지를 해결할 필요가 없기 때문에 TAAU보다 훨씬 간단합니다.
재투영 풋프린트에 텍셀별 기각 가중치를 사용하라고 제안했던 것을 기억하시나요? 이는 부분적으로 여기서도 '빈 히스토리' 기각 테스트를 수행해야 하기 때문입니다. 다만 텍셀을 실제 히스토리 길이로 가중하지 않도록 주의하세요 – 이는 신호 스위밍(swimming)을 일으키고 이미지 품질을 크게 떨어뜨리는 것으로 알려져 있습니다.
시간적 히스토리에 도달한 후, 쿼드 내 픽셀의 히스토리가 64, 64, 64, 65가 될 수 있습니다(최대 시간적 히스토리 길이가 64일 때). 그 65를 너무 일찍 클램핑하지 않도록 하세요. 그렇지 않으면 '갱신된' 샘플이 시간적 필터에 제대로 기여하지 못하고, 신호가 수렴하는 대신 시간이 지나며 소산됩니다. 올바른 누적 수행 방법은 제공된 코드를 참조하세요.

[video] 정적 카메라에서의 시간적 재구성
이상적으로는 이것이 카메라 컷에서만 발생하는데, 부분 화면 무효화에서는 항상 빠르게 슈퍼샘플링하기 때문입니다.

[video] 동적 카메라에서의 시간적 재구성
참고: 시간적 처리가 없을 때의 흐릿함은 비활성화된 공간 분산 추정 때문입니다(시간적 히스토리가 수렴할 때까지 분산 가중치가 꺼져 있어 과도한 블러가 발생함)

[애니메이션 슬라이드] 우리의 현재 로드 밸런싱 알고리즘은 단순함 쪽으로 치우쳐 있습니다.
우리는 프레임당 고정 예산(매 프레임 동일한 광선 수)을 달성하고자 하며 – 이는 '픽셀당 평균 광선 수' 슬라이더(예: 1.5)로 표현됩니다. 각 픽셀은 독립적으로 자신의 요청 광선 비율을 결정하고(즉 슈퍼샘플링 및 언더샘플링 섹션에서 설명한 방식으로), 이 값들을 버킷으로 양자화해야 각 버킷의 픽셀 수와 전체 화면의 광선 비율 총합을 (전역적으로) 제대로 셀 수 있습니다. 사실, 광선 비율 요청을 이미 양자화된 인덱스로 지정해 양자화 단계를 건너뛸 수도 있습니다.
각 버킷의 카운터는 시간적 재투영 셰이더 끝에서 누적할 수 있는데, 이 셰이더는 이미 광선 비율을 결정하는 모든 중요한 데이터를 가져와 두었습니다. InterlockedAdd를 groupshared 메모리에 활용한 다음, 컴퓨트 그룹 내에서 값을 reswizzling(재배치)하여 각 레인이 별도의 버킷 인덱스에 InterlockedAdd를 수행하게 하면 사실상 추가 비용 없이 할 수 있습니다(즉, 컴퓨트 그룹 내 여러 스레드에서 동일한 주소로 전역 메모리에 InterlockedAdd를 사용해서는 안 됩니다)
로드 밸런싱을 적용하려면, 예컨대 전체 화면 광선 총합이 예산을 초과할 때, 활성 픽셀이 있는 가장 높은 버킷을 찾아 예산 안에 들어올 때까지 그 픽셀들을 한 버킷 낮춥니다. 예산 미만인 경우에는 반대로 합니다. 이는 로드 밸런서가 픽셀별 광선 요청에 작동하는 것이 아니라, 버킷 수준에서만 임계값을 결정한다는 뜻입니다.

이 방식은 거칠기 때문에 명백한 실패 사례가 있습니다. 예를 들어 한 버킷의 모든 픽셀을 올릴 수는 있지만 그 픽셀의 일부만 올릴 수는 없어 과대평가할 수 있습니다. 이를 해결하기 위해 '링(rings)'으로 검색을 정교화합니다(그림 참조, 그다지 둥글지는 않지만 간단히 계산할 수 있고 계산을 쉽게 하려고 컴퓨트 그룹 크기에 맞춥니다). 따라서 '버킷 임계값' 위에 이 버킷 내부의 '링 임계값'을 찾아야 부분적인 버킷 올림을 할 수 있습니다. 이를 위해 각 링(각 링 x 각 버킷)마다 추가 카운터가 필요하지만, 이 역시 재투영 셰이더 끝에서 저렴하게 할 수 있습니다.
이를 통해 '중심와(foveated)' 우선순위를 부여할 수 있는데, 주어진 버킷에서 화면 안쪽 부분이 바깥쪽보다 광선을 1개 더 갖게 됩니다 – 특히 FPS에서는 보통 중앙 근처의 품질이 더 좋기를 원합니다.
물론 이 방식을 > 1인 분수 버킷을 처리하도록 확장하고(그 광선들을 화면 전체에 균일하게 분산), 언더샘플링처럼 노이즈를 통한 임계값 처리를 활용할 수도 있지만, 이는 버킷 수를 크게 늘려 간단하지 않습니다.

로드 밸런서 자체는 단일 셰이더 레인(또는 LDS로 버킷을 프리페치하려면 단일 그룹)에서 실행되는 사소한 프로그램입니다. 내부 중첩 루프는 반복 횟수가 많을 수 있지만, 단일 스레드이므로 그냥 넘어갈 수 있습니다. 이것은 (예: > 1인 분수 버킷을 처리할 때) 다시 손보고 싶은 부분입니다. 편의를 위해 코드를 제공합니다.

광선 밸런싱 비용의 대부분은 우리가 찾은 버킷/링 임계값에 맞춰 광선 요청을 '트리밍'해야 하는 패스에서 나옵니다. 다행히 작은 텍스처 하나만 읽으면 되고 임계값 처리 코드가 매우 단순해서 비용은 미미합니다. 이 패스는 또한 간접 디스패치 args를 raygen 셰이더용으로 계산하고, 스레드 디스크립터(광선 수, rng 오프셋, 픽셀 xy 좌표)를 담은 버퍼(리스트)도 계산해야 합니다. 이것 역시 거의 무료로 만들 수 있습니다 – 버퍼 카운터와 각 스레드의 출력 인덱스 계산을 위해 WavePrefixSum + InterlockedAdd를 groupshared 메모리에 활용하세요.

사용할 수 있는 몇 가지 구현 팁입니다. 우리는 현재 분리된 TraceRay/셰이딩을 사용하며, 히트 지오메트리/머티리얼 특성 기반의 버킷팅을 적용하므로 각 광선은(슈퍼샘플링 시에도) 자체 스레드를 가지며, 시간적 누적 전에 이를 합산하는 작은 패스를 둡니다.

[video]

[video]

[video]

이제 광선을 가장 중요한 곳으로 옮기는 신뢰할 수 있는 방법을 갖췄으니, 디스오클루전과 동일한 원리를 적용할 수 있도록 동적 이벤트 감지와 히스토리 기각을 '그저' 처리하기만 하면 됩니다. 앞서 설명했듯 분산 기반 색상 클램핑은 '감지' 알고리즘이 아니라 히스토리 교정 알고리즘에 가깝습니다. 우리는 더 나은 것을 원합니다.
다행히 SVGF의 저자인 Christoph Schied가 후속 논문을 통해 템포럴 그래디언트 개념을 도입했는데, 이는 분산 기반 클램핑의 훌륭한 대안입니다.
템포럴 그래디언트 주제에 관한 자료들을 꼭 숙지하시길 강력히 권합니다. 주요 논문은 다소 추상적이지만, 핵심 개념에 대한 실용적인 발표(슬라이드에 링크됨)와 서로 다른 두 개의 오픈소스 구현이 모두 제공됩니다. 분산 기반 클램핑보다 엔진 측 작업이 조금 더 필요하지만 매우 강력한 도구입니다. 우리 업계가 이것을 정말 등한시하고 있다고 생각합니다.

템포럴 그래디언트의 핵심 개념은, Q2VKPT에 구현된 대로 다음과 같습니다: raygen을 작은 타일로 나누고(Q2VKPT에서는 3x3), 타일마다 무작위 픽셀을 골라 이전 프레임과 정확히 같은 광선을 쏜 다음, 들어오는 라디언스를 비교해 작은 텍스처로 출력합니다. 이것이 템포럴 그래디언트, 즉 라디언스의 변화율입니다. 이는 거친 화면 공간 추정치이므로 유용하려면 블러가 필요하지만, 화면의 어느 부분에 (대략) 동적 조명 이벤트가 일어나는지 감지할 수 있게 해줍니다. 이를 사용해 시간적 히스토리 버퍼 길이를 클램핑할 수 있습니다(이것은 임의의 튜닝 값입니다).
같은 광선을 쏘려면 광선의 원점과 방향에 영향을 주는 이전 프레임의 모든 데이터를 재투영해야 합니다. 자세한 내용은 뒤 슬라이드의 코드를 참조하세요.

Call of Duty에서 우리는 템포럴 그래디언트를 프리패스(prepass)로 구현했습니다 – 메인 raygen 이전에 템포럴 그래디언트를 계산하는 별도의 더 작은 raygen입니다. 이렇게 하면 메인 광선을 어디에 쏠지 결정하기 전에 템포럴 그래디언트 정보를 확보할 수 있어, 디스오클루전 데이터와 함께 시간적 재투영 패스에 공급되어 광선 비율을 결정할 수 있습니다.
그런 패스는 추가 광선 때문에 추가 비용이 들지만, 템포럴 그래디언트는 낮은 해상도(예: 8x8 다운샘플),에서도 강력하며, 낮은 해상도의 단점은 VRRT 슈퍼샘플링으로 자동으로 완화됩니다. 평균적으로 템포럴 그래디언트 추정치가 화면의 작은 부분만 차지하는 한, 광선 예산에 맞추면서 그 영역을 슈퍼샘플링할 수 있어야 합니다.

악마는 디테일에 있으므로, 템포럴 그래디언트 구현을 위한 몇 가지 실용적인 팁과 코드 샘플을 적어두었습니다 – 여러 파일을 오가야 하는 Q2VKPT/RTX github 저장소보다 초기 파악에는 조금 더 읽기 쉬울 것입니다.
가장 중요한 것은, 템포럴 그래디언트용 광선을 쏠 때 셰이더 전체가 지난 프레임에 사용된 동일한 rng에 '연결'되어야 한다는 점입니다 – 그렇지 않으면 지속적인 거짓 양성이 발생하여 슈퍼샘플링이 VRRT에 의해 불필요하게 수행됩니다.

[video] 템포럴 그래디언트가 작동하는 모습입니다

[video] 여기서는 더 역동적인 시나리오에서 모든 디버그 오버레이를 살펴봅니다

[애니메이션 슬라이드] 전체 파이프라인은 다음과 같습니다:
시간적 재투영 패스에서 대부분의 마법이 일어나는데, 광선 비율 계산에 영향을 주는 모든 데이터 소스를 공급하고 최종 결정을 내리기에 완벽한 지점이기 때문입니다(디스오클루전, 템포럴 그래디언트, VRS 마스크)


이제 VRRT의 모든 구성 요소를 갖췄으니, 이들이 어떻게 맞물리는지 정리해 봅시다(슬라이드의 색상 코딩에 주목하세요).
모션을 감지하는 신뢰할 수 있는 방법을 갖추면 이 프레임워크가 하나로 완성되는데, 이제 시간적 히스토리 유효성에 관한 주요 불확실성 요인이 없기 때문입니다.
우리는 불안정한 영역을 쉽게 슈퍼샘플링하고 안정적인 영역을 언더샘플링할 수 있으며, 동시에 (결정적으로!) 무언가 움직이기 시작할 때 프레임 지연 없이 복구할 수 있습니다 – 이는 템포럴 그래디언트가 프리패스로 계산되기 때문이며, 분산 클램핑으로는 언더샘플링 시 신호가 너무 희박해져 불가능했을 것입니다.
로드 밸런서가 이것을 하나로 묶어줍니다 – 예산을 초과하지 않고 고정된 수의 광선을 쏠 수 있게 하며, 화면에 아무 일도 없으면 평균 광선 비율을 자동으로 올려(즉 이미지 품질을 개선) 줍니다.
이렇게 해서 우리는 일관된 성능 오버헤드와 일관된 품질을 달성합니다 – 디노이징의 최악 시나리오 기준을 크게 끌어올렸습니다.

VRRT는 최소한의 오버헤드를 유지하면서 고전적인 화면 공간 디노이징을 개선합니다 – 일정한 고정 비용이 있지만, 이는 쉽게 본전을 뽑으며, 광선 비율을 조금 낮추는 것만으로 이 비용을 쉽게 회수할 수 있습니다(이제 사실상 실수 슬라이더이기 때문입니다). VRRT가 아닌 디노이징의 오버헤드에 비하면 VRRT의 추가 비용은 무시할 만합니다.
제 경험상 이것은 언제나 그만한 가치가 있는데, VRRT 없이는 우리 광선 예산의 상당 부분을 아무것도 하지 않는 데 낭비하기 때문입니다.

템포럴 그래디언트가 VRRT에 통합되는 방식에서 제가 개인적으로 가장 마음에 드는 점은 (분산 기반 클램핑에 비해) 더 사람 친화적인 튜닝 값(tunables)입니다. 이제 우리는 수신자와 오클루더의 속성(머티리얼, 지오메트리, 모션)에 관한 게임 내 정보를 활용해, 조명 반응성과 선명함 사이에서 휴리스틱을 튜닝할 수 있습니다. 일반적인 게임플레이 시나리오에서는 더 범용적인 휴리스틱을 원할 수 있지만, 특정 시나리오(예: 컷신을 다듬을 때)를 위해 VRRT를 튜닝할 여지도 여전히 있습니다. 이전에는 디노이징 품질에 관한 어떤 jira 티켓을 받아도 그저 어깨를 으쓱하며 "개선해 볼 수는 있지만 다른 게 깨질 것"이라고 답할 수밖에 없었습니다. 이제는 실제로 새로운 도구가 제 도구함에 생겼습니다.

완전한 VRRT를 Call of Duty 엔진에 마침내 도입하기까지 여러 해가 걸렸지만, 이것은 우리에게 끝이 아니라 시작일 뿐입니다. 앞으로 몇 년에 걸쳐 우리가 하고 싶은 잠재적 연구가 아주 많습니다. 저는 이것이 미래의 RT 중심 엔진 버전에서 품질과 성능을 마지막 한 방울까지 짜내는 데 있어 우리의 주요 격전지가 될 수 있다고 믿습니다. 이것들은 제가 떠오르는 대로 적어둔 몇 가지 아이디어일 뿐입니다! 지금은 다루지 않겠습니다, 또 몇 시간이 걸릴 테니까요.

VRRT가 얼마나 유용한지 여러분을 납득시켰기를, 그리고 이 강연 초반에 제시한 처음의 약속을 완전히 실현했기를 바랍니다. 이것은 고전적인 디노이징 파이프라인의 확장이므로, 여러분의 디노이저를 단계별로 확장하며 차근차근 시작할 수 있습니다. 어떤 순서로 하는 것이 가장 좋은지 제 팁을 적어두었습니다.



Google Slides 로드 중
docs.google.com