TECHARTNOMAD | MAZELINE.TECH

TECH.ART.FLOW.IO

[번역] REAC2025《오버워치 2》의 GI 솔루션

jplee 2026. 2. 9. 18:23

역자의 말: 곧 구정입니다. 구정이 지나면 이 추위가 좀 누그러질까요? 정말 춥네요.

REAC 2025는 《오버워치 2》의 글로벌 일루미네이션(GI) 시스템 업그레이드에 초점을 맞춘 기술 회의 또는 내부 기술 공유 활동의 코드명입니다. 이 용어는 본문에서 2025년 팀이 게임의 확산형 글로벌 일루미네이션 방식을 업데이트하는 작업을 가리키며, 대체 방안 평가부터 생산 배포까지의 전체 프로세스를 포괄합니다. REAC는 “Rendering Evolution and Architecture Conference”(렌더링 진화 및 아키텍처 컨퍼런스)의 약자로, 해당 기술 이터레이션 과정을 조직하거나 기록하는 데 사용될 수 있습니다. 문맥상 이 행사는 기존 GI 방식을 현대적 방법으로 업그레이드하면서도 기존 맵과의 호환성을 유지하는 데 초점을 맞추며, 순수 코드 개발보다는 프로세스 관리와 리스크 통제에 중점을 둡니다.

REAC 2025 Evolving Global Illumination in Overwatch 2.

개요 및 소개

  • 《오버워치 2》는 경쟁형 1인칭 팀 기반 슈팅 게임으로, 다양한 영웅과 전 세계 각지의 맵을 보유
  • 각 맵은 낮, 밤, 황혼, 새벽 등 다양한 라이팅 시나리오를 지원
  • 본 발표는 디퓨즈 GI 솔루션을 현대적 방법으로 업데이트한 경험과 프로세스에 초점
  • 발표 내용: 대안 평가, 프로토타입 설계, 데이터 수집, 리스크 감소, 프로덕션 배포
  • 현재 전체 GI 교체 여정의 중간 단계에 위치

《오버워치 2》는 경쟁형 1인칭 팀 기반 슈팅 게임으로, 다수의 고유한 영웅 라인업과 전 세계 각지의 다양한 맵을 보유하고 있습니다. 각 맵은 낮, 밤, 황혼, 새벽 등 다양한 라이팅 시나리오를 가질 수 있습니다. 본 발표에서는 기존 솔루션을 유지하면서 《오버워치 2》의 디퓨즈 글로벌 일루미네이션 솔루션을 보다 현대적인 방식으로 업데이트한 과정을 소개합니다. 코드 중심의 발표가 아니라, 그 과정에서 사용한 경험과 프로세스에 초점을 맞추고 있습니다. 평가한 대안, 프로토타입 아이디어, 주요 리스크를 낮추기 위한 유의미한 데이터 수집, 그리고 최종적으로 프로덕션에 투입한 과정을 다룹니다. 성공과 도전에 대해 이야기하고, 앞으로의 로드맵과 남은 과제를 전망합니다. 주목할 점은, 현재 보고 계신 것이 전체 GI 교체 여정의 중간 단계라는 것입니다.

현재 GI 솔루션: Enlighten

  • 솔루션이 여러 맵에서 라이브 중이나, 기능이 아직 완전히 완성되지 않음
  • Enlighten은 정적 지오메트리에 베이크 라이트맵, 동적 오브젝트에 베이크 프로브 제공
  • 새 GI 솔루션 평가의 주요 이유: 아티스트 워크플로우 및 이터레이션 시간 개선
  • 주요 페인 포인트: 긴 라이팅 베이크 시간, 라이팅 타겟 메시 생성 부담

본 발표에서 소개하는 솔루션은 이미 여러 맵에서 출시되었지만, 기능 완성이라 부르기까지 아직 할 일이 남아 있습니다. 현재 GI 솔루션은 Enlighten이라는 도구를 사용합니다. Enlighten은 정적 지오메트리에는 베이크 라이트맵, 동적 오브젝트에는 베이크 프로브를 제공합니다. 다른 GI 솔루션을 평가하기로 결정한 주요 이유 중 하나는 아티스트의 워크플로우와 이터레이션 시간을 개선하기 위함이었습니다. Enlighten이 일반적으로 매우 좋은 최종 결과를 내지만, 긴 라이팅 베이크 시간과 라이팅 타겟 메시 생성은 아티스트에게 부담이 되었습니다.

Target Mesh (타겟 메시)

  • Target mesh는 아티스트가 Maya에서 수작업으로 제작하는 간소화된 메시로, Enlighten 베이크 입력으로 사용
  • 아티스트에게 추가적인 시간과 노력 부담
  • Target Mesh의 장점:
    • 더 적은 라이트맵 UV 아일랜드를 생성하여 라이팅 이음새와 메모리 사용량 감소
    • 아티스트가 라이트맵 이음새 위치를 제어 가능
    • 베이커에 전송되는 폴리곤이 적어 베이크 턴어라운드가 빠름

Target mesh는 아티스트가 Maya에서 수작업으로 제작해야 하는 추가 메시 유형으로, 렌더 메시의 간소화된 버전입니다. 이는 아티스트에게 추가적인 시간과 노력 부담을 줍니다. 이 슬라이드에서 왼쪽은 렌더 메시 지오메트리(게임 내 실제 모습)이고, 오른쪽은 타겟 메시 지오메트리를 보여주는 디버그 뷰입니다. 이 지오메트리가 Enlighten 베이크 프로세스의 입력으로 사용됩니다.

Enlighten은 소스 메시를 입력으로 사용할 수 있지만, 타겟 메시를 선택하는 데는 몇 가지 충분한 이유가 있습니다. 첫째, 타겟 메시는 자동 및 랩 솔루션보다 더 적은 라이트맵 UV 아일랜드를 생성하여 라이팅 이음새가 적고 라이트맵 메모리도 적게 필요합니다. 둘째, 타겟 메시는 아티스트가 라이트맵 이음새 위치를 제어할 수 있게 합니다. 또한 베이커에 전송되는 전체 폴리곤이 적어 베이크 턴어라운드 시간이 빨라집니다.

Enlighten 작동 원리

  • 정적 지오메트리를 "클러스터(clusters)"라는 작은 표면 패치로 분해
  • 각 클러스터에 "더스터(dusters)"라는 랜덤 포인트를 포함하여 직접 라이팅 계산
  • 클러스터 간 가시성과 에너지 전달 비율 계산
  • 데이터를 최적화된 런타임 포맷으로 변환
  • 단점: 정적 지오메트리 업데이트 시 재실행 필요, 시간이 오래 걸림
  • 장점: 런타임 평가 속도가 빠름

Enlighten은 씬의 정적 지오메트리를 "클러스터"라 불리는 작은 표면 패치로 분해하여 작동합니다. 각 클러스터는 표면을 따라 "더스터"라 불리는 랜덤 포인트를 포함하며, 이를 통해 해당 클러스터의 직접 라이팅을 계산합니다. 그런 다음 Enlighten은 각 클러스터 간의 가시성을 계산하고, 에너지가 한 클러스터에서 다른 클러스터로 직접 전달될 수 있는 비율을 결정합니다. 이 모든 데이터는 최종적으로 최적화된 런타임 포맷으로 변환됩니다. 이는 시간이 오래 걸리는 프로세스로, 정적 지오메트리가 업데이트될 때마다 재실행해야 합니다. 하지만 그 대가로 런타임 평가 속도가 매우 빠릅니다.

이 슬라이드의 이미지는 왼쪽에 클러스터만의 디버그 뷰, 오른쪽에 더스터가 포함된 클러스터를 보여줍니다.

왼쪽에서는 씬의 Enlighten 클러스터 데이터를 보여주는 디버그 뷰를 볼 수 있습니다. 오른쪽에서는 클러스터가 렌더 메시 지오메트리와 함께 그려집니다. 나무나 대형 입구처럼 많은 오브젝트가 크게 간소화되었고, 조각상처럼 아예 표현되지 않는 오브젝트도 있음에 주목하세요.

평가한 대안

1. Target Mesh 프로세스 개선

  • 타겟 메시 프로세스 자동화 방법 탐색
  • AI 그룹과 협력하여 렌더 메시에서 타겟 메시 자동 생성 시도
  • 결과: 훈련 데이터 부족, 생성된 메시 품질이 Enlighten 베이크 요구사항을 충족하지 못함

아티스트 워크플로우를 개선하는 첫 번째이자 가장 명백한 방법은 타겟 메시 솔루션을 개선할 수 있는지 살펴보는 것이었습니다. 프로세스 자동화를 위한 다양한 방법을 탐색했습니다. 팀의 다른 멤버가 AI 그룹과 협력하여 렌더 메시에서 타겟 메시를 자동 생성할 수 있는지 살펴보았습니다. 하지만 당시에는 사용 가능한 결과를 얻기에 충분한 훈련 데이터가 없었습니다. 생성된 메시의 품질이 Enlighten이 정확하게 베이크할 수 있는 입력을 제공하기에 충분하지 않았습니다.

2. SDF(Signed Distance Field) 솔루션

  • 조사한 솔루션: UE5의 Lumen, Godot 4의 SDFGI
  • 장점: 설득력 있는 최종 결과 제공
  • 단점:
    • 기존 파이프라인에 통합하기 어려움
    • 품질 대비 성능 트레이드오프 불확실
    • 개발 리소스 제한(엔지니어 1명, 제한된 시간)
    • 연구 시간 부족

SDF(Signed Distance Field) 기반 솔루션도 조사했습니다. 언리얼 엔진 5의 Lumen과 Godot 4의 SDFGI가 그 예입니다. 이러한 솔루션은 설득력 있는 최종 결과를 제공하지만, 기존 파이프라인에 통합하기에는 다소 복잡해 보였고, 보이는 품질 대비 성능 트레이드오프에도 확신이 서지 않았습니다. 개발 리소스가 제한적이어서 한 명의 엔지니어가 제한된 시간 내에 이 작업을 수행하고 있었기에, 충분한 연구 시간 확보도 어려웠습니다.

3. DDGI (Dynamic Diffuse Global Illumination)

  • Nvidia RTXGI에 포함된 DDGI
  • 라이팅과 가시성 데이터를 포함하는 프로브 기반 솔루션
  • 장점: 기존 프로브 GI의 라이트 리킹 문제 완화에 도움
  • 단점: 플랫폼 지원 제한
    • 완전 동적 DDGI는 하드웨어 레이 트레이싱 지원 필요
    • 컴퓨트 셰이더 폴백 방식도 저사양 플랫폼에서는 비현실적
  • 결론: 큰 가능성을 보았고, 최종적으로 현재 솔루션으로 이끌어줌

매우 흥미로웠던 또 다른 솔루션은 Nvidia RTXGI에 포함된 DDGI였습니다. 이는 라이팅과 가시성 데이터를 포함하는 프로브 기반 솔루션으로, 기존 프로브 기반 GI 구현에서 발생하는 라이트 리킹 문제를 완화하는 데 도움이 됩니다. 가장 큰 단점은 플랫폼 지원이었습니다. 완전 동적 DDGI를 사용하려면 하드웨어 레이 트레이싱 지원이 필요하거나, 최소한 폴백으로 컴퓨트 셰이더에서 알고리즘을 실행할 수 있어야 합니다. 안타깝게도 컴퓨트 셰이더 폴백 방식조차 우리가 지원하는 일부 저사양 플랫폼에서는 현실적이지 않았습니다. 하지만 기성품 구현을 사용할 수 없었음에도 큰 가능성을 보았고, 이것이 최종적으로 현재 솔루션으로 이끌어주었습니다.

우리의 솔루션: 사전 베이크 DDGI

DDGI 알고리즘 개요

  • DDGI를 새 솔루션의 기반으로 사용하되, 런타임이 아닌 도구에서 사전에 텍스처를 베이크
  • 핵심 아이디어: 월드 스페이스에서 균일 간격의 3D 프로브 그리드
  • 각 프로브 위치에서 래디언스와 가시성 데이터를 캡처하여 두 개의 별도 텍스처에 저장
  • GI 평가 시 쿼리 포인트를 둘러싼 8개 프로브를 샘플링하고 보간
  • 가시성 항과 추가 가중치 항을 결합하여 지오메트리를 통한 라이트 리킹 감소

DDGI를 새 솔루션의 기반으로 사용하기로 결정했습니다. 런타임에 알고리즘을 실행하는 대신, 도구에서 사전에 텍스처를 베이크합니다. 핵심 아이디어는 월드 스페이스에서 균일 간격의 3D 프로브 그리드를 사용하는 것입니다. 각 프로브 위치에서 래디언스와 가시성 데이터를 캡처한 후 두 개의 별도 텍스처에 저장합니다. GI 평가 시 쿼리 포인트를 둘러싼 8개 프로브를 샘플링하고 보간하여 최종 라이팅 값을 얻습니다. 각 프로브에 연관된 가시성 항은 여러 추가 가중치 항과 결합되어 지오메트리를 통한 라이트 리킹을 완화합니다.

