TECHARTNOMAD | TECHARTFLOWIO.COM

TECH.ART.FLOW.IO

[발표번역] GDC2024. GLOBAL ILLUMINATION WITH BRIXELIZER SDK UPDATES.

jplee 2024. 8. 10. 19:29

역자의 말. 딱 1년 만에 브릭셀라이저 업데이트 발표가 있었습니다. GDC2023 에서 공개 된 버전에 비해서 많은 업데이트가 있습니다.


저자 : AMD
 

 
 


안녕하세요, AMD 피델리티FX 브릭셀라이저와 함께하는 글로벌 일루미네이션 강연에 오신 것을 환영합니다. 
저는 AMD 게임 엔지니어링 핵심 기술 그룹의 수석 소프트웨어 엔지니어인 디하라 위제퉁가(Dihara Wijetunga)입니다.

먼저 Brixelizer에 대한 간략한 개요와 작동 방식에 대해 설명한 다음 Brixelizer GI를 소개합니다. 그런 다음 알고리즘을 단계별로 살펴보고 몇 가지 실측 비교와 성능 수치를 살펴본 다음 API의 모양과 애플리케이션에 통합되는 방식을 살펴봅니다. 마지막으로 FidelityFX SDK 업데이트로 마무리하겠습니다. 그럼 시작해 보시죠.
 

Brixelizer는 씬에 대한 광선을 효율적으로 추적하기 위해 트라이앵글 지오메트리에 대한 희소 거리 필드를 실시간으로 생성하는 FidelityFX 라이브러리입니다. 정적 및 동적 지오메트리 모두에서 작동하며 거리 필드에 대해 광선을 추적하는 셰이더 API를 제공하며, 향후 출시될 FidelityFX SDK에서 사용할 수 있게 됩니다.

이제 브릭셀라이저의 작동 원리를 간략하게 살펴보겠습니다. 브릭셀라이저는 주어진 위치 주변에 거리 필드의 캐스케이드를 생성합니다. 대부분의 경우 이 위치가 카메라 위치입니다. 각 캐스케이드는 복셀 그리드로, 각 축의 길이는 64복셀입니다.

복셀이 지오메트리와 교차하는 경우 복셀 내에서 로컬 거리 필드가 생성됩니다. 이러한 로컬 거리 필드를 브릭이라고 합니다.

브릭은 R8 UNORM 형식의 8x8x8 크기의 3D 텍스처입니다. 그리고 모든 캐스케이드는 글로벌 브릭 아틀라스 3D 텍스처에서 브릭을 할당합니다. 브릭 내의 텍셀을 브릭셀이라고 합니다.

브릭이 생성되면 각 캐스케이드에 대해 3단계 AABB 트리를 구축합니다.

이 AABB 트리는 레이트레이스 트래버스에 사용됩니다. 트리 레벨에서 시작하여 광선이 교차하는 리프 노드를 찾습니다. 그 지점에서 교차점을 찾을 때까지 거리 필드를 레이마칭하는 방식으로 전환합니다.

지금까지 브릭셀라이저에 대해 간략하게 살펴보았습니다. 이제 브릭셀라이저 위에 구축된 빠르고 근사한 글로벌 조명 솔루션인 브릭셀라이저 GI에 대해 살펴보겠습니다. 이 솔루션은 하드웨어 가속 레이 트레이싱이 필요 없이 전적으로 컴퓨팅에 기반합니다. 저사양 하드웨어에서도 동적 글로벌 조명의 형태를 가질 수 있도록 레이 트레이싱 GI의 폴백을 제공하는 것이 주요 동기입니다.
이는 다음 FidelityFX SDK 릴리스의 일부로 제공될 예정이며 Brixelizer를 보완하는 라이브러리로 제공될 것입니다. 그리고 모든 C++ 및 셰이더 소스는 언제나처럼 MIT 라이선스에 따라 제공됩니다. Brixelizer GI의 높은 수준의 아이디어는 애플리케이션의 G 버퍼뿐만 아니라 Brixelizer의 출력 리소스를 가져와 최종 셰이딩 출력에 합성할 수 있는 확산 및 스페큘러 GI 출력을 제공한다는 점입니다.
 

