Unity 6 URP의 Adaptive Probe Volumes 완전 분석

씬에 배치된 수백 개의 Light Probe Group이 엉뚱한 곳을 밝히고 있거나, 오브젝트 경계에서 조명이 갑자기 튀거나, 멀티 씬 프로젝트에서 베이크한 라이팅이 서로 어울리지 않아 배치를 일일이 조정해야 했던 경험. 바로 그 문제를 해결하기 위해 Unity 6에서 URP에 정식 도입된 것이 Adaptive Probe Volumes(APV)입니다.

HDRP에서 실험적으로 시작된 APV가 Unity 6.0(URP 17)에서 URP에 안정 버전으로 들어왔습니다. 이 포스팅은 APV가 기존 Light Probe Groups와 무엇이 다른지, 내부에서 어떤 구조로 동작하는지, 그리고 Unity 6.0부터 6.3 LTS까지 어떤 기능이 추가되었는지를 파고듭니다.

목차


Light Probe Groups의 한계 — 왜 새 시스템이 필요했나

기존 Light Probe Groups(LPG)는 개발자가 씬에 직접 Light Probe를 배치하는 방식이었습니다. 직관적이지만, 규모가 커질수록 세 가지 구조적인 한계가 드러납니다.

첫째, per-object 샘플링. LPG는 오브젝트 단위로 하나의 혼합 프로브 값을 계산합니다. 차량처럼 크기가 큰 오브젝트는 루프가 햇빛을 받고 있어도 바닥과 같은 어두운 값을 받는 문제가 생깁니다. 오브젝트가 여러 조명 환경에 걸쳐 있으면 부정확한 혼합이 발생합니다.

둘째, 수동 배치의 한계. 수천 개의 오브젝트가 있는 씬에서 조명 변화가 잦은 구역(창문 근처, 아치 안쪽 등)에 프로브를 적절히 배치하는 것은 사실상 수작업입니다. 배치가 어설프면 경계에서 조명 이음새(seam)가 생깁니다.

셋째, 멀티 씬 한계. 여러 씬을 합쳐서 쓰는 대규모 오픈월드에서 LPG의 베이크 데이터는 씬 간 연속성을 보장하지 못합니다.

APV는 이 세 가지를 모두 자동화와 구조적 개선으로 해결합니다.


APV의 핵심 아이디어 — 자동 배치, 브릭 구조, per-pixel 샘플링

APV의 핵심은 세 가지입니다: 자동 배치, 브릭 구조, per-pixel 샘플링.

자동 배치

LPG에서는 개발자가 씬을 돌아다니며 Light Probe를 직접 놓아야 했습니다. APV는 이 과정을 완전히 자동화합니다.

베이킹 전, Unity는 씬 안의 Mesh Renderer와 TerrainContribute Global Illumination이 활성화된 오브젝트를 모두 수집해 지오메트리 밀도를 분석합니다. 이 분석 결과를 바탕으로 오브젝트가 밀집한 구역에는 프로브를 촘촘하게, 빈 공간에는 성기게 배치합니다.

밀도를 직접 조정하고 싶다면 두 가지 방법이 있습니다. APV Inspector의 Override Probe Spacing으로 씬 전체의 최소·최대 간격을 지정하거나, 특정 구역에 로컬 APV 볼륨을 추가해 해당 영역만 별도 간격으로 제어할 수 있습니다. 예를 들어 넓은 광장에 로컬 APV를 씌워 그 구역만 밀도를 낮추는 식입니다.

기존 Light Probe Groups 수동 배치(좌)와 APV 자동 배치(우) 비교

브릭 구조

Unity는 씬을 분석해서 브릭(Brick) 단위로 Light Probe를 자동 배치합니다. 브릭 하나는 4×4×4 배열, 즉 64개의 Light Probe로 구성됩니다. 브릭의 크기는 고정이 아니라 씬의 지오메트리 밀도에 따라 달라집니다.

APV 브릭 구조 — 지오메트리 밀도에 따라 크기가 달라지는 4×4×4 Light Probe 배열 단위

브릭 간격 기본값: 1m / 3m / 9m / 27m (계층적 적용)

[복잡한 지오메트리 영역]   → 1m 간격 소형 브릭 → 고해상도 조명
[개방된 빈 공간]          → 27m 간격 대형 브릭 → 메모리 절약

건물 내부나 창문 근처처럼 조명 변화가 큰 구역은 작은 브릭으로 촘촘하게, 개방된 하늘 아래 평야는 큰 브릭으로 성기게 채웁니다.

per-pixel 샘플링