GI 볼륨 배치

  • 아티스트가 수동으로 GI 볼륨을 배치하고 각 축별 프로브 밀도 설정 가능
  • 공간에서 볼륨 방향을 조정하여 좁은 복도, 계단실의 라이트 리킹 문제 완화
  • 수동 배치를 통해 메모리 사용량과 라이팅 디테일 간의 트레이드오프 제어

맵이 주로 정적이므로 아티스트가 수동으로 GI 볼륨을 배치하고 필요에 따라 각 축의 프로브 밀도를 설정할 수 있습니다. 공간에서 볼륨의 방향도 조정할 수 있어 좁은 복도, 계단실 등의 라이트 리킹 및 유사 문제를 더욱 완화할 수 있습니다. 수동으로 볼륨을 배치하고 프로브 밀도를 설정할 수 있어 추가 디테일이 필요한 영역을 제어하는 여러 수단을 제공합니다. 이는 메모리 사용량과 라이팅 디테일 간의 트레이드오프를 제공합니다.

볼륨 계층 구조

  • GI 볼륨 계층 구조 지원, 부모 볼륨 안에 여러 자식 볼륨 중첩 가능
  • 캡처 시 자식 볼륨의 마지막 한 줄 프로브를 부모 볼륨 프로브로 블렌딩
  • 고디테일과 저디테일 영역 사이에 더 부드러운 그라데이션 제공

아티스트가 GI 볼륨의 계층 구조를 구축하여 큰 부모 볼륨 안에 여러 자식 볼륨을 중첩할 수 있습니다. 캡처 과정에서 자식 볼륨의 마지막 한 줄 프로브를 부모 볼륨의 둘러싸는 프로브로 블렌딩하여 고디테일과 저디테일 영역 사이에 더 부드러운 그라데이션을 제공합니다.

텍스처 포맷 및 저장

  • 각 볼륨에 대해 BC6 압축 텍스처 한 쌍 생성 (래디언스 + 가시성)
  • BC5 대신 BC6 선택: 블록당 16바이트, 16비트 정밀도 부동소수점 값 지원, 양자화 로직 간소화
  • 옥타히드럴 매핑으로 평탄화된 프로브 저장
  • 프로브는 2D 텍스처 배열에 저장, 각 슬라이스는 XZ 평면 하나를 나타냄

각 볼륨에 대해 BC6 압축 텍스처 한 쌍을 생성합니다. 하나는 래디언스용, 하나는 가시성용입니다. BC5를 가시성에 사용해보기도 했지만, BC6는 블록당 16바이트로 동일한 점유량이면서 16비트 정밀도 부동소수점 값을 지원하여 많은 양자화 로직을 간소화할 수 있었기에 합리적인 선택이었습니다. 원래 구현과 마찬가지로 옥타히드럴 매핑을 사용하여 평탄화된 프로브를 저장합니다. 프로브는 2D 텍스처 배열에 저장되며, 각 슬라이스는 XZ 평면의 프로브를 나타냅니다.

메모리 관리

  • 맵당 여러 볼륨이 있으므로 텍스처 메모리 사용량을 면밀히 주시
  • 보고 도구 구축 완료, 아티스트가 점유량을 직관적으로 파악할 수 있는 추가 도구 계획
  • 플랫폼 또는 그래픽 설정에 따라 특정 볼륨을 완전히 생략할 수 있는 LOD 시스템

맵당 여러 볼륨이 있을 수 있고, 각 볼륨이 자체 텍스처 세트를 생성하므로 텍스처 메모리 사용량을 면밀히 주시하는 것이 중요합니다. 이를 돕기 위한 보고 도구를 이미 구축했으며, 아티스트가 작업 중 전체 점유량을 더 직관적으로 파악할 수 있는 추가 도구도 계획하고 있습니다. 플랫폼이나 플레이어의 그래픽 설정에 따라 특정 볼륨을 완전히 생략할 수 있는 기본적인 LOD 시스템도 구축했습니다.

기존 Enlighten 데이터 활용

  • 기존 Enlighten 베이크에서 생성된 클러스터 데이터를 활용하여 빠르게 시작
  • Embree를 사용하여 Enlighten 클러스터 메시에 CPU 레이 트레이싱 수행으로 래디언스와 가시성 획득
  • 자체 맨테리얼 및 라이팅 데이터를 CPU에서 샘플링하는 작업을 우회
  • 영구적 솔루션은 아니지만 대량의 작업을 개발 후반으로 미루는 데 도움

빠르게 시작하기 위해 이미 사용 가능한 데이터를 활용하기로 했습니다. 이는 기존 Enlighten 베이크가 이미 생성한 데이터를 활용하는 것입니다. 구체적으로, Enlighten이 빌드 과정에서 출력하는 클러스터 데이터를 래디언스 문제 해결에 사용합니다. Embree를 사용하여 Enlighten 클러스터 메시에 대해 CPU 레이 트레이싱을 수행하여 래디언스와 가시성을 획득합니다. 이를 통해 자체 맨테리얼 및 라이팅 데이터를 CPU에서 샘플링하고 평가할 준비를 하는 작업을 우회할 수 있었습니다. 물론 영구적인 솔루션은 아니지만, 대량의 작업을 개발 파이프라인 후반으로 미루고 매우 빠르게 레이 트레이싱을 시작하고 사용 가능한 데이터를 캡처할 수 있었습니다.

DDGI 선택 이유

확장성

  • 《오버워치 2》는 극히 넓은 플랫폼 범위에서 실행: 최고사양 PC부터 10년 이상된 구형 하드웨어까지
  • DDGI 장점: 예측 가능한 메모리 점유량과 런타임 성능 비용
  • 저사양 플랫폼에서는 GI 볼륨을 완전히 생략하여 메모리 점유량 감소 가능

《오버워치 2》는 극히 넓은 범위의 플랫폼과 하드웨어 사양에서 실행됩니다. 최고사양 PC부터 현재 10년 이상된 하드웨어까지 지원합니다. DDGI의 예측 가능한 메모리 점유량과, 마찬가지로 중요한 예측 가능한 런타임 성능 비용이 경쟁 솔루션 중에서 돋보이게 해주었습니다. 또한 저사양 플랫폼에서는 텍스처 메모리를 줄여야 할 경우 GI 볼륨을 완전히 생략할 수도 있습니다.

아티스트에게 익숙한 워크플로우

  • 아티스트가 이미 배치 가능한 볼륨 워크플로우에 익숙 (리플렉션 프로브, 포그 볼륨)
  • DDGI는 세밀하게 조정된 컨벡스 볼륨 방식에 비해 아티스트 개입이 적음
  • 단일 볼륨으로 실내와 실외를 모두 커버 가능, 라이트 리킹 걱정이 적음

우리 솔루션의 또 다른 장점은 아티스트에게 이미 익숙한 워크플로우를 제공한다는 것입니다. 리플렉션 프로브나 포그 볼륨 등에서 이미 배치 가능한 볼륨 기반 워크플로우를 사용하고 있어 GI 볼륨을 맵에 추가할 때 크게 다를 것이 없습니다. 사실 이는 DDGI가 기존 프로브 기반 솔루션(세밀하게 조정된 컨벡스 볼륨 등)과 차별화되는 또 다른 요소입니다. 타겟 메시에서 보았듯이, 대량의 추가 아티스트 개입을 줄이고자 했습니다. 실내와 실외 모두를 커버하면서 라이트 리킹도 크게 걱정하지 않아도 되는 볼륨을 맵에 추가할 수 있다는 점이 DDGI를 매우 매력적으로 만들었습니다.

사전 베이크 방식의 장점

  • 맵이 정적 라이팅을 사용하므로 다양한 라이팅 시나리오에 대해 데이터를 사전 베이크 가능
  • 맵 로딩 시 활성 시간대에 필요한 데이터만 선택
  • 복잡한 간접 라이팅 업데이트 로직 불필요, 룩업 연산으로 귀결
  • 참고: DDGI는 실제로 16회 텍스처 샘플링 필요 (래디언스 8회 + 가시성 8회)

선택한 솔루션의 또 다른 장점은 사전 베이크 방식이 여전히 유리하다는 것입니다. 매치가 시작된 후 맵이 주로 정적 라이팅을 사용하므로, 각 맵의 다양한 라이팅 시나리오에 대해 모든 데이터를 사전 베이크한 다음 맵 로딩 시 활성 시간대에 필요한 데이터만 선택할 수 있습니다. 이는 간접 라이팅에 대한 복잡한 업데이트 및 평가 로직이 필요 없고, 단순한 룩업으로 귀결될 수 있음을 의미합니다. 물론 여기에 별표가 있는데, DDGI 알고리즘은 실제로 16회 텍스처 샘플링이 필요합니다(래디언스 프로브 8회, 가시성 프로브 8회). 따라서 단순 룩업보다는 무겁지만, 인덱싱 로직은 상당히 직관적이고 이해하기 쉽습니다.

초기 효과 비교

  • Enlighten과 DDGI의 효과 비교
  • 동적 오브젝트(이동 가능한 배럴 등): 이전에는 벽/바닥에 매몰된 프로브에서 잘못된 라이팅을 받아 씬과 부조화
  • DDGI는 대부분의 오브젝트에 대해 픽셀별 라이팅 평가 가능, 결과가 더 일관적
  • 타겟 메시 데이터로 인한 라이트맵 이음새 문제 해결

Enlighten 결과와 DDGI 결과의 초기 비교 이미지를 간략히 살펴보겠습니다. 이 씬에서 모서리의 배럴은 동적 오브젝트입니다. 넘어뜨리거나 씬에서 이동시킬 수 있으므로 프로브 라이팅을 사용합니다. 이전 솔루션에서는 이 오브젝트들이 벽과 바닥에 매몰된 프로브에서 잘못된 라이팅 정보를 받고 있었습니다. 배럴이 씬의 나머지 부분과 매우 부조화스럽게 보이는 것을 확인할 수 있습니다.

새 솔루션으로 대부분의 오브젝트에 대해 픽셀별 라이팅 평가가 가능합니다. 오른쪽 이미지의 배럴이 이제 씬의 나머지 부분과 조화를 이루는 것을 볼 수 있습니다. 다음 이미지는 나쁜 타겟 메시 데이터로 인해 아티스트에게 많은 문제를 일으킨 특정 에셋을 보여줍니다. 쓰러진 나무 줄기 하단 근처에 라이트맵 이음새로 인한 눈에 띄는 이상한 그라데이션이 있습니다. 줄기 자체도 주변 라이팅 환경보다 약간 어두워 보입니다. DDGI에서는 모든 것이 동일한 방식으로 평가됩니다. 걱정할 라이트맵이 없으므로 지오메트리에 이상한 띠를 만드는 이음새도 없습니다. 모든 것이 훨씬 더 일관적이 됩니다.

실험과 프로토타입 설계

전체 접근 방식

  • 구상, 실험, 솔루션 적합성 검증 프로세스 심층 탐구
  • 저사양 하드웨어(10년 이상) 도전에 직면
  • 모든 플랫폼에서 실행해야 함

이제 구상, 실험, 그리고 실제적인 관점에서 이 솔루션이 우리에게 정말 적합한지 판단하는 프로세스를 더 깊이 살펴보겠습니다. 이 과정에서 직면한 저사양 하드웨어 관련 과제도 논의합니다. 앞서 언급했듯이 10년 이상된 하드웨어를 지원하고 있어, 모든 플랫폼에서 실행시키려면 상당한 작업이 필요하다는 것을 알고 있었습니다.

상위 수준 방법론

  • 연구 단계에서 DDGI 기반 접근 방식 확정
  • 조기에 제한 사항 확정: 추가 메모리 및 프레임 시간 예산
  • 실용적 태도가 중요: 새 기술의 비용은 제로가 될 수 없음

이 슬라이드는 새 GI 솔루션을 게임에 도입하기 위한 상위 수준 접근 방식을 다룹니다. 연구 단계와 DDGI 기반 접근 방식에 도달한 과정은 이미 논의했습니다. 조기에 제한 사항을 정하는 것도 중요했습니다. 새 기술에 감당할 수 있는 추가 메모리와 프레임 시간을 파악하고 합의하면, 프로토타입 설계와 데이터 수집을 시작할 때 정직함을 유지하는 데 도움이 됩니다. 여기서 실용적 태도가 중요합니다. "새롭고 개선된 것을 만들어라, 그런데 시간은 전혀 들면 안 된다"라고 말하기는 어렵습니다.