다음은 직접 조명만 출력한 스크린샷과 Brix GI를 통해 간접 조명을 추가한 스크린샷입니다.

다음은 몇 가지 스크린샷입니다.

스폰자의 필수 스크린샷은 다음과 같습니다.

따라서 Brixelizer GI는 캡사이신 프레임워크와 함께 제공되는 AMD의 GI 1.0 알고리즘을 훨씬 더 단순화한 구현입니다. 마찬가지로 화면 공간 프로브도 사용하며, 이는 월드 스페이스 방사 및 조도 캐시에 의해 뒷받침됩니다.

알고리즘을 간단히 살펴보겠습니다. 여기서 G-버퍼 표면의 단면과 해당 지오메트리를 둘러싼 복셀 그리드를 볼 수 있습니다. 실제 지오메트리를 포함하는 복셀은 녹색으로 강조 표시됩니다. 먼저 복사 캐시를 채우는 것으로 시작합니다. 각 1차 광선 히트 포인트에 해당하는 브릭을 찾아 이전 프레임의 직접 조명을 재투사하여 복사 캐시에 주입합니다.
먼저 G-버퍼 표면에 스크린 프로브를 스폰합니다. 그런 다음 스크린 프로브에서 확산 광선을 추적하고 셰이딩을 위해 방사 캐시를 샘플링합니다. 그런 다음 방금 업데이트한 스크린 프로브를 사용하여 월드 스페이스 방사 캐시를 공급합니다. 그 후 G-버퍼에서 정반사 광선을 추적하고 다시 셰이딩을 위해 방사 캐시에서 샘플링합니다. 마지막으로 스크린 프로브와 방사 캐시를 사용하여 확산 GI를 해결합니다.

다음은 동일한 알고리즘이지만 더 자세한 설명입니다. 많은 내용을 다루고 있지만 단계별로 살펴보겠습니다. 그 전에 여기에 관련된 다양한 데이터 구조를 살펴보겠습니다.

스크린 프로브를 사용하는 이유는 무엇입니까? 기존 GI 프로브의 일반적인 문제는 빛이 새는 것입니다. 벽으로 분리된 두 개의 방을 예로 들어 보겠습니다. 왼쪽은 빨간색 광원을 사용하여 조명이 켜져 있고 오른쪽은 완전히 비어 있습니다.
여기 오른쪽에 표시된 위치를 음영 처리하면 주변의 프로브를 사용하여 일부 프로브가 조명이 있는 쪽에 있음을 알 수 있습니다. 따라서 프로브를 보간하면 왼쪽의 빨간색 빛 중 일부가 오른쪽으로 누출됩니다. 프로브를 더 똑똑하게 배치하면 어느 정도 완화할 수 있지만 완전히 해결할 수 있는 것은 아닙니다.
그러나 DDGI 알고리즘은 기본적으로 각 프로브에서 깊이 맵을 사용하고 샘플링 중에 이를 평가하여 이 문제를 어느 정도 해결합니다. 그러나 스크린 프로브는 깊이 버퍼의 보이는 표면에만 프로브를 배치하여 이 문제를 완전히 회피합니다. 이 시나리오를 예로 들어 보겠습니다. 스크린 프로브를 사용하여 이 지점을 음영 처리하면 상단 프로브는 너무 멀어서 무시할 수 있으며 간단한 깊이와 정규 비교를 사용하여 프로브 기여도를 평가할 수 있습니다. 또한 특히 보고 있는 표면에 가까운 경우 월드 공간 프로브 격자보다 더 밀집되어 있다는 장점도 있습니다.

화면 프로브는 다음과 같이 8x8 팔면체 인코딩을 사용하여 표시됩니다.


 