LPG와 가장 큰 차이점입니다. APV는 오브젝트당 하나의 프로브 값이 아니라, 픽셀마다 가장 가까운 8개의 프로브에서 조명 데이터를 샘플링합니다.

LPG (기존):
차량 → 단일 블렌드 값 → 루프/보닛/바닥 모두 동일 조명

APV (새):
차량 루프 픽셀 → 주변 8개 프로브 샘플 → 햇빛 반영
차량 바닥 픽셀 → 주변 8개 프로브 샘플 → 지면 반사 반영

결과적으로 하나의 오브젝트 안에서도 조명이 자연스럽게 변화합니다. 볼류메트릭 포그를 사용하는 경우 포그 내부의 조명 변화도 더 정확하게 표현됩니다.

Per-object vs Per-pixel 비교


내부 동작 원리 — 베이킹부터 런타임 스트리밍까지

APV는 에디터의 베이킹 단계와 런타임 단계가 명확히 분리됩니다.

베이킹 단계

APV는 씬의 지오메트리를 분석해 브릭 배치를 결정한 다음, Progressive GPU Lightmapper로 각 프로브 위치의 SH(Spherical Harmonics) 계수를 계산해 저장합니다. 결과는 Baking Set 단위로 관리됩니다.

Virtual Offset이라는 기능도 있는데, 벽 안쪽이나 표면에 너무 가깝게 위치한 프로브를 자동으로 바깥쪽으로 밀어내 아티팩트를 줄입니다. 이 과정 역시 자동으로 처리됩니다.

런타임 단계

런타임에서 APV 데이터는 네 단계로 처리됩니다:

1. Cell Registration  — 셀(브릭 묶음)을 ProbeReferenceVolume에 등록
2. Cell Streaming     — 카메라 위치 기준, 가까운 셀 우선 비동기 로드
3. GPU Data Upload    — 셀 데이터를 텍스처 기반 포맷으로 GPU 메모리에 업로드
4. Shader Sampling    — APVResources 구조체를 통해 셰이더가 GI 데이터 조회

핵심 클래스는 ProbeReferenceVolume 싱글턴으로, 전체 APV 시스템을 관리합니다. ProbeBrickPool이 GPU 메모리의 브릭 데이터를, ProbeBrickIndex가 계층적 인덱싱과 조회를 담당합니다.

스트리밍 시스템은 카메라와의 거리를 기준으로 셀 우선순위를 매기고, 제한된 GPU 메모리를 풀(Pool) 방식으로 재사용합니다. 이 구조 덕분에 GPU 메모리보다 큰 APV 데이터도 런타임에 분할 로드할 수 있습니다.


Sky Occlusion — 베이크 1회로 하늘 색상 기반 낮/밤 전환 구현하기

APV의 가장 인상적인 기능 중 하나입니다. Sky Occlusion은 단 한 번의 베이크로, ambient probe에서 오는 하늘 색상 변화를 런타임에 반영합니다. 태양 위치 이동이나 씬 내 조명 상태 변화는 이 기능의 범위 밖이지만, 하늘이 밝아지고 어두워지는 변화만으로도 충분한 타임오브데이 연출이 가능한 경우에 유효한 선택입니다.

동작 원리

Sky Occlusion이 활성화되면 Unity는 베이킹 시 각 프로브에 sky occlusion 값을 추가로 저장합니다. 이 값은 “이 프로브 위치에서 하늘빛이 얼마나 닿는가”를 나타내는 정적 데이터입니다.

런타임에서 GameObject가 프로브를 샘플링할 때 Unity는 두 값을 곱합니다:

최종 하늘빛 = sky color (ambient probe, 동적 업데이트)
            × sky occlusion value (베이크된 정적 값)

하늘 색상은 ambient probe를 통해 실시간으로 변경되지만, 얼마나 도달하는지는 베이크된 값이 결정합니다. 실내 깊숙한 곳은 sky occlusion 값이 낮아 하늘이 아무리 밝아도 어둡게 유지됩니다.

활성화 및 런타임 설정

Sky Occlusion을 사용하려면 먼저 Progressive GPU Lightmapper로 전환해야 합니다. CPU Lightmapper에서는 sky occlusion 계산 자체가 지원되지 않습니다.

Window → Rendering → Lighting → Scene 패널Lightmapper: Progressive GPU 로 변경한 뒤, APV 패널에서 Sky Occlusion을 활성화하고 베이크를 다시 실행합니다.

런타임에서 하늘 색상을 실제로 변경하려면 ambient probe가 동적으로 업데이트되어야 합니다. URP에서의 방법은 두 가지입니다.