초기 프로토타입

  • 목표: 가능한 빨리 무언가를 실행시키는 것
  • 런타임 평가 부분에 우선 집중하여 런타임 성능 비용 파악
  • 초기 설정: 맵 1개, GI 볼륨 1개, 고정 프로브 밀도(32×8×32)
  • 초기 래디언스는 가장 가까운 Enlighten 프로브 8개를 선형 보간(실제 레이 트레이싱 아님)
  • 실제 가시성 트레이싱 수행(오클루전 테스트가 라이팅 평가보다 간단)
  • 주의: 핵 솔루션은 기술 부채를 발생시킴

초기 프로토타입의 목표는 가능한 빨리 무언가를 실행시키는 것이었습니다. 주로 기술의 실시간 평가 부분에 진입하여 다른 것에 너무 많은 시간을 쓰기 전에 런타임 성능 비용을 파악하고자 했습니다. 초기 프로토타입 설정으로 맵 하나에 GI 볼륨 하나를 선택했습니다.

해당 볼륨은 X, Y, Z 축 각각 32×8×32 프로브의 고정 밀도를 사용했으며, 특정 맵의 특정 위치를 중심으로 하드코딩되었습니다. 또한 이 기회를 활용하여 필요한 데이터를 캡처하고, 그 데이터를 라이팅 파이프라인에 적용하여 올바르게 보이는지 확인했습니다. 실제로 초기 구현에서는 래디언스를 캡처하기 위한 실제 레이 트레이싱조차 하지 않았습니다. 대신 이미 사용 가능한 가장 가까운 Enlighten 프로브 8개를 사용하여 선형 보간으로 프로브에 라이팅 정보를 부여했습니다. 다시 한번 강조하지만, 여기서의 주요 목표는 가능한 빨리 대표적인 무언가를 실행시키는 것이었습니다. 가시성 트레이싱은 실제로 수행했는데, 오클루전 테스트가 라이팅 평가보다 훨씬 간단하기 때문입니다. 화면에 무언가를 표시하기 위해 라이트 버퍼의 내용을 덮어쓰고, 첫 번째 결과가 이 슬라이드에서 보이는 것입니다. 이는 프로토타입 설계 목적으로 매우 좋았으며, 이제 초기 데이터를 수집할 수 있게 되었습니다. 하지만 주의할 점이 있습니다. 이런 식의 핵 솔루션을 프로젝트에 넣을 때는 조심하세요. 기술 부채 수금원이 결국 문을 두드릴 것입니다.

DDGI 캡처 출력

  • 출력 텍스처는 옥타히드럴 매핑 사용, 각 사각형이 프로브 하나의 데이터
  • 래디언스 캡처 해상도: 6×6 (테두리 포함 시 8×8 픽셀/프로브)
  • 가시성 캡처 해상도: 14×14 (테두리 포함 시 16×16 픽셀/프로브)
  • 1픽셀 테두리는 바이리니어 필터링용
  • 가시성 해상도 낮추면 품질 저하가 과도함

이 슬라이드는 첫 번째 성공적인 DDGI 캡처의 출력 텍스처를 보여줍니다. DDGI와 옥타히드럴 매핑에 익숙한 분들에게는 상당히 표준적으로 보일 것입니다. 그렇지 않은 분들에게는 알아보기 어려울 수 있지만, 기본적으로 각 텍스처의 각 사각형은 프로브의 래디언스 또는 가시성 데이터를 나타냅니다. 래디언스는 6×6 해상도로, 가시성은 14×14 해상도로 캡처합니다. 각 프로브에 바이리니어 필터링을 위한 1픽셀 테두리가 있으므로, 래디언스 프로브당 점유량은 8×8 픽셀, 가시성 프로브는 16×16입니다. 가시성 해상도를 낮추는 실험도 했지만, 다른 연구자들이 이미 발견한 것처럼 품질이 너무 빠르게 저하되어 사용할 수 없었습니다.

메모리 계산 검증

  • 데이터 내보내기 후 메모리 계산 가정 검증

데이터를 내보낼 수 있게 되었으므로 일부 가정을 검증할 수 있었습니다. 메모리 계산이 맞다고 상당히 확신했는데, 솔직히 이해하기 쉬운 계산이기 때문입니다. 하지만 가정을 확인하는 것은 항상 좋습니다.

비압축 메모리 점유량

  • 프로브당 비용: 1.5KB (가시성 1KB + 래디언스 512바이트)
  • 32×8×32 프로브 볼륨: 비압축 가시성 8MB + 래디언스 4MB = 총 12MB

비압축 시 각 프로브의 비용은 1.5KB(가시성 1KB, 래디언스 512바이트)여야 합니다. 따라서 32×8×32 프로브 볼륨의 경우 비압축 메모리는 가시성 8MB, 래디언스 4MB로 가정했습니다. 내보낸 데이터에서 이 수치를 빠르게 확인할 수 있었으며, 이는 압축 적용 후 얼마나 절약할 수 있는지 이해하기 위한 기준선을 제공했습니다.

BC6 압축 후 메모리 점유량

  • BC6 압축: 4×4 블록당 16바이트 출력
  • 가시성 프로브: 16×16 픽셀 = 16블록 × 16바이트 = 256바이트/프로브
  • 래디언스 프로브: 8×8 픽셀 = 4블록 × 16바이트 = 64바이트/프로브
  • 32×8×32 프로브 볼륨 압축 후: 가시성 2MB + 래디언스 512KB = 총 2.5MB
  • 비압축 대비 9.5MB 절약 (12MB → 2.5MB)

앞서 언급했듯이 래디언스와 가시성 모두 BC6로 압축합니다. BC6는 4×4 블록당 16바이트를 출력하므로, 프로브가 차지하는 블록 수를 보면 예상 결과를 알 수 있습니다. 가시성 프로브의 경우 프로브당 16×16 픽셀로 16블록이 됩니다. 16블록 × 블록당 16바이트 = 프로브당 256바이트입니다. 래디언스 프로브는 프로브당 8×8 픽셀로 4블록, 따라서 프로브당 64바이트입니다. 동일한 32×8×32 프로브 볼륨의 경우 가시성 텍스처 2MB, 래디언스 텍스처 512KB로 빠르게 검증할 수 있었습니다. 이 값들을 합치면 비압축 텍스처 대비 9.5MB를 절약하여 총 12MB에서 단 2.5MB로 줄었습니다. 분명히 이 수치가 훨씬 수용 가능하며, 특히 맵에 여러 GI 볼륨이 있는 시나리오를 고려하면 더욱 그렇습니다.

초기 성능 측정

  • 테스트 장비: GTX 1080
  • 전체 해상도 DDGI 평가: 약 330마이크로초
  • 반 해상도 평가: 약 115마이크로초
  • 저사양 하드웨어에서 실행하려면 반 해상도 지원 필요

첫 번째 성능 측정을 살펴보겠습니다. 슬라이드의 이미지는 NVIDIA Nsight에서 획득했으며, 캡처에 사용된 GPU는 GTX 1080입니다. 전체 해상도에서 DDGI 평가 패스는 약 330마이크로초가 걸렸습니다. 끔찍하다고 보지는 않았습니다. 처음부터 특히 다양한 밀도의 여러 볼륨을 지원하려면 성능 수치를 조정해야 할 것임을 알고 있었습니다. 또한 일찍이 저사양 하드웨어에서 실행할 기회를 가지려면 반 해상도 버전의 이펙트를 지원해야 할 것이라고 판단했습니다. 동일 하드웨어에서 반 해상도 평가 시 약 115마이크로초를 확인했습니다.

고사양 플랫폼에 대한 자신감

  • 독립 데스크톱 GPU의 초기 수치에 만족
  • 새 기술이 기존 GI 방식을 대체하면 일부 시간 회수 가능
  • 성능 차이 보전에 자신감

독립 데스크톱 GPU에서 데이터를 수집한 초기 테스트의 출발점 수치를 고려할 때, 성능 목표 달성에 대해 상당히 만족스러웠습니다. 이 기술이 기존 GI 솔루션을 대체할 것이므로, 이전 코드가 더 이상 실행할 필요가 없어 라이팅 파이프라인에서 시간을 회수할 수 있다는 것을 알고 있었습니다. 나머지 차이를 맞출 수 있다는 상당한 자신감이 있었습니다.

저사양 플랫폼의 도전

  • Switch 초기 성능: 기존 GI 방식 제거를 고려해도 약 8밀리초 프레임 시간 추가
  • 배경: 10밀리초는 Switch 전체 프레임 예산의 1/3
  • 실현 가능성에 의문을 갖기 시작한 시점
  • "고집스러운 그래픽스 프로그래머"로서 계속 최적화

하지만 저사양 타깃에서 데이터를 수집하기 시작하자 수치가 그리 희망적이지 않았습니다. Switch의 초기 성능 캡처는 정말 난감했습니다. 기존 GI 방식 제거를 고려해도 거의 8밀리초의 프레임 시간 증가를 보았습니다. 물론 성능 회복을 위한 최적화 단계를 계획했지만, 이렇게 큰 격차에서 동일한 수준으로 돌아오는 것은 불가능해 보였습니다. 참고로, 10밀리초는 Switch 전체 프레임 예산의 1/3입니다. 분명히 하자면, 이것은 Switch의 잘못이 아니며 폄하하려는 것도 아닙니다. Switch는 최상위 하드웨어라고 주장한 적이 없습니다. 우리가 이 기술을 추구하기로 선택했으므로, 모든 플랫폼에 정말 적합한지 파악하는 것은 우리의 몰이었습니다. 실현 가능성에 의문을 갖기 시작한 시점이 있다면 바로 이때였습니다. 다행히 우리는 고집스러운 그래픽스 프로그래머로, 언제 포기해야 하는지 모릅니다.

반해상도 평가

  • 반해상도로 낮추면(각 축 절반 = 1/4 픽셀) 격차가 약 3밀리초로 감소
  • 1/4 해상도는 품질 저하가 너무 심해 허용 불가
  • 테스트 위치는 최악의 경우 선택: 모든 픽셀이 간접 조명을 받아야 하는 상황

가장 먼저 하고 가장 명백한 것은 당연히 더 낮은 해상도로 이펙트를 평가하는 것이었습니다. 반해상도로 낮추고 이전 GI 코드를 완전히 대체한 후, 격차가 약 3밀리초로 줄었습니다. 1/4 해상도로 라이팅을 평가하는 것도 조사했지만, 품질이 너무 많이 저하되어 수용할 수 없었습니다. 이제 우리가 직면한 상황을 이해했으므로, 추가 시간을 회복할 방법을 찾기 시작할 수 있었습니다. 참고로, 이 슬라이드의 위치는 모든 성능 데이터를 캡처한 지점을 보여줍니다. 모든 픽셀이 간접 조명을 받아야 하는 표면의 일부인 최악의 시나리오를 대표하기 때문에 선택했습니다.

저사양 플랫폼 최적화

  • 성능 회복을 위한 다양한 최적화 시도
  • 저사양 특화 최적화지만 중고사양 플랫폼에도 부정적 영향 없음

평가 렌더 타겟을 RGBA16 float에서 RG11B10 float 포맷으로 변경

간단한 업데이트로 약간의 시간 회수

평가 렌더 타겟을 RGBA16 float 텍스처 포맷에서 RG11B10 float 포맷으로 변경하는 것은 간단한 업데이트였지만 약간의 시간을 회수하는 데 도움이 되었습니다.

  • 평가 렌더 타겟을 RGBA16 float에서 RG11B10 float 포맷으로 변경
  • 루프 분리 최적화:

가시성과 래디언스 평가를 별도 루프로 분리

Switch 특화 큰 성과 (텍스처 캐시 접근이 이 설정에 더 적합)

  • 다른 플랫폼은 성능 동일, 별도 코드 경로 유지 부담을 피하기 위해 모든 플랫폼에 통일 적용
  • 놀라운 Switch 특화 성능 향상은 가시성과 래디언스 평가를 별도 루프로 분리하여 상당한 성과를 얻은 것입니다. 레퍼런스 구현은 단일 루프에서 두 항목을 평가한 후 최종 래디언스 항을 정규화합니다. 하지만 Switch의 텍스처 캐시 접근은 이 설정에 더 적합한 것으로 보입니다. 다른 플랫폼은 루프 설정 방식에 관계없이 성능이 거의 동일했습니다. 따라서 별도의 코드 경로를 유지해야 하는 부담을 피하기 위해 모든 플랫폼에 활성화했습니다.
  • 다른 플랫폼은 성능 동일, 별도 코드 경로 유지 부담을 피하기 위해 모든 플랫폼에 통일 적용