하지만 화면 프로브가 있다면 왜 월드 스페이스 조도 캐시가 있을까요? 화면 프로브는 반응성이 좋지만, 프로브가 처음부터 축적을 다시 시작해야 하므로 장애가 발생하면 노이즈가 발생할 수 있으며, 이로 인해 아티팩트가 끓는 현상이 발생할 수 있습니다.
반면 월드 스페이스 캐시는 더 거칠지만 더 안정적이고 지속적이므로 화면 프로브가 실패할 때마다 이상적인 대안이 됩니다. 이는 2차 구형 고조파로 저장되므로 컬러 채널당 9개의 계수가 저장되며 모든 브릭셀라이저 캐스케이드에 공통으로 사용되는 하나의 큰 버퍼에 저장됩니다.

마지막으로 래디언스 캐시를 사용하는 이유는 무엇일까요? 몇 가지 이유가 있지만, 주로 원거리 필드에 있는 머티리얼 데이터와 UV에 액세스할 수 없기 때문에 브릭셀라이저로 트레이스할 때 히트 포인트를 셰이딩할 수 없기 때문입니다. 또한 통합 프로세스가 크게 간소화됩니다. 최신 게임 엔진에는 다양한 유형의 광원, 머티리얼 및 셰이딩 모델이 있습니다. 이를 모두 노출하는 것은 어려운 일입니다.
광원 캐시를 사용하면 셰이딩은 애플리케이션이 처리하도록 맡기고, 브릭셀라이저에서는 그 결과를 캐시하여 필요할 때마다 조회할 수 있습니다. 이는 축당 크기가 256인 R11G11B10 형식의 3D 텍스처 아틀라스로 저장됩니다. 그리고 광원 캐시 내부의 브릭은 4x4x4 픽셀로, 브릭의 볼륨 전체에 광원을 나타내므로 브릭셀라이저의 절반 크기로 제공됩니다.

이제 알고리즘을 자세히 살펴보겠습니다. 먼저 광원 캐시 채우기부터 시작하겠습니다. 이 패스에서는 각 기본 광선의 광원으로 광원 캐시를 채웁니다. 이전 프레임의 직접 조명 출력을 사용하여 이 작업을 수행합니다. 모든 픽셀에 대해 이 작업을 수행하는 대신 1/4 해상도에서 수행하므로 각 4x4 타일에 하나의 값을 주입합니다.

타일 내에서 임의의 지점을 선택한 다음 제공된 모션 벡터를 사용하여 마지막 프레임의 직사광선을 재투영합니다. 그런 다음 월드 스페이스 위치를 재구성하고 각 캐스케이드에서 해당 위치에 해당하는 브릭을 찾습니다. 그런 다음 브릭 내에서 UVW 좌표를 계산합니다. 마지막으로 재투영된 광원을 UVW 좌표의 광원 캐시에 축적합니다. 다음은 광원 캐시를 직접 샘플링했을 때의 모습을 시각화한 결과물입니다.

다음으로 새로운 화면 프로브를 생성합니다.

화면 프로브는 내부적으로 8x8 팔면체 투영 매핑으로 저장됩니다. 그리고 프레임의 각 8x8 타일마다 프로브가 스폰됩니다. 그리고 프로브 스폰을 최대 8번 시도합니다. 각 시도는 해머슬리 저불일치 시퀀스를 사용하여 지터링됩니다. 이 지터링된 좌표를 사용하여 깊이 버퍼를 샘플링하고 하늘이나 배경 픽셀에 속하지 않는 경우 이를 받아들입니다.
그런 다음 빈 프로브로 초기화하고 재구성된 월드 스페이스 위치에 프로브를 스폰하고 프로브 정보를 버퍼에 저장합니다. 여기에는 깊이 값, 월드 스페이스 노멀, 랜덤 시드 등의 정보가 포함됩니다. 이 정보를 사용하여 나중에 파이프라인에서 샘플 방향뿐만 아니라 프로브 위치를 재구성할 수 있습니다.

새 화면 프로브를 만든 후, 이제 지난 프레임에서 열심히 작업한 부분을 재사용하여 이전 프로브를 다시 투영해 보겠습니다.


 

