Virtual Shadow Maps
가상화 그림자 맵으로 고품질 그림자 구현
Virtual Shadow Maps란?
Nanite와 함께하는 차세대 그림자 시스템
Virtual Shadow Maps(VSM)은 UE5의 가상화 그림자 맵 시스템입니다. 기존 Cascaded Shadow Maps를 대체하여 픽셀 단위의 일관된 그림자 품질을 제공합니다.
/*
┌─────────────────────────────────────────────────────────────┐
│ VIRTUAL SHADOW MAPS │
├─────────────────────────────────────────────────────────────┤
│ │
│ 기존 CSM (Cascaded Shadow Maps): │
│ ┌─────┬─────┬─────┬─────┐ │
│ │Cas 0│Cas 1│Cas 2│Cas 3│ 고정된 캐스케이드, 해상도 불균일 │
│ └─────┴─────┴─────┴─────┘ │
│ │
│ VSM (Virtual Shadow Maps): │
│ ┌─────────────────────────────────────────────┐ │
│ │ 16K x 16K 가상 그림자 맵 (타일 기반) │ │
│ │ ┌───┬───┬───┐ │ │
│ │ │ T │ T │ T │ 필요한 타일만 렌더링 │ │
│ │ ├───┼───┼───┤ 화면 픽셀당 일관된 해상도 │ │
│ │ │ T │ T │ T │ 캐시를 통한 재사용 │ │
│ │ └───┴───┴───┘ │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
*/
VSM 장점
- 일관된 그림자 해상도
- 캐시 기반 재사용
- Nanite와 최적 통합
- 대규모 월드 지원
VSM 단점
- VRAM 사용량 증가
- 정적 오브젝트에 최적화
- WPO 성능 비용 높음
- 일부 아티팩트 가능
VSM 활성화 및 설정
프로젝트 및 라이트 설정
// Project Settings > Engine > Rendering > Shadows
Shadow Map Method:
Shadow Map Method: Virtual Shadow Maps // CSM 대신 VSM
Virtual Shadow Maps:
Virtual Shadow Map Resolution: 16384 // 16K (기본)
Enable Virtual Shadow Maps: true
Directional Light 설정
// Directional Light Actor > Details
Shadows:
Cast Shadows: true
Dynamic Shadow Distance MovableLight: 0 // VSM이 처리
Virtual Shadow Map:
Use Virtual Shadow Map: true
// 콘솔 명령
r.Shadow.Virtual.Enable 1
r.Shadow.Virtual.Resolution 16384
Point/Spot Light 설정
// Point Light / Spot Light
Shadows:
Cast Shadows: true
Use Inverse Squared Falloff: true
// 로컬 라이트도 VSM 사용
// 성능을 위해 그림자 캐스팅 라이트 수 제한 권장
캐싱과 무효화
성능을 위한 그림자 캐시 관리
VSM은 페이지 캐싱을 통해 정적 오브젝트의 그림자를 재사용합니다. 오브젝트가 이동하면 해당 타일만 무효화됩니다.
/*
정적 오브젝트:
- 그림자 한 번 렌더링 후 캐시
- 카메라 이동해도 재사용
- 매우 효율적
동적 오브젝트:
- 매 프레임 해당 타일 무효화
- 이동 범위의 타일 재렌더링
- 성능 비용 발생
최적화 핵심:
- 가능한 많은 오브젝트를 Static으로
- 움직이는 오브젝트 최소화
- WPO 사용 시 Disable Distance 설정
*/
C++ 그림자 캐시 제어
// 컴포넌트의 그림자 캐시 힌트 설정
void AMyActor::SetupShadowCaching()
{
if (UStaticMeshComponent* SMC = FindComponentByClass<UStaticMeshComponent>())
{
// 정적으로 설정 - 그림자 캐시 활용
SMC->SetMobility(EComponentMobility::Static);
// 또는 Stationary (위치 고정, 머티리얼 변경 가능)
// SMC->SetMobility(EComponentMobility::Stationary);
// 그림자 캐스팅 설정
SMC->SetCastShadow(true);
// 자체 그림자만 받기 (성능 최적화)
// SMC->bCastHiddenShadow = false;
}
}
// 강제 캐시 무효화 (에디터/특수 상황)
void AMyActor::InvalidateShadowCache()
{
if (UPrimitiveComponent* Prim = FindComponentByClass<UPrimitiveComponent>())
{
// 렌더 상태 마킹으로 간접 무효화
Prim->MarkRenderStateDirty();
}
}
VSM 성능 최적화
VRAM과 성능 밸런싱
// VSM 해상도 (16K가 기본, 낮추면 품질 저하)
r.Shadow.Virtual.Resolution 16384
// 최대 물리 페이지 수 (VRAM 사용량)
r.Shadow.Virtual.MaxPhysicalPages 4096
// 캐시 크기
r.Shadow.Virtual.Cache.Size 512
// 페이지 풀 크기 (MB)
r.Shadow.Virtual.Pool.Size 512
// 통계 확인
stat ShadowRendering
stat VirtualShadowMaps
| 설정 | Low | Medium | High | Epic |
|---|---|---|---|---|
| Resolution | 4096 | 8192 | 16384 | 16384 |
| Max Pages | 1024 | 2048 | 4096 | 8192 |
| Pool Size (MB) | 128 | 256 | 512 | 1024 |
VSM은 상당한 VRAM을 사용합니다. 4GB VRAM GPU에서는 Pool Size를 256MB 이하로 제한하세요.
일반적인 문제와 해결
VSM 아티팩트 디버깅
그림자 깜빡임
원인: 얇은 지오메트리, 양면 머티리얼
해결: 지오메트리 두께 확보, Shadow Bias 조정
그림자 끊김
원인: 페이지 풀 부족
해결: MaxPhysicalPages, Pool.Size 증가
성능 저하
원인: 과도한 동적 오브젝트, WPO
해결: Static 설정, WPO Distance
Self-Shadow 아티팩트
원인: Contact Shadow 필요
해결: Contact Shadow Length 조정
// VSM 시각화
r.Shadow.Virtual.Visualize 1 // 타일 시각화
// 캐시 상태 확인
r.Shadow.Virtual.Cache.StaticSeparate 1
// 무효화 영역 표시
r.Shadow.Virtual.InvalidationDebug 1
핵심 요약
- VSM — 가상화 그림자 맵, 타일 기반, 일관된 해상도
- 캐싱 — 정적 오브젝트 그림자 재사용, 동적은 무효화
- Nanite 통합 — Nanite 메시와 최적화된 그림자 렌더링
- VRAM 관리 — Pool Size, Max Pages로 메모리 제어
- 최적화 — Static 모빌리티, WPO Disable Distance
도전 과제
배운 내용을 직접 실습해보세요
Project Settings에서 Shadow Map Method를 Virtual Shadow Maps로 설정하세요. r.Shadow.Virtual.Visualize 1로 섀도우 맵 타일을 시각화하고, 오픈월드의 나무/건물 그림자 품질을 확인하세요.
r.Shadow.Virtual.Cache.StaticSeparate 1을 설정하여 정적 오브젝트의 섀도우 캐시를 최적화하세요. stat ShadowRendering으로 섀도우 렌더링 비용을 측정하고, 동적/정적 오브젝트의 캐시 효율을 비교하세요.
Nanite 메시의 VSM 렌더링 성능을 프로파일링하고, r.Shadow.Virtual.MaxPhysicalPages를 조정하여 대규모 오픈월드에서 VRAM 사용량과 품질의 균형을 찾으세요. One Pass Projection 옵션의 효과도 측정하세요.