16비트 타입 최적화:

DDGI 셰이더는 텍스처 페치 제한

  • Switch 셰이더에서 16비트 타입 활성화
  • DDGI 셰이더에서는 제한적 성과 (여전히 텍스처 바운드)
  • 파이프라인의 다른 지점에 신중하게 적용 시 수백 마이크로초 회수 가능
  • 핵심: 16비트 타입은 만능 해결책이 아니며, 적용 위치를 측정하고 이해하는 것이 중요
  • DDGI 셰이더는 여전히 명백하게 텍스처 페치 바운드였고, 해당 셰이더에서 추가 시간을 확보할 옵션이 고갈되기 시작했습니다. Switch 셰이더에서 16비트 타입을 활성화하는 실험을 하기로 결정했습니다. DDGI 셰이더와 일부 다른 셰이더들을 업데이트했습니다. 예를 들어 일부 포스트 프로세싱 이펙트에서 16비트 타입을 계산에 사용하도록 했습니다. DDGI 셰이더에서는 여전히 텍스처 바운드이기 때문에 제한적인 성과만 얻었습니다. 하지만 파이프라인의 특정 다른 지점에 신중하게 적용했을 때 전체적으로 수백 마이크로초를 회수할 수 있었습니다. 여기서 핵심은 16비트 타입을 활성화하는 것이 만능 해결책이 아니며, 어디에 적용하는 것이 합리적인지 측정하고 이해하는 것이 여전히 중요하다는 것입니다.

DDGI 셰이더는 여전히 명백하게 텍스처 페치 바운드였고, 해당 셰이더에서 추가 시간을 확보할 옵션이 고갈되기 시작했습니다. Switch 셰이더에서 16비트 타입을 활성화하는 실험을 하기로 결정했습니다. DDGI 셰이더와 일부 다른 셰이더들을 업데이트했습니다. 예를 들어 일부 포스트 프로세싱 이펙트에서 16비트 타입을 계산에 사용하도록 했습니다. DDGI 셰이더에서는 여전히 텍스처 바운드이기 때문에 제한적인 성과만 얻었습니다. 하지만 파이프라인의 특정 다른 지점에 신중하게 적용했을 때 전체적으로 수백 마이크로초를 회수할 수 있었습니다. 여기서 핵심은 16비트 타입을 활성화하는 것이 만능 해결책이 아니며, 어디에 적용하는 것이 합리적인지 측정하고 이해하는 것이 여전히 중요하다는 것입니다.

프로브 읽기 순서 최적화

  • 레퍼런스 구현은 XYZ 순서로 프로브 처리, 텍스처 배열 슬라이스 간 왕복
  • 최적화: 루프 재정렬, 각 슬라이스의 모든 프로브를 먼저 읽기
  • 각 슬라이스는 수직 스택된 프로브 슬래브, XZ 평면 인접 프로브 먼저 읽은 후 다음 슬라이스로 이동
  • Switch에서 측정 가능한 성과, 대형 텍스처 캐시 플랫폼은 차이 없음

Switch에 도움이 된 또 다른 텍스처 접근 최적화는 프로브 읽기 순서를 약간 업데이트한 것입니다. 레퍼런스 구현은 XYZ 순서로 프로브 기여를 처리하는데, 이는 완전히 합리적이고 가독성이 좋습니다. 하지만 이 설정으로 텍스처에 접근하는 방식은 먼저 X축 인접 프로브를 읽고, 텍스처 배열의 다른 슬라이스로 이동하여 다음 두 프로브를 가져온 후, 원래 슬라이스로 돌아가 Z 인접 프로브를 가져오고, 다시 다른 슬라이스로 돌아가 마지막 두 Z 프로브를 가져옵니다. 텍스처 캐시가 좋다면 괜찮을 수 있습니다. 하지만 Switch의 경우, 루프를 재정렬하여 슬라이스별로 모든 프로브를 먼저 읽도록 하면 텍스처 캐시 히트가 개선되는 것을 발견했습니다. 각 텍스처 배열 슬라이스가 수직으로 쌓인 프로브 슬래브를 나타내므로, XZ 평면의 모든 인접 프로브를 먼저 읽은 다음 다음 슬라이스의 인접 프로브로 이동하여 나머지 프로브를 읽습니다. 대형 텍스처 캐시를 가진 플랫폼에서는 큰 차이나 아무 차이도 보이지 않았지만, Switch에서는 접근 순서를 바꿔 측정 가능한 성과를 얻었습니다.

다중 볼륨 렌더링 통합

  • 앞서 언급한 최적화로 기준선 수준 회복
  • 성능 테스트: 단일 GI 볼륨, GBuffer 전체 뷰(최악의 경우)
  • 도전 과제: 여러 볼륨 렌더링 필요, 당시 각 추가 인스턴스가 거의 선형 비용

앞서 논의한 최적화와 제가 잊어버린 몇 가지 다른 최적화를 통해 마침내 기준선 수준으로 돌아왔습니다. 상기시켜 드리자면, 성능 테스트 설정은 단일 GI 볼륨이었고, 카메라는 GBuffer가 가득 찬 뷰를 캡처하도록 설정하여 최악의 시나리오를 파악할 수 있었습니다. 하지만 필요한 것은 여러 볼륨을 렌더링하는 것이었습니다. 당시 설정 방식으로는 각 추가 인스턴스를 렌더링하는 데 거의 선형적인 비용이 발생할 것 같았습니다.

엔진에 정식 통합

  • 성능 수치가 유리해 정식으로 엔진에 통합하기 좋은 타이밍
  • 추가한 기능: 여러 볼륨 생성/배치, 부모 볼륨 내부에 자식 볼륨 중첩, 캡처 및 볼륨 블렌딩
  • DDGI를 사용하는 맵을 위해 더 명확한 커스텀 라이팅 경로 구성

성능 수치가 유리해 보였고, 다중 볼륨 비용 문제를 해결할 꽤 확실한 아이디어가 있었기 때문에 DDGI 솔루션을 엔진과 도구에 정식으로 통합하기에 좋은 시점이라고 판단했습니다. 이를 위해 여러 볼륨을 생성하고 배치하는 기능, 부모 볼륨 안에 자식 볼륨을 중첩하는 기능, 그리고 도구/데이터 파이프라인에서 캡처와 볼륨 블렌딩을 수행하는 기능을 추가했습니다. 또한 맵이 이러한 새 타입을 인지하도록 만들고, DDGI를 GI 솔루션으로 사용하는 맵을 위한 더 깔끔한 커스텀 라이팅 경로를 만들었습니다.

맵 GI 방식 선택

  • 맵은 "placeable"(배치 오브젝트)로 구성되며, 타입 식별자 정보를 가짐
  • 맵 빌드 시 타입별로 그룹화되고, 로드 시 타입 단위로 배치 처리
  • DDGI 볼륨 존재 여부를 검사해 새/구 렌더 경로를 결정
  • 한 맵은 단 하나의 GI 방식만 사용 (DDGI 또는 라이트맵)

기본 흐름은 다음과 같습니다. 우리의 맵은 "placeable"이라 부르는 것들로 만들어지며, 각 placeable에는 기본적인 타입 식별자 정보가 있습니다. placeable은 맵 빌드 시점에 함께 그룹화되고, 게임에서 맵을 로드할 때는 동일 타입의 오브젝트들을 한 번에 처리할 수 있습니다. 따라서 여기서 필요한 것은 맵에 디퓨즈 GI 볼륨이 존재하는지 여부뿐이었습니다. DDGI 볼륨이 있다면 플래그를 세워 라이팅 과정에서 새로운 렌더 경로를 타도록 하고, 없다면 기존 GI 솔루션 로직은 그대로 유지되어 예상대로 동작합니다. 결국 맵은 둘 중 하나만 지원합니다. DDGI 볼륨이 발견되면 그 맵은 DDGI를 GI 솔루션으로 사용한다고 인지하고, 그렇지 않으면 라이트맵을 계속 사용합니다.

초기 다중 볼륨 렌더링 방식

  • 초기 방식: 큰 것부터 작은 순서로 볼륨 그리기 (자식 볼륨이 부모 볼륨 덮어씀)
  • 뷰 프러스텀 밖의 볼륨 컬링
  • 문제: 대량의 낭비되는 작업과 과도한 오버드로우

해킹 방식을 정리하고 맵에 디퓨즈 GI 볼륨을 추가하는 훨씬 간단한 워크플로우를 갖춘 후, 프로토타이핑으로 돌아갈 수 있었습니다. 맵에 여러 볼륨을 추가하기 시작할 때 무엇을 보게 될지에 대한 가설을 세웠는데, 즉 비용이 각 볼륨의 스크린 스페이스 크기에 따라 다소 선형적일 것이라는 것이었습니다. 맵에 여러 볼륨을 쉽게 추가할 수 있게 되자, 성능에 대한 가정을 빠르게 검증할 수 있었습니다. 물론 뷰 프러스텀 완전히 밖에 있는 볼륨은 컬링했지만, 그 외에는 상당히 순진하거나 솔직히 말해 꽤 어리석은 접근 방식을 사용했습니다 - 큰 것부터 작은 순서로 볼륨을 그리는 것이었습니다. 이렇게 그린 이유는 자식 볼륨이 부모 볼륨 내에 완전히 들어가야 하고, 그 목적이 디테일을 추가하는 것이기 때문입니다. 따라서 항상 자식 볼륨의 내용이 우선하여 평가된 표면의 최종 색상이 되기를 원했습니다. 이렇게 그리는 것은 매우 간단했는데, 자식 볼륨이 GI 렌더 타겟에 이전에 작성된 모든 내용을 그냥 덮어쓸 수 있었기 때문입니다. 하지만 물론, 이것은 엄청난 양의 낭비되는 작업과 오버드로우였습니다.

물론 뷰 프러스텀 바깥에 완전히 있는 볼륨은 컬링했지만, 그 외에는 상당히 순진하거나 솔직히 말해 다소 어리석은 방식으로 큰 것부터 작은 것 순서로 볼륨을 그렸습니다. 자식 볼륨은 부모 볼륨 내부에 완전히 들어가야 하고, 목적이 디테일을 추가하는 것이므로 자식 결과가 항상 최종 색으로 "이겨야" 했기 때문입니다. 또한 이 방식은 구현이 매우 단순했습니다. 자식 볼륨이 이전에 GI 렌더 타겟에 기록된 내용을 그대로 덮어쓰면 되었기 때문입니다. 하지만 당연히 이 방식은 엄청난 낭비 작업과 오버드로우를 유발합니다.

스텐실 테스트 최적화

스텐실 비트로 중복 평가 방지

  • 목표: 작은 볼륨 → 큰 볼륨 순으로 그리되, 각 픽셀은 한 번만 평가
  • 스텐실 비트 2개 사용
    • "current" 비트: 현재 그리는 볼륨이 건드린 픽셀 표시
    • "any" 비트: 어떤 볼륨이든 이미 한 번이라도 그려진 픽셀 표시
  • 스텐실 채우기 패스(Stencil fill pass): 단순 셰이더로 그리기
    • "any" 비트를 스텐실 테스트 (이미 설정되어 있으면 거부)
    • 볼륨 경계 밖 픽셀은 discard
    • 통과한 픽셀에 "current" 비트를 설정
  • 평가 패스(Evaluation pass): 전체 DDGI 평가 셰이더로 그리기
    • "current" 비트를 테스트하여 설정된 픽셀만 처리
    • 통과 픽셀은 "any" 비트를 설정하고 "current" 비트를 클리어
    • 이 패스는 discard를 사용하지 않으므로 early depth-stencil을 강제 적용 가능
  • 결과: 작은 볼륨부터 큰 볼륨 순으로 그리면서도, 픽셀당 최대 1회만(비싼) GI 평가
  • 스텐실 채우기 비용은 매우 저렴
    • 저사양에서도 보통 한 자릿수 마이크로초
    • 고사양에서는 수백 나노초 수준

이상적으로는 모든 볼륨을 반대 순서로(작은 것부터 큰 것) 그리면서, 각 볼륨이 어떤 픽셀을 건드렸는지 표시해두고 픽셀당 한 번만 평가 비용을 지불하는 것이 좋습니다. 매년 “크리스마스에 갖고 싶은 건 스텐실 비트 하나 더”라는 농담을 하는데, 다행히 이 경우 프레임의 이 시점에서 사용되지 않는 특수 목적 예약 비트가 몇 개 있어서 우리가 필요한 만큼을 가져올 수 있었습니다.

우리는 여기서 두 비트를 사용합니다. 하나는 현재 그리는 볼륨("current")을 표시하고, 다른 하나는 지금까지 어떤 볼륨이라도 그려진 적이 있는 픽셀("any")을 표시합니다.