여기서는 지난 프레임의 프로브를 재투영하여 현재 프레임의 프로브에서 그 빛을 재사용할 수 있도록 합니다. 프로브당 8x8 스레드를 파견하고 각 스레드는 단일 픽셀을 처리하여 재투영 후보를 찾으려고 합니다. 재투영 가중치를 공유 메모리에 저장하고 가중치가 가장 높은 프로브를 재사용할 프로브로 선택합니다. 여기에서 재투영된 화면 프로브를 볼 수 있습니다. 재투영 실패한 프로브에 해당하는 구멍이 보입니다. 그리고 자세히 살펴볼 수 있습니다.

또한 재투영된 프로브를 둘러싼 프로브의 조도를 공유하고 정상 및 위치 유사성을 사용하여 기여도를 평가합니다. 이제 파이프라인을 따라 이동하여 스크린 프로브에서 일부 광선을 추적하고 새로운 조도 데이터를 추가할 차례입니다.

 

새로 생성된 프로브가 지난 프레임의 프로브를 재사용하지 못하면 새로운 광원을 주입합니다. 각 프로브 픽셀에 대해 반구를 균일하게 샘플링하고 Brixelizer를 사용하여 광선을 추적합니다. 광선이 맞으면 브릭 ID와 UVW 좌표를 사용하여 광원 캐시를 샘플링하고, 광선을 놓치면 그냥 환경 맵을 샘플링합니다.

이제 다음 패스에서는 스페큘러 GI 측면을 다뤄보겠습니다.

먼저 1/4 해상도로 광선을 추적하고 히트 포인트에 브릭 ID를 저장합니다. 광원 캐시의 세분성은 브릭 수준이므로 저해상도 추적은 품질에 큰 영향을 주지 않고 추적되는 광선 수를 크게 줄입니다. 다음으로 별도의 전체 해상도 디스패치에서 브릭 ID를 로드하고 브릭 내에서 교차점을 찾습니다. 이는 광선-행진으로 직접 이동할 수 있으므로 전체 추적보다 저렴합니다. 마지막으로 브릭 ID와 UVW 좌표를 사용하여 광원 캐시 샘플링을 수행합니다.

다음으로 마지막 프레임의 디퓨즈 및 스페큘러 GI 출력을 재투영하여 누적할 준비를 하겠습니다.

여기서는 제공된 모션 벡터를 사용하여 이전 디퓨즈 및 스페큘러 GI 출력을 현재 프레임에 간단히 재투영합니다. 내부적으로 현재 및 이전 프레임의 뎁스 버퍼와 G 버퍼 노멀을 사용하여 디소클루전 마스크를 만듭니다. 디소클루전이 있는 경우 0보다 큰 값을 저장하여 히스토리를 거부합니다. 재투영된 출력은 다음과 같습니다. 프레임 간 움직임이 과장되었지만 히스토리에서 거부된 부분이 검은색으로 표시되어 있는 것을 확인할 수 있습니다.


 

이제 화면 프로브가 채워졌으므로 조도 캐시에 공급할 준비를 하겠습니다.
 

여기서는 스크린 프로브에서 64개의 수신 조도 값을 구형 고조파로 투영하고 이를 사용하여 조도 캐시를 공급하고 나중에 최종 확산 GI 출력을 재구성합니다. 프로브당 8x8 스레드 그룹을 파견하고 조도를 2 차 구형 고조파로 투영하고 이를 중간 버퍼에 저장합니다.

각 스레드는 스크린 프로브의 해당 텍셀의 복사 값을 로드하고 광선 방향을 재구성합니다. 그런 다음 복사 값을 SH 계수에 투영하고 공유 메모리에 저장합니다. 마지막으로 공유 메모리에서 병렬 감소를 수행하여 64개의 복사 값을 모두 결합합니다. 이는 각 활성 스레드가 3개의 인접 복사 값을 결합하여 세 번의 반복을 통해 수행됩니다. 첫 번째 반복은 각 스레드 간 간격이 2인 4x4 스레드를 사용합니다.

두 번째 반복은 보폭이 4인 2x2 스레드를 사용합니다.

그리고 마지막 반복은 나머지 세 개의 값을 수집하는 단일 스레드를 사용합니다.