① Gradient / Color Source 사용 (권장)

Window → Rendering → Lighting → Environment 패널Source: Gradient 또는 Color 로 설정합니다. 이후 RenderSettings.ambientSkyColor 등의 API나 Animation 창으로 색상을 변경하면 ambient probe가 즉시 반영됩니다.

② Skybox Source 사용 (주의 필요)

Source를 Skybox로 유지할 수도 있지만, skybox가 바뀔 때마다 DynamicGI.UpdateEnvironment()를 수동으로 호출해야 합니다. 이 API는 성능 부담이 매우 크기 때문에 타임오브데이처럼 매 프레임 색상이 바뀌는 용도에는 적합하지 않습니다.

Sky Direction — 방향성 있는 하늘빛

기본 Sky Occlusion은 하늘빛의 만 저장합니다. 각 픽셀이 ambient probe를 샘플링할 때 기준 방향으로 오브젝트의 표면 법선을 사용하는데, 이 근사값은 창문이 있는 방 안쪽이나 동굴 입구처럼 하늘빛이 특정 방향으로만 들어오는 상황에서는 부정확합니다.

Sky Direction을 활성화하면 각 프로브에 하늘빛이 실제로 오는 방향을 함께 저장합니다. 바운스 라이팅까지 고려하므로 동굴이나 창문 씬에서 체감 차이가 큽니다.

APV Sky Occlusion — 단일 베이크로 런타임 낮/밤 하늘빛 변화를 반영하는 시연

단, 프로브 간 방향 데이터 보간이 되지 않아 프로브 경계에서 이음새가 생길 수 있습니다. 특정 구역의 방향을 수동으로 수정하려면 Probe Adjustment Volume 컴포넌트를 해당 구역에 추가하면 됩니다. Sky Direction 활성화 시 베이크 시간과 런타임 메모리도 추가로 증가합니다.

Sky Occlusion의 한계

제약 이유
Progressive GPU Lightmapper 필수 CPU Lightmapper는 sky occlusion 계산 미지원
오브젝트 색상 무시 베이킹 시 모든 표면을 회색 불투명체로 처리 — 어두운 벽과 밝은 벽이 같은 양의 빛을 반사
투명/반투명 오브젝트 창문·나뭇잎이 빛을 투과하지 않고 불투명체처럼 반사
Sky Direction 프로브 간 보간 없음 방향 데이터가 보간되지 않아 경계에서 이음새 발생 가능
베이크 시간·메모리 증가 sky occlusion 값, Sky Direction 방향 데이터 추가 저장 비용

투명·반투명 오브젝트가 많다면 해당 오브젝트의 Static Editor Flags에서 Contribute GI를 비활성화하는 것이 결과를 개선하는 가장 직접적인 방법입니다. 표면 색상의 근사 오차를 줄이려면 APV 패널의 Sky Occlusion Settings에서 Albedo Override 값을 조정합니다.


Lighting Scenarios — 더 복잡한 조명 변화 다루기

Sky Occlusion이 하늘 색상 변화에 특화돼 있다면, Lighting Scenarios는 씬 내 조명 오브젝트의 상태 변화(켜진 램프 → 꺼진 램프, 낮 풍경 → 밤 풍경)까지 다룹니다.

각 Lighting Scenario는 특정 조명 상태로 베이크된 APV 데이터 세트입니다. 런타임에 시나리오를 전환하거나 두 시나리오 사이를 블렌딩할 수 있습니다. Unity 6.0에서 URP에 Lighting Scenario Blending이 추가됐습니다.

Sky Occlusion vs Lighting Scenarios 비교

항목 Sky Occlusion Lighting Scenarios
베이크 횟수 1회 시나리오당 1회
하늘 색상 업데이트 동적 (실시간) 동적 (실시간)
씬 조명 변화 불가 가능
전환 비용 낮음 (부드럽고 빠름) 블렌딩 비용 있음
정확도 근사값 높음

둘을 함께 쓸 수도 있습니다. Sky Occlusion으로 하늘빛 변화를 처리하고, Lighting Scenarios로 실내 조명 상태 전환을 처리하는 식입니다.

실무 판단 기준: 낮/밤 전환만 필요하다면 Sky Occlusion 하나로 충분합니다. 건물 내부 조명의 켜짐/꺼짐까지 표현해야 한다면 Lighting Scenarios를 추가하세요.


대규모 월드를 위한 Disk Streaming