먼저 아주 단순한 픽셀 셰이더로 볼륨을 그립니다. 이 셰이더는 "any" 비트를 스텐실 테스트하여 이미 설정되어 있으면 거부합니다. 픽셀이 볼륨 경계 밖이면 셰이더에서 discard 합니다. 그렇지 않으면 "current" 비트를 설정합니다.

다음으로 전체 평가 셰이더로 볼륨을 그립니다. 이번에는 "current" 비트를 테스트해, 해당 비트가 설정된 픽셀만 통과시킵니다. 스텐실 상태는 통과한 픽셀에 대해 "any" 비트를 설정하고 "current" 비트를 클리어하도록 구성합니다. 또한 이 패스는 discard를 사용하지 않기 때문에, early depth-stencil 셰이더 어트리뷰트를 사용해 조기 스텐실 테스트를 강제할 수 있습니다.

이 변경을 통해 우리가 선호하는 순서(작은 것부터 큰 것)로 볼륨을 그리면서도, 비싼 GI 평가는 픽셀당 최대 한 번만 수행되도록 만들 수 있었습니다. 스텐실 채우기 드로우는 매우 저렴하며, 단일 볼륨에서 관측되던 드로우 시간이 여러 볼륨에 분산되더라도 전체 합이 단일 볼륨 케이스를 넘지 않는다는 것을 검증할 수 있었습니다.

카메라가 볼륨 내부에 있을 때 최적화

  • 카메라가 볼륨 내부에 있으면 스텐실 채우기 패스를 생략 가능
  • 내부에서 그릴 때 깊이 테스트가 박스(볼륨) 바깥 지오메트리를 거부
    • 이는 스텐실 채우기 패스에서 discard로 하던 역할과 동일
  • 이 경우 평가 셰이더로 한 번만 그리되
    • "current" 비트를 찾는 대신 "any" 비트를 테스트 (설정되어 있으면 거부)
    • 통과 픽셀은 기존과 동일하게 "any" 비트를 기록
  • 흥미로운 결과: 실내에서는 첫 번째 볼륨이 스텐실 버퍼를 거의 다 채워버려, 이후 볼륨이 전부 거부되는 상황이 자주 발생

스텐실 볼륨을 그리는 비용이 이미 매우 싸더라도, 가능하다면 낭비 작업은 줄이고 싶었습니다. 그래서 볼륨을 내부에서 그리느냐 외부에서 그리느냐에 따라 다른 깊이 테스트를 사용했습니다. 볼륨 내부에서 그리면 깊이 테스트가 박스 바깥의 지오메트리를 거부하는데, 이것이 바로 스텐실 채우기 패스에서 discard를 사용하던 이유와 같습니다.

따라서 이 경우 스텐실 채우기 패스를 완전히 생략할 수 있습니다. 평가 셰이더로 볼륨을 한 번만 그리되, "current" 비트가 아니라 "any" 비트가 설정되어 있으면 거부하도록 설정합니다(이는 스텐실 채우기 패스에서 사용하던 테스트와 동일합니다). 깊이 및 스텐실 테스트를 통과한 픽셀에 대해서는 기존과 같이 "any" 비트를 기록합니다.

결과적으로 실내에서는 첫 번째 볼륨에서 스텐실 버퍼가 거의 다 채워져, 이후의 다른 볼륨들이 downstream에서 전부 거부되는 경우가 생기기도 합니다.

스텐실 테스트 동작 예시

  • 씬에는 GI 볼륨이 3개 존재
    • 카메라 앞 방 안의 작은 볼륨
    • 대부분의 플레이 공간을 덮는 중간 크기 볼륨
    • 맵과 배경의 나머지를 덮는 더 큰 저밀도(글로벌) 볼륨
  • 빨간 픽셀 = 거부
  • 초록 픽셀 = 통과
  • 볼륨 외부에서 시작하는 경우와 내부에서 시작하는 경우 두 가지를 시연

이미 익숙한 분들도 있겠지만, 스텐실 테스트가 낯선 분들을 위해 실제 동작 예시를 두 가지 간단히 보여드리겠습니다. 이 슬라이드의 씬에는 세 개의 GI 볼륨이 있습니다. 카메라 앞 방 안에 작은 볼륨이 있고, 두 번째 중간 크기 볼륨이 대부분의 플레이 공간을 감싸며, 마지막으로 더 큰 저밀도 볼륨이 맵과 배경의 나머지 영역을 감쌉니다.

이후 슬라이드들에서 볼륨은 단순한 박스로 그려집니다. 빨간 픽셀은 거부, 초록 픽셀은 통과를 의미합니다. 이미지의 보라색 패치는 무시해도 됩니다. 프레임 앞부분의 텍스처를 재사용해 표시한 것일 뿐, 최종 결과에는 들어가지 않습니다.

가장 작은 볼륨의 바깥에서 시작하므로, 해당 볼륨에 대해 스텐실 채우기 패스를 수행합니다. 왼쪽은 깊이 테스트 결과, 오른쪽은 스텐실 테스트 결과입니다. 픽셀이 볼륨 내부가 아니라고 판단되면 셰이더에서 수동으로 discard 한다는 점을 기억하세요. 이 패스는 깊이/스텐실 테스트를 통과한(그리고 discard되지 않은) 픽셀에 "current" 비트를 설정합니다.

다음 이미지는 방 내부에서 실제 GI 평가를 수행할 때 스텐실 테스트를 통과한 픽셀을 보여줍니다. 뒤쪽 출입구는 셰이더 discard 때문에 거부되는 것에 주목하세요.

스텐실 기반 평가 결과

  • 평가 패스는 "current" 비트를 읽고, 해당 비트가 설정된 픽셀만 그린다.
  • 패스 종료 시 "current" 비트는 클리어하고 "any" 비트는 설정한다.
  • 카메라가 큰 볼륨 내부에 있으면 스텐실 채우기 패스를 생략할 수 있다.
  • 방 내부는 스텐실로 제외되고, 방 뒤쪽 영역이 GI 평가를 받는다.
  • 마지막 글로벌 볼륨은 실제로 할 일이 없다. (이미 모두 평가되고 스텐실로 제외됨)

이 패스는 "current" 스텐실 비트를 읽고, 비트가 설정된 곳에서만 그립니다. 또한 패스가 끝날 때 "current" 비트를 클리어하고 "any" 비트를 설정합니다. 다음 볼륨은 충분히 커서 카메라가 그 내부에 있으므로 스텐실 채우기 패스를 건너뛸 수 있습니다. 방 내부는 스텐실로 제외되지만, 방 뒤쪽 영역은 이제 GI 평가를 받게 됩니다. 이 패스는 관련 픽셀에 대해 "any" 비트를 설정합니다. 마지막으로 글로벌 볼륨은 이 시점에서 이미 모든 픽셀이 평가되고 스텐실로 제외되었기 때문에 실제 작업이 없습니다.

볼륨 내부에서 시작하는 경우

  • 카메라가 방 안에 있으면 첫 번째 볼륨의 스텐실 채우기 패스를 생략
  • 깊이 테스트가 볼륨 밖 지오메트리를 거부하므로 출입구 바깥은 무시
  • 다음 볼륨은 남은 작업이 거의 없음
  • 글로벌 볼륨은 완전히 할 일이 없음

또 다른 아주 빠른 예시로, 볼륨 내부에서 시작하면 어떤 일이 일어나는지 보여드리겠습니다. 이전과 같은 뷰에서 카메라만 방 안으로 옮겼습니다. 이번에는 카메라가 첫 번째 볼륨 내부에서 시작하므로 스텐실 채우기 패스를 생략할 수 있습니다. 깊이 테스트가 볼륨 바깥 지오메트리를 거부하기 때문에, 출입구 너머의 모든 것이 무시되는 것을 볼 수 있습니다. 다음 볼륨으로 넘어가면 남은 작업은 거의 없고, 다시 한 번 글로벌 볼륨은 전혀 할 일이 없음을 확인할 수 있습니다.

품질 개선: 업샘플링

  • 고사양 하드웨어: 풀 해상도에서 픽셀 단위로 GI 평가 (품질 우수)
  • 중저사양 하드웨어: 반해상도 평가 후 업샘플링 필요
    • 여기서 "반해상도"는 각 축을 절반으로 낮춘다는 의미이므로, 결과 픽셀 수는 1/4
  • 단순한 바이리니어 업샘플링은 품질이 매우 나쁘고 아티팩트가 심함

모든 플랫폼에서 성능이 유리하게 나오기 시작하면서, 이제 품질 개선에 집중할 시점이었습니다. 고사양에서는 풀 해상도로 픽셀별 GI 평가를 수행해 훌륭한 결과를 얻을 수 있었습니다. 반면 중저사양에서는 반해상도로 평가한 뒤 업샘플링이 필요한데, 단순 바이리니어 업샘플링을 적용하면 결과가 심각하게 깨지고 움직임에서도 불쾌할 정도로 아티팩트가 눈에 띄었습니다. 이 방식은 제품으로 내보낼 수 없었습니다.

업샘플링 접근 방식 탐색

바이리니어 업샘플링:

  • 초기 구현이지만, 최종적으로 대체할 계획이었음
  • 아티팩트가 너무 심해 실사용 불가

바이리니어로 시작했지만, 애초부터 대체될 예정이었습니다.

바이레터럴(양방향) 업샘플링:

  • 깊이 및 표면 정보를 고려하여 바이리니어보다 개선
  • 그래도 아티팩트가 많아 출시 품질에 미달
  • 다중 샘플 기반 확장 버전은 품질이 좋아지지만 비용이 증가

깊이와 표면 정보를 고려하는 바이레터럴 업샘플링으로 업데이트하면 바이리니어보다 눈에 띄게 개선되지만, 여전히 거슬리는 아티팩트가 많아 출시 가능한 수준이라고 보기 어려웠습니다. 주변에서 여러 샘플을 가져와 추론하는 확장 버전도 시도했으나, 품질은 일부 좋아졌지만 여전히 목표 수준에 미치지 못했고, 추가 샘플과 로직 때문에 비용도 훨씬 더 컸습니다.

시간적(Temporal) 접근:

  • 기존 데이터를 활용해 시간에 따라 풀 해상도 이미지를 누적
  • 디퓨즈 간접광은 저주파 특성이 강해 Temporal 기법과 잘 맞음
  • 비싼 평가는 저해상도로 유지하고, 결과를 풀 해상도 누적 텍스처와 결합
  • 샘플 가중치 기준: 깊이 차, 디소클루전(가려짐 해제), 휘도, 화면 공간 이동 거리

우리는 시간적 누적 방식(Temporal)을 파고들기 시작했습니다. 이 방식은 디퓨즈 조명이 본질적으로 저주파 성분이 많아, Temporal에서 흔히 문제가 되는 고스팅 같은 아티팩트가 상대적으로 덜 드러날 것이라고 판단했습니다. 따라서 비싼 GI 평가는 저해상도로 유지하고, 결과를 풀 해상도 누적 텍스처와 결합하도록 했습니다. 새로운 샘플은 깊이 변화, 디소클루전, 휘도, 화면 공간 이동 거리 등 여러 기준에 따라 가중치를 부여했습니다.

동적 오브젝트 처리

  • 문제: Temporal이 특히 필요한 플랫폼에서 모션 벡터를 생성하지 않음
  • 해결: 해당 플랫폼에서는 동적 오브젝트를 구면 조화 함수(SH)로 평가
  • 파티클/이펙트 등에 이미 SH 평가를 구현해 둔 상태라 추가 지원 부담이 크지 않았음
  • 프레임 초반 컴퓨트 셰이더로 오브젝트별 계수(계산 결과)를 미리 계산
  • DDGI 입력을 이용해 계수를 계산하여 조명 결과 일관성 유지
  • 평가 셰이더는 동적 오브젝트 픽셀에서 조기 종료(early-out) 가능

Temporal 방식의 가장 큰 문제는, 그것이 가장 필요한 플랫폼에서 모션 벡터를 생성하지 않는다는 점이었습니다. 이를 해결하기 위해 해당 플랫폼에서는 동적 오브젝트를 구면 조화 함수로 평가하는 방식을 사용했습니다. 프레임 초반에 컴퓨트 셰이더로 동적 오브젝트의 계수를 계산해두고, 라이팅 패스에서 사용할 때 준비된 값을 활용했습니다. 또한 DDGI 입력으로 계수를 계산해 평가 결과의 일관성을 유지했으며, 평가 셰이더에서 동적 오브젝트 픽셀에 대한 추가 조기 종료 포인트도 얻을 수 있었습니다.