이제 화면 프로브는 조도 캐시에 쉽게 축적할 수 있는 형식이 되었습니다.

이전에 생성한 SH 프로브를 사용하여 월드 스페이스 조도 캐시에 공급합니다. 각 스레드는 단일 SH 프로브에 로드됩니다. 그런 다음 각 브릭셀라이저 캐스케이드에 대해 프로브가 교차하는 브릭을 찾습니다. 그런 다음 월드 스페이스 조도 캐시에서 스크린 프로브와 SH 프로브를 블렌딩합니다.


이제 조도 캐시가 새로운 조도 데이터로 업데이트되었으므로 이 데이터 중 일부를 전파해 보겠습니다.

따라서 이 패스에서는 각 브릭의 구형 고조파 프로브의 조도를 인접 브릭으로 전파합니다. 이는 시간 분할 업데이트이므로 프레임당 하나의 캐스케이드를 업데이트하고 가장 세부적인 캐스케이드가 더 자주 업데이트됩니다.

이제 보간 화면 프로브 패스에서 모든 것을 통합합니다.


여기서는 가장 가까운 2x2 SH 스크린 프로브를 G-버퍼 노멀에 투영하여 화면 공간 조도를 재구성합니다. 또한 주변 8개의 월드 프로브를 보간하여 월드 공간 조도를 재구성합니다. 마지막으로 이들을 혼합하여 최종 조도 값을 얻습니다.

동일한 패스에서 이전에 리젝트된 디퓨즈 및 스페큘러 GI 출력을 일시적으로 누적합니다.

이제 공간 노이즈 제거 패스로 마무리합니다.

이것은 비교적 간단한 양방향 블러로 GI 출력의 노이즈를 더 제거합니다. 반경은 샘플 수에 따라 결정되므로 샘플 수가 적을수록 더 큰 반경을 사용합니다.


알고리즘의 마지막 세부 사항은 광도 및 조도 캐시가 지워지는 방식입니다. 브릭셀라이저의 캐스케이드는 클립 맵으로 구현되며 카메라가 움직이면 브릭이 무효화됩니다. 이를 보완하기 위해 무효화된 브릭과 관련된 캐시 항목을 지우고 브릭셀라이저 내부 버퍼에 의존합니다. 따라서 각 브릭셀라이저 GI 업데이트가 시작될 때 간접 파견을 사용하여 관련 광도 및 복사도 캐시 항목을 삭제합니다. 이것으로 알고리즘에 대해 살펴보겠습니다.

이제 실측 데이터와 비교하여 Brixelizer GI의 성능을 살펴봅시다. 왼쪽에는 Brixelizer GI가, 오른쪽에는 빠른 DXR 경로 추적기가 있습니다. 보시다시피, 지면에서 발생하는 간접 확산 반사를 매우 잘 포착합니다.

하지만 여기에서는 작은 규모의 세부 사항 중 일부는 사실 그대로 유지되지 않는 것을 볼 수 있습니다.

다음은 몇 가지 더 비교한 내용입니다.


보시다시피, 대략적인 사실에 잘 근접합니다.


이제 어떻게 작동하는지 알았으니 성능을 살펴보겠습니다. 화면 프로브에서 작동하는 패스는 해상도에 따라 다르며, 방사 및 조도 캐시를 업데이트하는 패스는 주로 복셀 크기에 따라 장면에 따라 다릅니다. 디퓨즈 GI는 본질적으로 저주파이므로 내부적으로 기본적으로 절반 해상도 또는 0.5배 스케일로 출력하지만 0으로 출력하도록 옵션으로 설정할 수 있습니다.75배 스케일 또는 기본 해상도로 출력할 수 있습니다. Radeon RX 7900 XTX에서는 4K 해상도에서 약 2밀리초가 걸리고, GeForce RTX 4080에서는 4K 해상도에서 약 2.2밀리초가 걸립니다. 더 흥미로운 결과는 1080p 게이밍 카드인 RX 7600 XT에서 1080p 해상도에서 약 1.7밀리초가 걸린다는 것입니다. 따라서 저사양 하드웨어에서 실행 가능한 동적 GI 솔루션이 될 수 있습니다.
 
 