대규모 오픈월드에서 APV 데이터 전체를 메모리에 올리는 것은 현실적이지 않습니다. Unity 6.0에서 추가된 Disk Streaming이 이 문제를 해결합니다.

스트리밍이 활성화되면 APV 데이터를 씬을 구성하는 셀(Cell) 단위로 분할해 디스크에 저장합니다. 런타임에서 카메라의 뷰 프러스텀 안에 있는 셀만 비동기로 로드합니다.

기본적으로 APV 데이터는 Streaming Assets에 저장되는데, Unity 6.0에서 Probe Volume Disable Streaming Assets 옵션을 추가해 일반 에셋 형태로 저장할 수 있게 됐습니다. 이 덕분에 APV 데이터를 AssetBundle이나 Addressables에 포함시켜 배포하는 것이 가능해졌습니다.

Project Settings > Graphics > Pipeline Specific Settings > URP > Adaptive Probe Volumes > Probe Volume Disable Streaming Assets


활성화 방법 (URP 기준)

세 군데 설정이 필요합니다.

① URP Asset에서 Light Probe System 변경
Project Settings > Quality → 활성 URP Asset 더블클릭
Lighting > Light Probe Lighting > Light Probe SystemAdaptive Probe Volumes

② APV 오브젝트 배치
GameObject > Light > Adaptive Probe Volume
Inspector에서 Mode → Global (씬 전체 커버)

③ 오브젝트 GI 설정
– 빛을 받을 오브젝트: Contribute Global Illumination 활성화
Receive Global IlluminationLight Probes
– 씬에 포함할 조명: Light > ModeMixed 또는 Baked

설정 후 Window > Rendering > Lighting 패널에서 Generate Lighting 클릭.


작동하지 않는 경우 — 제약 조건과 이유

그래픽스 API / 하드웨어 제약

APV의 런타임 스트리밍, Sky Occlusion 베이킹 등 핵심 기능은 내부적으로 Compute Shader를 사용합니다. Compute Shader를 지원하지 않는 플랫폼이나 그래픽스 API에서는 APV 자체가 동작하지 않습니다.

플랫폼 / API Compute Shader APV 지원 여부
DirectX 11/12 (Shader Model 5.0+) 완전 지원 지원
Vulkan 완전 지원 지원
Metal (iOS, macOS) 완전 지원 지원
OpenGL ES 3.1 (Android) 지원, 단 Compute Buffer 4개만 보장 조건부 지원
OpenGL ES 3.0 이하 Compute Shader 미지원 미지원
OpenGL (macOS) Apple이 4.1로 제한 → Compute Shader 미지원 미지원 (Metal 사용 필요)
WebGL 2 Compute Shader 미지원 미지원
WebGPU (실험적) Compute Shader 지원하나 제한 있음 미지원 (프로덕션 비권장)

OpenGL ES 3.1 주의사항: 스펙상 Compute Buffer는 4개만 보장됩니다. 실제 디바이스는 더 많이 지원하는 경우가 많지만, 구형 Android 저사양 기기를 타겟으로 할 경우 SystemInfo.supportsComputeShaders로 런타임에 지원 여부를 확인하는 것이 안전합니다.

macOS 주의사항: Apple은 macOS에서 OpenGL을 4.1로 제한하므로 OpenGL을 통한 Compute Shader가 불가합니다. macOS에서 APV를 사용하려면 그래픽스 API를 Metal로 설정해야 합니다.

Sky Occlusion 추가 제약: Sky Occlusion 베이킹은 Progressive GPU Lightmapper를 사용하므로, GPU가 충분한 VRAM을 갖추지 못한 환경에서는 베이킹이 CPU로 폴백되고 Sky Occlusion은 비활성화됩니다.


씬 구조 / 기능 제약

제약 조건 이유
Light Probe Groups와 동시 사용 제한 한 씬에서 두 시스템이 경쟁하며 예측 불가한 조명 결과 발생
프로브 위치 수동 조정 불가 브릭 단위 자동 배치 구조이므로 개별 프로브 위치 편집 인터페이스 미제공
Light Probe Groups에서 변환 불가 데이터 구조가 근본적으로 다름 — 새로 베이크 필요
Sky Occlusion에서 투명 오브젝트 처리 베이킹 시 모든 표면을 불투명 회색체로 처리하는 근사 방식의 한계
LPPV(Light Probe Proxy Volume)와 GPU Resident Drawer GPU Resident Drawer는 인스턴스 데이터를 GPU 메모리에 올려두고 CPU 개입 없이 처리하지만, LPPV는 매 프레임 CPU가 인스턴스별 SH 계수를 주입해야 하므로 구조적으로 충돌. APV + GPU Resident Drawer 조합을 사용하려면 LPPV 대신 APV를 직접 사용 권장