Temporal 업샘플링 결과 비교

  • 정적 오브젝트: 카메라 이동으로 모션 벡터를 즉석에서 계산
  • 반해상도 Temporal 업샘플링은 코너 및 깊이 불연속 부근에서도 비교적 잘 유지
  • 바이리니어에서 보이던 아티팩트가 크게 완화
  • 동적 오브젝트(예: 커튼)
    • 풀 해상도: 픽셀별 평가
    • 반해상도: 구면 조화 함수 기반 평가

아래 비교에서는 왼쪽이 풀 해상도 평가 결과이고, 오른쪽이 반해상도 평가 + Temporal 업샘플링 결과입니다. 코너나 깊이 불연속 근처에서도 반해상도 Temporal 업샘플링이 비교적 잘 버티며, 바이리니어에서 보이던 불쾌한 아티팩트가 크게 줄어든 것을 확인할 수 있습니다. 배경의 커튼처럼 동적인 오브젝트는 풀 해상도에서는 픽셀별로 평가되며, 반해상도에서는 구면 조화 함수로 평가됩니다.

풀 해상도 결과와 반해상도 Temporal 업샘플링 결과를 더 크게 확대한 버전입니다.

프로덕션 배포

  • Season 13: 히어로 갤러리 맵(작은 맵, 사용 빈도 높음)에서 고사양 플랫폼 기준 정적 + 동적 오브젝트에 적용
  • Season 14: 전 플랫폼, 전 오브젝트(정적 + 동적)로 확대. 여러 데스매치(자유 난투) 맵 업데이트
  • Season 15: 대형 PvP 맵 적용 (Hanoka, Throne of Anubis)
  • Season 16: Stadium 모드. 신규 9개 맵 전부 DDGI 적용
  • 메모리: DDGI 프로브 메모리는 대체로 기존 프로브 세트보다 낮음. Atlas와 UV를 회수하면 항상 이전 임계값 이하
  • 성능: Switch 실제 페널티 약 1ms, Xbox One 약 0.5ms, 고사양 플랫폼은 거의 무시 가능한 수준

점진적 롤아웃 전략

  • 기존 GI 솔루션을 계속 유지해야 함
  • 대규모 장애를 피하기 위해 새 시스템을 신중하게 단계적으로 적용
  • 《오버워치 2》의 시즌 단위 콘텐츠 모델이 점진적 롤아웃과 잘 맞았음

모든 플랫폼에서 성능과 품질에 대한 자신감이 생기자, 이를 프로덕션에 넣는 방법을 고민하기 시작했습니다. 중요한 점은, 이 여정 내내 기존 GI 솔루션을 계속 유지해야 했다는 것입니다. 영향 범위가 큰 기능을 한 번에 배포해 문제가 터지는 상황을 피하고 싶었기 때문에, 단계적으로 롤아웃하는 현실적인 접근이 필요했습니다. 결과적으로 《오버워치 2》의 시즌 단위 업데이트 방식이 이 작업에 매우 적합했습니다.

Season 13: 히어로 갤러리

  • 첫 적용 맵: 히어로 갤러리(작은 맵, 사용 빈도 높음, 이벤트가 제한적)
  • 원래는 동적 오브젝트만 적용하려 했지만, 고사양 플랫폼에서는 정적 오브젝트에도 적용하기로 결정

새 GI 솔루션이 처음 적용된 맵은 히어로 갤러리였습니다. 처음 계획은 동적 오브젝트만 새로운 GI를 사용하도록 하는 것이었지만, 스스로 목표를 높여서 고사양 플랫폼(현 세대 콘솔 및 PC 고 옵션 이상)에서는 정적 오브젝트에도 적용하기로 했습니다.

Season 14: 전 플랫폼 확대

  • 전 플랫폼, 전 오브젝트(정적 + 동적)에 새 시스템 활성화
  • 더 많은 맵을 새 GI 솔루션으로 업데이트
  • 실제 메모리 수치를 확인하며 추정치 검증

Season 14 업데이트에서는 전 플랫폼에서 정적과 동적을 포함한 모든 오브젝트에 새 시스템을 활성화했습니다. 또한 더 많은 맵이 새 GI를 사용하도록 업데이트했고, 실전 맵을 대상으로 추정치가 충분히 정확한지 실제 수치를 확인하는 단계로 넘어갔습니다.

히어로 갤러리를 첫 대상으로 고른 이유

  • 최대한 많은 외부 변수를 통제하는 "관리 가능한" 롤아웃이 필요
  • 작은 맵이면서 사용 빈도가 높음(스킨/이모트 등 코스메틱 확인 시 로드)
  • 맵 내 이벤트가 제한적이라, 성능/품질 문제 발생 시 영향 범위가 작음

앞서 언급했듯이, 우리는 완전히 새로운 시스템을 가능한 한 통제된 방식으로 배포하고 싶었습니다. 히어로 갤러리는 작은 맵이며 사용 빈도가 높고, 맵 내에서 벌어지는 일이 제한적이어서 예기치 못한 성능 또는 품질 문제를 관찰하기에 표면적이 작았습니다.

메모리 비교

  • 핵심 비교: Enlighten probe set(기존 프로브 세트) vs DDGI probes(신규)
  • 히어로 갤러리에서는 기존 대비 상당한 메모리 절감 달성
  • 기존 Enlighten 프로브 세트 메모리가 0이 아닌 이유
    • 파이프라인에서 누락된 경로가 있을 때를 대비해 소량을 "폴백"으로 유지
  • Atlas(라이트맵) 메모리는 맵이 한 번에 한 기술만 쓰므로 최종적으로 완전히 제거 가능
  • UV 메모리는 라이트맵 UV + 베이크 AO UV의 합인데
    • DDGI 맵에서는 최종적으로 베이크 AO UV만 필요해 사실상 절반으로 감소 가능

이 슬라이드는 이전/이후 메모리 점유량을 보여줍니다. 가장 중요한 항목은 기존 Enlighten 프로브 세트 메모리와 DDGI 프로브 메모리입니다. 히어로 갤러리에서는 비슷한 결과 품질을 유지하면서도 기존 대비 메모리를 크게 줄일 수 있었습니다. 또한 일부 Enlighten 프로브 세트 메모리가 남아 있는 것은, 업데이트가 누락된 경로가 있을 때 완전히 주변광이 사라지는 것을 막기 위한 폴백을 남겨두었기 때문입니다.

아울러 Atlas(라이트맵) 및 UV 메모리도 중요합니다. 맵은 한 번에 하나의 기술만 사용하므로, DDGI 맵에서는 라이트맵 Atlas를 완전히 제거할 수 있습니다. UV는 라이트맵 UV와 베이크 AO UV의 조합인데, 최종적으로는 베이크 AO UV만 로드하도록 바꿀 수 있어 UV 메모리도 크게 줄일 수 있습니다.

Chateau 맵(데스매치)

  • Season 14에서 업데이트된 데스매치 맵 중 하나
  • 히어로 갤러리보다 크고, 지하실을 포함한 더 넓은 실내 공간 보유
  • 실제 매치가 진행되는 맵이라, 혼전 상황에서 성능을 모니터링 가능
  • DDGI 프로브 메모리는 증가하지만, Atlas/UV 회수 전 기준으로도 여전히 이전 프로브 세트보다 낮은 수준

Season 14에서 새 GI로 업데이트한 다음 맵은 데스매치 맵 Chateau였습니다. 히어로 갤러리보다 크고 지하실을 포함해 더 다양한 실내 공간이 있으며, 무엇보다 실제 매치가 이루어져 혼잡한 상황에서 성능을 관찰할 수 있었습니다. 이 맵에서도 DDGI 프로브 메모리는 증가하지만, Atlas와 UV 회수를 고려하기 전 단계에서도 기존 프로브 세트보다 낮게 유지되는 것을 확인했습니다.

더 많은 데스매치 맵 적용

  • 자신감을 얻어 더 많은 데스매치 맵에서 테스트
  • 데스매치 맵은 PvP 맵보다 작지만, 실내/실외/복잡한 라이팅이 혼재
  • 메모리 이점이 다양한 시나리오에서도 유지됨
  • 대부분 기존 프로브 세트와 같거나 더 낮은 수준
  • Atlas/UV 회수까지 포함하면 항상 이전 임계값 이하
  • "기어가기(crawl)"에서 "걷기(walk)" 단계로 넘어간 지점

초기 관측 결과가 좋았기 때문에 Chateau 하나로 끝내지 않고 더 많은 데스매치 맵으로 확장했습니다. 규모는 작지만 실내/실외와 다양한 라이팅 복잡도가 섞여 있어 테스트에 좋았습니다. 전반적으로 메모리 이점이 유지되었고, Atlas 및 UV 회수까지 고려하면 항상 이전 임계값 아래로 내려갔습니다.

Season 15: 대형 PvP 맵

  • Clash 모드 맵 2개 업데이트: Hanoka, Throne of Anubis
  • 일정 수준 이상의 볼륨 수와 밀도를 적용하면, 초기 프로브 세트 메모리를 몇 MB 초과하는 "변곡점"이 존재
  • 하지만 Atlas와 UV를 회수하면 다시 충분히 여유 있는 수준으로 내려감
  • 추가 메모리가 있더라도 맵 전체 라이팅 예산 범위 내

Season 15에는 더 큰 PvP 맵에서 새 GI 솔루션을 본격적으로 시험했습니다. 원하는 디테일/품질을 얻기 위해 볼륨 수와 밀도를 충분히 늘리면, 초기 프로브 세트 메모리를 몇 MB 초과하는 지점이 있었습니다. 그러나 Atlas와 UV 메모리를 회수하면 결과적으로 시작점보다 더 낮은 수준으로 돌아왔고, 추가 메모리가 있더라도 전체 라이팅 예산 내에 머물렀습니다.

프로덕션 성능 데이터

  • Xbox One과 Switch가 성능이 가장 낮은 콘솔 타깃 (PS4 수치는 Xbox One과 매우 유사)
  • Switch는 30fps 목표

이제 프로덕션에서의 성능 수치를 살펴보겠습니다. Xbox One과 Switch부터 보겠습니다. 이들이 가장 낮은 성능의 콘솔이며, PS4도 Xbox One과 비슷한 수준입니다. Switch 수치는 처음 보면 좋아 보이지 않을 수 있지만, Switch는 30fps 목표라는 점이 전제입니다.

성능 요약

  • 아래 수치는 단순히 기존 프레임 타임에 "추가"되는 값이 아님
    • 파이프라인의 다른 부분을 최적화해 시간을 회수했고
    • 새 솔루션이 활성화될 때 기존 GI 평가 코드를 대체함
  • Switch의 실제 페널티: 약 1ms
  • Xbox One의 실제 페널티: 약 0.5ms
  • 고사양 플랫폼에서는 대체로 무시 가능한(노이즈로 볼 수 있는) 수준
  • 최저사양 PC는 대체로 Switch와 Xbox One 사이
  • 고사양 PC 및 현 세대 콘솔은 풀 해상도 픽셀별 평가가 가능해 Temporal 업샘플링을 생략할 수 있음
  • 수치는 최악의 경우(GBuffer가 평가 대상 픽셀로 가득 찬 경우)를 기준으로 측정
    • 하늘/배경 비중이 늘어날수록 수치는 빠르게 감소

전체적으로 우리는 목표한 지점에 만족했습니다. 다시 강조하지만, 이 수치는 기존 프레임에 단순 가산되는 항목이 아니라, 새 솔루션 적용과 함께 기존 GI 코드를 대체하고 파이프라인 다른 지점도 최적화하여 회수한 시간을 포함한 "순 페널티" 관점에서 보는 것이 맞습니다.

또한 고사양 PC 및 현 세대 콘솔에서는 풀 해상도에서 GI를 픽셀별로 평가하므로 Temporal 업샘플링을 완전히 건너뛰고, 사실상 볼륨 렌더링 비용만 지불하면 됩니다. 마지막으로, 이 수치들은 최악 조건을 기준으로 하며, 화면에 하늘과 배경이 많아질수록 평가해야 할 픽셀이 줄어들어 비용도 급격히 내려갑니다.

Season 16: Stadium 모드

  • 몇 개 시즌에 걸친 프로덕션 데이터와 수정 사항을 통해 "뛰기(run)" 단계로 갈 준비가 됨
  • Stadium 모드 출시: 신규 맵 9개
    • 각 맵은 출시 시점부터 여러 시간대(시간대별 라이팅) 지원
  • 목표: 이후 모든 신규 맵을 새 GI(DDGI 기반)로 완전히 전환
  • 결과: Stadium의 모든 맵을 새 DDGI 기반 GI로 출시하는 데 성공