메모리 사용량과 관련하여 Brixelizer는 내부 리소스에 약 16메가바이트의 VRAM이 필요하고, SDF 텍스처 아틀라스에는 약 128메가바이트, 필요한 각 캐스케이드에는 약 1메가바이트가 필요합니다. 업데이트를 위해 스크래치 버퍼도 필요하지만 이는 장면의 복잡도에 따라 달라지며 제공된 함수를 사용하여 크기를 쿼리할 수 있습니다.
반면에 브릭셀라이저 GI는 해상도에 따라 달라지며, 이 표를 통해 각 스케일링 설정에서 얼마나 많은 VRAM이 필요한지 알 수 있습니다. 0.5배율인 기본 설정에서는 1080p에서 약 110메가바이트, 1440p에서 130메가바이트, 4K에서 200메가바이트가 소요됩니다.

따라서 브릭셀라이저 GI에는 몇 가지 제한 사항이 있습니다. 화면 공간 정보를 사용하여 광원 캐시를 채우는 방식은 표면을 한 번 이상 봐야만 바운스 조명이 색을 입힐 수 있습니다. 그 후에는 캐시된 광원이 지속됩니다. 그러나 광원 캐시가 업데이트될 수 있도록 조명을 변경하는 것도 시야에 있을 때만 적용됩니다. 추가 뷰를 사용하여 광원 캐시에 더 많은 광원 데이터를 주입함으로써 이러한 문제를 어느 정도 완화할 수 있습니다.
예를 들어 애플리케이션에 동적으로 업데이트되는 리플렉션 프로브가 있는 경우 이를 사용하여 플레이어 주변의 최신 광원으로 광원 캐시를 채울 수 있습니다. 또는 드로콜을 더 많이 사용할 수 있다면 더 간단한 LOD와 셰이딩을 사용하여 뷰에서 벗어난 장면의 일부를 1/4 해상도로 그릴 수 있습니다. 다른 문제는 화면 프로브의 희소성으로 인해 일부 소규모 디테일이 손실된다는 것입니다. 하지만 스크린 스페이스 앰비언트 오클루전 또는 스크린 스페이스 GI를 사용하여 이러한 디테일 대부분을 복구할 수 있습니다.


이제 Brixelizer GI API와 애플리케이션에 통합하는 방법을 살펴보겠습니다. Brixelizer GI를 사용하려면 기존 Brixelizer 통합이 필요하므로 선택한 API에 대한 FidelityFX 백엔드 및 Brixelizer 컨텍스트를 생성해야 합니다. 애플리케이션을 Brixelizer GI 라이브러리에 연결하고 ffx_brixelizer_gi.h 헤더를 포함합니다. 그런 다음 필요한 플래그(이 경우 반전 깊이)를 전달하여 Brixelizer GI 컨텍스트를 생성합니다. 그리고 필요한 품질 설정, 출력 해상도, 백엔드 인터페이스 등을 지정합니다.

브릭셀라이저 GI 컴퓨팅을 디스패치하기 위해 워크로드는 먼저 디스패치 설명 구조를 브릭셀라이저 컨텍스트, 브릭셀라이저 출력 리소스인 SDF 텍스처 아틀라스 및 브릭 AABB, 브릭 맵, AABB 트리용 버퍼로 채우는 것으로 시작됩니다.

그런 다음 현재 및 이전 프레임의 뎁스 및 월드 스페이스 노멀 버퍼, 모션 벡터, 러프니스가 포함된 G 버퍼 렌더 타깃인 필수 G 버퍼 리소스를 할당합니다. 컨텍스트 생성 시 플래그로 샘플링할 컬러 채널을 지정할 수 있습니다. 또한 이전 프레임의 셰이딩 출력과 레이 미스에서 샘플링할 환경 맵을 제공해야 합니다. 마지막으로 디퓨즈 및 스페큘러 GI 출력을 저장할 두 개의 출력 리소스를 제공합니다.