버전별 변경사항 — Unity 6.0 → 6.3 LTS

Unity 버전 URP 버전 주요 APV 변경사항
6.0 URP 17 Lighting Scenario Blending, Sky Occlusion, Disk Streaming, AssetBundle/Addressables 지원
6.1 URP 17.1 Bicubic Lightmap Sampling, Probe Atlas Blending 제어 추가
6.2 URP 17.2 멀티씬 환경 에디터 메모리 버그 수정, WebGL 미지원 에러 메시지 추가, Addressables 에러 메시지 개선
6.3 LTS URP 17.3 에디터 메모리·안정성 추가 수정

Unity 6.0 (URP 17) — 핵심 기능 도입

HDRP에서 실험적으로 개발되던 APV가 URP에 안정 버전으로 정식 도입된 시점입니다. Unity 2022 LTS에서 “URP does not support APV”라는 에러를 본 적 있다면, 그 벽이 Unity 6.0에서 허물어진 것입니다.

이번 릴리스에서 Lighting Scenario Blending, Sky Occlusion, Disk Streaming이 한꺼번에 들어왔습니다. APV의 핵심 기능이 대부분 이 버전에서 갖춰졌습니다.

Unity 6.1 (URP 17.1) — 품질 개선

Bicubic Lightmap Sampling이 추가됐습니다. 저해상도 라이트맵에서 바이리니어 보간으로 인한 계단 현상을 Bicubic 방식으로 크게 개선합니다. Project Settings > Graphics > Use Bicubic Lightmap Sampling에서 활성화할 수 있습니다.

Probe Atlas Blending 속성이 추가돼 Forward+ 렌더러에서 Reflection Probe 아틀라스 블렌딩을 독립적으로 제어할 수 있게 됐습니다.

Unity 6.2 / 6.3 LTS — 안정화

두 버전 모두 주로 버그 수정에 집중했습니다. 특히 멀티씬 환경에서 에디터 메모리가 과도하게 증가하던 버그가 수정됐습니다. APV를 사용하는 씬이 많은 프로젝트에서 에디터가 느려지는 문제를 경험했다면 6.2 이상으로 업그레이드가 도움이 됩니다.

6.2에서 WebGL 빌드 시 APV 미지원 에러가 명시적으로 표시되도록 됐습니다. 이전에는 빌드가 진행되다가 실패하거나 런타임 에러로만 확인할 수 있었습니다.


디버깅 — Rendering Debugger 활용

APV가 제대로 작동하는지 확인하는 주요 도구는 Rendering Debugger입니다.

Window > Analysis > Rendering Debugger > Probe Volume 탭

옵션 확인할 수 있는 것
Display Probes 각 프로브 위치와 저장된 조명 데이터 시각화
Display Bricks 브릭 경계선 표시 — 밀도 분포 확인
Display Cells 스트리밍 단위인 셀 경계 표시

브릭 밀도가 의도와 다르게 분포하고 있다면 Override Probe Spacing으로 특정 영역의 밀도를 직접 지정하거나, Probe Adjustment Volume 컴포넌트를 추가해 문제 구역을 세밀하게 조정할 수 있습니다.


결론 — 언제 쓰고 언제 재고하는가

APV는 아래 조건에서 가장 큰 효과를 냅니다.

  • 대규모 씬에서 수백 개의 Light Probe를 수동으로 배치하던 프로젝트
  • 오브젝트 경계에서 조명 이음새가 눈에 띄는 프로젝트
  • 타임오브데이 효과를 베이크된 간접광으로 구현하고 싶은 경우
  • 오픈월드처럼 메모리보다 큰 조명 데이터를 스트리밍으로 관리해야 하는 경우

반면 아래 경우는 신중하게 검토하세요.

  • WebGL 타겟 프로젝트: 현재 미지원
  • Sky Occlusion + 투명 오브젝트가 많은 씬: 창문이나 나뭇잎 투과광이 중요하다면 근사값 오차가 눈에 띌 수 있음
  • 매우 작은 씬: 수동 배치 LPG가 더 직관적이고 컨트롤하기 쉬울 수 있음

Unity 6.0에서 URP에 처음 도입된 이후 6.3 LTS까지 꾸준히 안정화된 APV는, 조명 품질과 워크플로우 양쪽에서 기존 Light Probe Groups를 대체할 만한 선택지로 자리 잡았습니다.


참고 자료

댓글 남기기