여러 시즌 동안 실제 서비스 환경에서 데이터를 모으고 문제를 해결하면서, 마침내 우리는 "이제는 뛰어도 된다"고 느끼게 됐습니다. 그리고 이 작업을 밀어붙이게 만든 또 하나의 동기가 있었다면, 바로 Season 16에서 신규 모드인 Stadium이 출시된다는 점이었습니다. Stadium은 9개의 신규 맵을 포함했고, 각 맵은 출시 시점부터 여러 시간대를 지원해야 했습니다. 우리는 이 출시를 기점으로 이후 모든 신규 맵이 새 GI 솔루션을 완전히 사용하도록 만들고 싶었습니다. 런타임 구현에 대한 자신감이 있었기 때문에, 목표를 달성해 Stadium 맵 전부를 DDGI 기반 솔루션으로 출시할 수 있었습니다.

여러 시간대에서의 Stadium 맵 스크린샷 모음입니다.

로마/파리 맵과 댐/아레나 맵의 예시입니다.

디버깅 도구

  • 어떤 규모의 복잡한 시스템을 만들든, 디버깅 기능은 매우 중요
  • 예: 디버그 뷰, 지표 리포팅, 값 관측 도구 등
  • 권장: 가능한 한 빨리 만들고, 다른 기능들과 함께 병행 개발
    • "필요해진 뒤" 만들면 이미 늦는 경우가 많음

마무리하기 전에 디버깅 유틸리티에 대해 짧게 이야기하겠습니다. 큰 시스템을 만들 때는, 특정 시점에 시스템 내부에서 무슨 일이 벌어지는지 이해할 수 있는 도구가 반드시 필요합니다. 디버그 뷰, 메트릭 리포팅, 값 관측 등 어떤 형태든 좋습니다. 가능한 한 빨리 만들어 두면, 정말 필요해졌을 때 큰 도움이 됩니다.

디버그 뷰

  • 좌상단: 기본 렌더링 씬
  • 우상단: 앰비언트 라이트 뷰 (DDGI 기여분만 표시)
  • 좌하단: 프로브의 월드 공간 위치를 표시하고, 래디언스 데이터로 색상화
  • 우하단: 프로브의 가시성(visibility) 정보
    • 밝을수록 좋음
    • 어두울수록 나쁨
    • 검정색은 back-face를 너무 많이 본 경우(예: 벽/바닥 내부에 박힌 프로브)

이 슬라이드는 새 GI 솔루션을 위해 초기에 구축한 디버그 뷰의 예시입니다.

레이 트레이싱 디버그 툴

  • Embree 기반 레이 트레이싱 월드(가시성 캡처에 사용)를 시각화
  • 색상 의미
    • 빨강: front-face 히트
    • 파랑: back-face 히트
  • 가시성이 나쁜 프로브를 진단하는 데 매우 유용
  • 사례: 외부 지오메트리가 실내로 잘못 삽입되어 프로브 가시성을 망가뜨리는 문제를 발견
    • 일반 렌더링에서는 back-face 컬링 때문에 보이지 않지만, 프로브는 back-face를 "봄"

이 도구 덕분에 문제 위치를 빠르게 찾아내고, 필요한 부분을 아티스트가 수정할 수 있었습니다.

성공 요약

  • Stadium의 모든 신규 맵을 새 GI(DDGI 기반)로 출시
  • 메모리 사용량은 기존 GI와 같거나 더 낮은 수준
  • 고사양 플랫폼 성능은 매우 우수
  • 저사양 플랫폼도 초기 목표로 설정했던 범위 내
  • 정적/동적 오브젝트 모두에서 일관된 GI 결과 확보
  • 라이트맵 이음새 문제 및 동적 오브젝트 데이터 문제 해소
  • 신규 맵에서는 아티스트가 더 이상 라이팅 타겟 메시를 만들 필요가 없음
  • 베이크 시간은 기존 30분~1시간에서 "수 분" 수준으로 단축(단, 아래에서 다시 언급)

달성한 목표

  • 새 GI 솔루션으로 Stadium 신규 맵 전체 출시
  • 맵 단위 메모리 점유량이 기존과 같거나 더 낮음
  • 고사양 성능 수치는 매우 좋고, 저사양도 목표 범위 안
  • 정적/동적 여부와 관계 없이 일관된 글로벌 일루미네이션 결과
  • 라이트맵 이음새를 더 이상 걱정하지 않아도 되고, 동적 오브젝트가 "나쁜 프로브"에서 잘못된 데이터를 가져오는 문제도 줄어듦

가장 먼저, 우리는 목표했던 대로 Stadium의 모든 신규 맵을 새 GI 솔루션으로 출시했습니다. 지금까지 업데이트된 맵들은 기존 GI 대비 메모리 점유량이 같거나 더 낮습니다. 고사양 플랫폼 성능 수치는 매우 좋았고, 저사양 플랫폼도 시작 단계에서 설정했던 한계 내에 들어왔습니다. 또한 정적/동적 오브젝트 여부와 관계없이 GI 결과가 훨씬 더 일관적이 되었고, 라이트맵 이음새나 잘못된 프로브 후보로 인한 문제를 크게 줄일 수 있었습니다.

아티스트 워크플로우 개선

  • DDGI를 전제로 제작되는 맵에서는
    • 아티스트가 더 이상 지오메트리 렌더 메시와 별도로 라이팅 타겟 메시를 만들 필요가 없음
  • 볼륨 배치 워크플로우는
    • 리플렉션 프로브, 포그 볼륨 등에서 이미 익숙한 방식

워크플로우 측면에서도 여러 개선이 있었습니다. DDGI를 처음부터 사용하는 맵에서는, 아티스트가 더 이상 라이팅 타겟 메시를 만들 필요가 없었습니다. 그리고 볼륨을 배치하는 방식 자체도 기존에 사용하던 시스템(리플렉션 프로브, 포그 볼륨 등)과 유사해 학습 부담이 상대적으로 적었습니다.

베이크 시간 개선(부분적으로)

또 하나의 성과로 "베이크 시간 단축"을 이야기할 수 있지만, 이는 조금 뒤에서 다시 짚어보겠습니다. Enlighten 베이크는 맵 크기, 복잡도, 라이팅 시나리오 수 등에 따라 30분에서 1시간 이상까지 걸릴 수 있었고, 이를 빠르게 하기 위해 여러 머신에 분산 실행했습니다. 반면 DDGI의 베이크는 복잡한 맵에서도 대개 수 분 수준에서 끝났고, 로컬에서 돌릴 수 있을 정도로 빨랐습니다(빌드팜에 보내고 기다리지 않아도 됨).

현재 과제

  • 저사양 성능: 여전히 더 많은 프레임 시간을 확보하기 위해 적극적으로 최적화 중
  • 라이트 리킹(빛샘): 프로브 간격과 얇은 지오메트리 조합에서 발생. 경우에 따라 더 두꺼운 벽/천장/바닥이 필요
  • BC6의 3번째 채널: 가시성 데이터가 2채널을 쓰므로 1채널이 남는데, 추가 데이터를 넣는 실험 중
  • CPU 베이크 시간: CPU 레이 트레이싱 기반이라 여전히 몇 분은 걸림
  • 결과 차이: DDGI는 "표면"이 아니라 "공간"에서 GI를 푸므로, 라이트맵과 다르게 보일 수 있음
  • 디버깅 난이도: 수천 개 프로브 × 프로브당 수천 개 레이로 문제 지점 분리가 어려움
  • 아티스트 워크플로우: 아직 Enlighten 베이크(10~20분)가 필요하고, 실시간 라이팅 프리뷰도 제한적

아직 해결해야 할 과제가 남아 있습니다. 발표 초반에 언급했듯이, 우리는 전체 GI 교체 여정의 "중간"에 있습니다. 가장 먼저는 저사양 성능입니다. 현재 수치에 아주 불만은 없지만, 더 나아질 수 있다고 보고 있으며 계속해서 프레임 시간을 더 회수할 방법을 찾고 있습니다.

DDGI의 고유한 한계

라이트 리킹(빛샘)

DDGI에는 라이트맵에서는 보통 겪지 않던 새로운 문제가 있습니다. 대표적으로, 가시성 데이터를 사용하더라도 일부 영역에서 라이트 리킹이 발생할 수 있습니다. 이는 보통 프로브 간격과 얇은 지오메트리의 조합에서 일어납니다. 모든 케이스를 메모리로 "밀어붙여" 해결할지(더 많은 자식 볼륨) 아니면 어느 정도 타협할지 균형이 필요합니다. 가장 좋은 해법 중 하나는 아티스트와 협업해 벽, 천장, 바닥 등을 더 두껍게 만드는 것입니다.

가시성 데이터의 여분 채널

가시성 데이터가 BC6 텍스처의 앞 두 채널에 저장되기 때문에, 남는 1채널에 어떤 유용한 추가 데이터를 넣을 수 있을지 실험 중입니다.

베이크 시간

CPU에서 레이 트레이싱을 수행하기 때문에 DDGI 프로브 베이크도 여전히 수 분이 걸립니다. 더 개선할 수 있다고 보고 있습니다.

라이트맵과의 결과 차이

DDGI 캡처 결과는 라이트맵 베이크와 다르게 보일 수 있습니다. 이유는 단순합니다. DDGI는 표면을 따라 계산하는 것이 아니라 표면 "주변 공간"에서 GI를 해결하기 때문입니다. 다만 라이트맵도 때로는 잘못될 수 있으므로, 새 방식이 더 "정답"에 가까운데 단지 기존과 다르게 보이는 경우도 있습니다.

디버깅 과제

수천 개의 프로브가 각각 수천 개의 레이를 쏘는 구조라, 특정 문제 지점을 고립시키는 것이 어렵습니다. 앞서 보여준 디버그 도구들 외에도, 개발을 계속하면서 유용한 시각화 도구들을 더 만들고 있습니다.

아티스트 워크플로우 과제

마지막으로, 현재 가장 큰 과제는 아티스트 워크플로우입니다. 일부는 좋아졌지만, 일부는 당장 더 나빠진 상태입니다. 출시 일정 때문에 런타임을 먼저 안정화한 뒤, 제작(Authoring) 측에 같은 수준의 노력을 들일 수밖에 없었습니다. 현재 워크플로우의 가장 큰 단점 두 가지는, 래디언스 데이터를 얻는 방식에서 비롯됩니다.

여전히 Enlighten 베이크가 필요함

아직은 Enlighten의 클러스터 데이터를 사용해 래디언스 레이 트레이싱을 하고 있기 때문에, 아티스트는 먼저 Enlighten 베이크를 수행해 해당 데이터를 만들어야 합니다. 지금은 Enlighten 프로브를 훨씬 적게 굽기 때문에 예전보다 빨라졌지만, 맵에 따라 10~20분이 걸릴 수 있습니다. 즉, 실제 체감 베이크 시간은 아직 우리가 바랐던 만큼 극적으로 줄지 않았습니다.

실시간 프리뷰 불가

또 다른 장벽은, 아티스트가 라이팅 변경의 결과를 "즉시" 보기 어렵고, DDGI 텍스처를 다시 캡처해야만 확인할 수 있다는 점입니다. 이 부분도 개선하고자 합니다.

아티스트(사용자)와의 커뮤니케이션

  • 초기부터 사용자 참여: 프로토타입에 확신이 생기자마자 아티스트 대상 큰 미팅을 진행
  • 직접 보여주기: DDGI 적용 맵의 before/after, 실험 빌드를 제공
  • 솔직하게 공유: 장점뿐 아니라 단점(임시적인 단점 포함)도 함께 공유
  • 피드백 수집: 우선순위 로드맵과 Jira 태스크 보드로 정리
  • 정기 업데이트: 기능 추가 시점마다 점진적으로 공유하고 체크인
  • 직접 협업: 아티스트와 함께 작업하며 적응을 돕고 추가 피드백 수집

이런 큰 기능 전환에서는, 가능한 한 빨리 사용자(아티스트)를 과정에 참여시키는 것이 중요합니다. 프로토타입에 확신이 생기자마자 아티스트들과 큰 미팅을 열어 새 시스템을 소개했습니다. DDGI를 적용한 여러 맵을 보여주고, 전후 비교를 공유했으며, 기능이 켜진 실험 빌드를 제공해 직접 결과를 확인할 수 있게 했습니다.

커뮤니케이션에서 중요했던 점

이 시간에 새 접근이 개선할 수 있는 점들을 이야기하는 것은 물론, 단점(심지어 임시적인 단점까지)도 숨기지 않고 공유했습니다. 이는 1차 피드백을 얻는 좋은 기회가 되었고, 피드백을 반영해 "우선순위가 있는 로드맵"을 만들 수 있었습니다. 남은 작업들은 Jira 태스크로 정리해, 누구나 보드를 보고 현재 진행 상황을 확인할 수 있게 했습니다.