그런 다음 카메라 행렬과 시작 및 종료 캐스케이드 인덱스와 같은 Brixelizer에 필요한 상수를 전달할 수 있습니다. 마지막으로 컨텍스트, 디스패치 설명 및 명령 목록을 사용하여 ffxBrixelizerGIDispatch를 호출할 수 있습니다.


업데이트 후에는 이미지 기반 라이팅과 동일한 방식으로 디퓨즈 및 스페큘러 GI 출력을 에픽의 분할합 근사치에 연결하여 다이렉트 라이팅 출력에 합성합니다.


이제 이전 프레임의 직접 조명만 사용하면 하나의 바운스 디퓨즈 GI를 얻을 수 있습니다. 하지만 멀티 바운스 GI를 원한다면 이전 프레임의 합성된 출력을 Brixelizer GI에 입력으로 사용하여 피드백 루프를 만들 수 있습니다. 여기에서 단일 바운스의 광원 캐시 및 디퓨즈 GI 출력의 모습을 볼 수 있습니다. 그리고 다음은 멀티 바운스의 모습입니다. 디퓨즈 GI 출력에서는 차이가 미묘하지만 간접 조명이 있는 특정 장면에서 도움이 될 수 있습니다.

여기에서 볼 수 있듯이 월드 스페이스 광원 및 조도 캐시를 검사하는 데 사용할 수 있는 디버그 시각화 모드(옵션)도 있습니다.
 

업데이트를 시작하면 브릭셀라이저 컨텍스트, 깊이 버퍼, G 버퍼 노멀, 카메라 매트릭스, 출력 리소스를 할당합니다. 또한 사용할 디버그 모드를 복사 캐시 또는 조도 캐시 중 선택합니다. 그리고 이 디스패치는 선택한 정보를 지정된 출력 리소스에 직접 출력합니다.

이제 Brixelizer GI가 실제로 작동하는 라이브 데모를 살펴보겠습니다. 다음은 Sponza 씬을 실행하는 Brixelizer GI 샘플입니다. 현재 GI가 켜져 있습니다. 다음은 GI를 껐을 때의 모습입니다. 보시다시피 대부분의 씬이 그림자 속에 있습니다.
GI를 다시 켜면 그림자가 있던 부분이 간접광으로 채워지는 것을 볼 수 있습니다. 다음은 디퓨즈 GI 자체입니다. 다음은 스페큘러 GI입니다. 다음은 래디언스 캐시입니다. 멀티 바운스 GI를 끄면 이전에 2차 바운스를 사용하여 조명하던 영역이 완전히 그림자가 되는 것을 볼 수 있습니다.
카메라가 돌아감에 따라 광원 캐시는 이 새로운 광원 데이터로 업데이트됩니다. 멀티 바운스를 다시 켜면 이전 프레임의 합성된 셰이딩 출력, 즉 디퓨즈 GI 및 스페큘러 GI 출력과 합성된 최종 셰이딩 출력을 다음 프레임의 브릭셀라이저에 공급하는 피드백 루프가 생성되어 광원 캐시에 2차 바운스를 추가합니다. 빛의 방향을 바꾸면 GI도 함께 변경되는 것을 알 수 있습니다. 여기서 GI를 더 잘 볼 수 있습니다. 디퓨즈 GI를 사용하면 이 기둥의 커튼에서 나오는 바운스 조명을 볼 수 있습니다.
 

이것으로 브리셀라이저 GI에 대한 강연을 마칩니다. 이제 곧 출시될 FidelityFX SDK 버전 1.1에 대해 살펴보겠습니다.
 

이번 릴리스에서 가장 크게 추가된 두 가지 기능은 Brixelizer 및 Brixelizer GI 라이브러리입니다. 또한 사용법을 보여주는 DirectX 12 및 벌칸 샘플이 함께 제공됩니다. 또한 정적 및 동적 장면 요소를 처리하는 방법과 다양한 디버그 뷰 및 디버그 카운터를 사용하여 이를 애플리케이션에 통합하는 방법도 보여 줍니다.


또 다른 새로운 라이브러리는 FidelityFX 브레드크럼입니다. 최신 명시적 그래픽 API를 사용하면 API의 잘못된 사용으로 인해 GPU 충돌이 발생하기 쉽습니다. 이러한 경우 운영 체제는 시간 초과 감지 또는 TDR을 통해 GPU를 다시 시작하여 모든 GPU 프로세스가 종료됩니다. 이러한 종류의 문제를 디버깅하는 것은 특히 수백 개의 드로 콜과 파견이 있는 복잡한 렌더러에서 상당히 어렵습니다.
이 새로운 라이브러리는 개발자가 해당 GPU 워크로드가 실행되기 전후에 발생하는 특수 버퍼에 대한 쓰기라는 기술을 사용하여 이러한 GPU 충돌을 디버깅할 수 있도록 지원합니다. 장치가 손실되면 이러한 빵가루를 덤프하여 충돌 시점에 어떤 명령이 완료되었고 어떤 명령이 실행 중이었는지 확인할 수 있습니다. 이렇게 하면 이러한 문제를 진단하는 데 걸리는 시간을 줄이는 데 도움이 됩니다. 이번 릴리스에는 이동 경로를 사용하는 방법을 보여주는 DirectX 12 및 Vulkan 샘플도 포함되어 있습니다.

그렇다면 이것이 Radeon GPU Detective 및 DRED와 어떻게 다른지 궁금할 수 있습니다. Radeon GPU Detective는 Radeon 개발자 도구 제품군의 일부로, Radeon GPU에서 작동하며 드라이버에 직접 연결되므로 게임 코드를 변경할 필요가 없습니다. 반면에 브레드크럼 및 DRED는 공급업체에 구애받지 않으며 DX 12의 쓰기 버퍼 중간 기능을 사용하여 구현됩니다. 그러나 DRED의 경우 세분성을 제어할 수 없습니다. 따라서 모든 API 호출에 대해 쓰기를 삽입합니다. 또한 이러한 쓰기에 대한 이름을 지정할 수도 없습니다. 하지만 브레드크럼 라이브러리를 사용하면 ffxBreadcrumbsBeginMarker 및 ffxBreadcrumbsEndMarker API를 사용하여 패스당 또는 드로우당 등 필요에 맞는 세분성 수준을 선택할 수 있습니다. 기존 프로파일러 마커에 연결하고 필요할 때 활성화하면 쉽게 통합할 수 있습니다.

이 외에도 FSR 및 하이브리드 리플렉션 샘플이 개선되었으며, 가마솥 프레임워크의 모든 샘플에 걸쳐 다양한 수정 및 개선이 이루어졌습니다. 또한 데스크톱과 Xbox 시리즈 콘솔을 모두 지원하는 새로운 GDK 백엔드도 SDK에 포함되어 있습니다.

Xbox 개발자는 Xbox 시리즈를 지원하는 버전을 사용할 수 있게 되어 기쁘게 생각합니다. 마지막으로 FidelityFX SDK 1.1은 가까운 시일 내에 GDC 이후에 출시될 예정입니다.

결론적으로 브리셀라이저 GI는 저사양 플랫폼에서 레이 트레이싱 글로벌 조명을 위한 대체 라이브러리입니다. G-버퍼와 직접 조명을 입력으로 받아 디퓨즈 및 스페큘러 GI를 출력합니다. 하드웨어 가속 레이 트레이싱 지원이 필요하지 않으며 DirectX 12와 벌칸 모두에서 작동합니다. 또한 MIT 라이선스를 통해 완전히 오픈 소스이며 FidelityFX SDK 버전 1.1에서 사용할 수 있습니다. 마지막으로 필요한 경우 고급 GI 솔루션의 기반이 될 수도 있습니다.
 

Brixelizer GI와 FidelityFX SDK에 기여해 주신 AMD의 이 분들께 특별히 감사드립니다.
 

이상으로 강연을 마칩니다. 자세한 내용은 GPUOpen 웹사이트에서 확인하시기 바랍니다. 감사합니다.