이후에도 기능이 추가될 때마다 정기적으로 업데이트와 점검을 진행했습니다. 또한 아티스트들이 새 워크플로우에 적응하는 동안 함께 작업하며 현재 도구 상태를 이해하도록 돕고, 우리가 미처 생각하지 못한 개선점을 피드백으로 얻었습니다. 워크플로우가 일시적으로 불편해진 상황에서도 아티스트들이 인내해 준 만큼, 최소한 최종 결과물이 정말로 도움이 되도록 만드는 것이 중요했습니다.

미래 계획

  • 아티스트 도구 개선
    • 맵 에디터에서 실시간 라이팅 업데이트(프리뷰) 재활성화
    • Enlighten 데이터 의존을 완전히 제거하고, 자체 머티리얼/데이터로 래디언스를 획득
    • GPU 가속 캡처 탐색 (DX12 백엔드는 베타로 제공 중)
  • 런타임 확장
    • DDGI 데이터를 체적 안개(Volumetric Fog)에 적용해 공간 변화가 있는 안개 조명 구현
    • 성능을 고려해 고사양 전용 기능으로 두고, 저사양은 기존 방식으로 폴백
  • 탐색적 연구
    • 희소(sparse) 볼륨 표현으로 하늘 같은 "변화가 적은 큰 공간"에서의 중복 프로브 메모리 감소
    • 트레이드오프: 더 나은 메모리 vs 더 복잡한 샘플링(잠재 성능 영향)

이제 실제 출시까지 왔으니, 다시 아티스트 쪽에 집중해서 워크플로우 문제를 완화할 수 있는 단계가 되었습니다.

아티스트 도구 개선

실시간 라이팅 업데이트(프리뷰)

우선순위가 높은 항목은 맵 에디터에서 실시간 라이팅 업데이트를 다시 활성화하는 것입니다. 이상적으로는 작업 중에도 "최종 결과에 가까운" 프리뷰를 보고, 체크인을 위한 "진짜 베이크"는 한 번만 돌리는 방식이 좋습니다. 이는 기본적으로 현재 결과를 BC6 텍스처로 압축해 적절히 저장하는 작업입니다.

Enlighten 의존 제거

또 하나는 Enlighten 데이터를 완전히 벗어나, 자체 머티리얼 등을 이용해 래디언스를 얻는 것입니다. 그러면 전체 라이팅 베이크가 필요 없어지고, DDGI가 실제로 필요로 하는 데이터만 굽게 됩니다. 전체 베이크를 피할 수 있다면 캡처 시간도 크게 줄어들 것입니다.

GPU 가속 캡처

GPU에서 DDGI 알고리즘을 그대로 실행할 수 있다면, 베이크 시간을 "수 분"에서 "수 초"로 낮출 수 있어 매우 매력적입니다. 다만 엔진이 DX11 기반이라 하드웨어 레이 트레이싱이 즉시 활용되기 어렵다는 문제가 있습니다. 좋은 소식은 DX12 백엔드가 베타로 제공되고 있어, 이 부분이 성숙해지면 다시 본격적으로 검토할 수 있다는 점입니다.

런타임 확장

체적 안개(Volumetric Fog)

런타임 측면에서는, 공간 GI 데이터를 확보했으니 이를 어디에 더 적용할 수 있을지 탐색하고 있습니다. 예를 들면 체적 안개입니다. 현재 안개는 단일 앰비언트 값만 사용하지만, DDGI 데이터를 읽도록 하면 공간적으로 변하는(더 자연스러운) 안개 조명을 얻을 수 있습니다. 물론 성능을 고려해야 하며, 고사양 전용 기능으로 두고 저사양은 기존 방식으로 폴백할 수 있습니다.

탐색적 연구

희소 볼륨 표현

시간 여유가 생기면, 하늘처럼 변화가 적은 큰 공간에서 "중복" 프로브로 낭비되는 메모리를 줄이기 위해 희소 볼륨 표현을 연구하고자 합니다. 이는 메모리 개선과 샘플링 복잡도 증가(성능 영향) 사이의 트레이드오프가 있습니다.

하지만 앞서 말했듯, 가정에 기대면 안 됩니다. 가설을 세우고, 이전을 측정하고, 이후를 측정해야 합니다.

개발 타임라인 및 정리

  • 컨셉부터 출시까지의 타임라인은 연속적이라기보다 "띄엄띄엄" 진행됨
  • 큰 기간은 《오버워치 2》 출시 및 라이브 지원 작업에 사용됨
  • 핵심 교훈: 라이브 제품에서 대형 시스템을 구현할 때는 "유연성"이 매우 중요
  • 엔지니어, 아티스트, QA, 그리고 Team 4 전체에 감사
  • DDGI 알고리즘 학습을 위한 추가 참고 자료 소개

마지막으로 흥미로운 점은, 이 작업의 전체 타임라인이 꽤 산발적이라는 것입니다. 이는 《오버워치 2》 출시를 향해 달리다가, 출시 이후에도 게임과 툴을 계속 지원하며 업데이트해야 했기 때문입니다. 슬라이드가 온라인으로 공개되면 여유 있을 때 자세히 살펴보셔도 좋습니다. 여기서의 핵심 메시지는, "출시된 제품"에 큰 시스템을 넣을 때는 유연성이 핵심이라는 점입니다.

감사 인사

엔지니어, 아티스트, QA, 그리고 Team 4의 모든 구성원에게 진심으로 감사드립니다. 이런 작업은 결코 혼자 할 수 없고, 누구나 어떤 방식으로든 기여했습니다. DDGI 알고리즘 자체를 더 깊게 알고 싶다면 소개된 자료들을 참고해 주세요. 또한 온라인 슬라이드 덱에 포함된 보너스 슬라이드에는, 새 GI 솔루션의 최종 결과 스크린샷이 더 포함되어 있습니다.

Q&A

Q&A 핵심 요약

  • Enlighten 가시성 계산: Embree로 각 표면에서 매우 많은 레이를 발사하고, 바운스 라이팅에 영향이 큰 다른 클러스터 256개를 유지
  • 볼륨 배치 워크플로우: 경계와 프로브 위치를 시각화할 수 있으며, 아티스트는 이미 유사한 워크플로우에 익숙함
  • 볼륨 개수 제한: 현재는 제한 없음. 대신 실시간 메모리 추정 도구를 구축 중
  • 프로브 푸시(Probe nudging): 베이크 중 벽에 너무 붙었거나 지오메트리 내부에 있는 프로브를 자동으로 밀어냄
  • 라이트 리킹 관리: 적절한 밀도 + 자식 볼륨 + 프로브 푸시 조합. BC6의 3번째 채널은 가중치 휴리스틱에 활용 가능성이 있음
  • 이중 GI 유지: 전반적으로 어렵지 않았고, 기존 구현은 계속 정상 동작
  • 16비트 타입 성능: ALU 집약 셰이더에서 효과가 크고, DDGI처럼 텍스처 페치 집약 셰이더에서는 효과가 제한적
  • 스텐실 패스와 리킹/접합: 스텐실 자체가 리킹을 직접 줄이지는 않음. 자식 볼륨 경계 블렌딩은 DDGI와 유사한 가중치 방식 사용

질문: Enlighten에서 클러스터 간 가시성은 어떻게 계산하나요?

Enlighten 베이크 중 Embree를 사용해 각 표면에서 사방으로 매우 많은 레이를 발사합니다. 그리고 반사광(바운스 라이팅)에 가장 큰 영향을 미치는 다른 클러스터 256개 목록을 유지해 평가에 사용합니다.

질문: DGI 프로브 볼륨 배치가 아티스트 워크플로우에 어떤 영향을 주나요?

볼륨을 조정할 때 경계는 물론이고, 프로브의 실제 표현도 켜서 볼 수 있습니다. 유용한 점은 아티스트가 어느 정도 이미 익숙한 방식이라는 것입니다. 다만 현재는(발표 말미에 언급했듯이) 실시간 라이팅이 아직 활성화되지 않아, 원하는 수준보다 시행착오가 조금 더 많을 수 있습니다. 이 부분은 실시간 라이팅이 다시 들어오면 크게 개선될 것으로 기대합니다. 전반적으로 아티스트는 비교적 빠르게 결과의 감을 잡고, 볼륨 밀도를 더 올릴지, 실내 디테일을 위해 자식 볼륨을 추가할지 등을 결정할 수 있습니다.

질문: 아티스트가 사용할 수 있는 DGI 볼륨 개수에 제한이 있나요?

현재는 볼륨 개수를 제한하지 않습니다. 다만 이 기능이 진행 중인 만큼, 각 볼륨의 메모리 추정치를 화면에 표시해 아티스트가 볼륨을 이동하거나 프로브 밀도를 조정할 때, "프로브 한 줄" 또는 "프로브 수" 증가가 전체 메모리 점유량에 어떤 영향을 주는지 실시간으로 볼 수 있게 하는 도구를 만들고 있습니다.

질문: 수동으로 볼륨을 배치하는 것이 아티스트에게 부담이 되지는 않나요?

기존의 라이트맵만 굽던 방식과는 분명히 다릅니다. 그래서 이를 돕기 위해 몇 가지를 하고 있습니다. 예를 들어 큰 공간에 볼륨을 드래그하면 실외/실내/경계 모두를 포함할 수 있습니다. 또한 베이크 중 "프로브 푸시"를 수행합니다. 프로브가 벽에 너무 붙어 있으면 약간 밀어내서, 일부 사용자에게 익숙한 "핀칭" 아티팩트를 줄입니다. 프로브가 지오메트리 내부에 있을 때도, 같은 셀의 다른 프로브와 간섭(crosstalk)을 일으키지 않는 범위에서 바깥으로 밀어냅니다.

질문: DGI에서 여전히 발생하는 라이트 리킹은 어떻게 관리하나요?

기본적으로는 적절한 밀도 확보, 적절한 밀도의 부모 볼륨 안에 자식 볼륨을 추가하는 것, 그리고 프로브 푸시의 조합입니다. 여전히 일부 리킹은 있고, 앞서 언급한 BC6의 3번째 채널을 신중하게 활용해 보려 합니다. 다만 압축 텍스처에 데이터를 넣으면 그대로 복원되지 않을 수 있기 때문에, 무엇을 넣을지 매우 조심해야 합니다. 이 채널에 유용한 휴리스틱 데이터를 넣어, 가중치 계산에서 "이 프로브는 좋으니 더 쓰자" 또는 "이 프로브는 별로니 덜 쓰자" 같은 결정을 돕는 방향을 연구 중입니다.

질문: 맵 단위로 새/구 구현을 선택할 때, 두 GI 구현을 유지하는 것이 어렵나요?

전반적으로는 어렵지 않았습니다. 기존 구현은 파이프라인 전반에서 계속 잘 동작했습니다. 다만 중간중간 새 기술 쪽에서 특정 패스를 커버하지 못한 것을 뒤늦게 발견해 보완해야 하는 경우는 있었는데, 이는 대부분 새 기술에만 해당하는 문제였습니다.

질문: 셰이더에서 16비트 타입을 쓰면 성능에 어떤 도움이 되나요?

답변이 쉽지는 않습니다. 우리가 본 가장 큰 이득은, 필요한 데이터를 레지스터에 올려 두고 ALU 연산을 많이 하는 셰이더에서 나왔습니다. 반면 DDGI 셰이더처럼 텍스처 페치 대기 시간이 지배적인 경우는, 16비트로 바꿔도 이득이 크지 않았습니다. 하지만 일부 라이팅 셰이더나 포스트 프로세스처럼 샘플 이후 수학 연산이 많은 구간에서는 더 많은 시간을 되찾을 수 있었습니다.

질문: 스텐실 패스가 라이트 리킹을 줄이는 데도 도움이 되나요? 그리고 여러 볼륨을 해석할 때 이음새가 생기지는 않나요?

스텐실 볼륨 자체는 라이트 리킹을 직접 줄이지는 않습니다. 이음새에 대해서는, 자식 볼륨의 첫 번째 링(probe ring)을 부모 쪽으로 블렌딩하려고 시도합니다. 여기에는 두 가지 모두 완벽하지 않은 선택지가 있습니다. 하나는 단순한 트라이리니어 보간인데, 그러면 프로브의 "비이상적인" 데이터를 가져올 수 있습니다. 다른 하나는(현재 우리가 하는 방식) DDGI 알고리즘과 유사한 가중치 기반 블렌딩입니다. 대부분은 잘 동작하지만, 선형 보간이 아니기 때문에 얇은 접합선이 생길 때도 있습니다. 이 경우 볼륨을 옮기거나 밀도를 바꾸는 등으로 완화하고, 그래도 남으면 식물 같은 것으로 시각적으로 가리는 식으로 대응하기도 합니다.

발표자료 내용 끝.