PART 2 · 강의 5/7

Virtual Shadow Maps

가상화 그림자 맵으로 고품질 그림자 구현

01

Virtual Shadow Maps란?

Nanite와 함께하는 차세대 그림자 시스템

Virtual Shadow Maps(VSM)은 UE5의 가상화 그림자 맵 시스템입니다. 기존 Cascaded Shadow Maps를 대체하여 픽셀 단위의 일관된 그림자 품질을 제공합니다.

VSM 아키텍처 /* ┌─────────────────────────────────────────────────────────────┐ │ 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 성능 비용 높음
  • 일부 아티팩트 가능
02

VSM 활성화 및 설정

프로젝트 및 라이트 설정

Project Settings // 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 // 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 설정

Local Lights // Point Light / Spot Light Shadows: Cast Shadows: true Use Inverse Squared Falloff: true // 로컬 라이트도 VSM 사용 // 성능을 위해 그림자 캐스팅 라이트 수 제한 권장
03

캐싱과 무효화

성능을 위한 그림자 캐시 관리

VSM은 페이지 캐싱을 통해 정적 오브젝트의 그림자를 재사용합니다. 오브젝트가 이동하면 해당 타일만 무효화됩니다.

캐시 동작 /* 정적 오브젝트: - 그림자 한 번 렌더링 후 캐시 - 카메라 이동해도 재사용 - 매우 효율적 동적 오브젝트: - 매 프레임 해당 타일 무효화 - 이동 범위의 타일 재렌더링 - 성능 비용 발생 최적화 핵심: - 가능한 많은 오브젝트를 Static으로 - 움직이는 오브젝트 최소화 - WPO 사용 시 Disable Distance 설정 */

C++ 그림자 캐시 제어

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(); } }
04

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
⚠️ VRAM 주의

VSM은 상당한 VRAM을 사용합니다. 4GB VRAM GPU에서는 Pool Size를 256MB 이하로 제한하세요.

05

일반적인 문제와 해결

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
SUMMARY

핵심 요약

  • VSM — 가상화 그림자 맵, 타일 기반, 일관된 해상도
  • 캐싱 — 정적 오브젝트 그림자 재사용, 동적은 무효화
  • Nanite 통합 — Nanite 메시와 최적화된 그림자 렌더링
  • VRAM 관리 — Pool Size, Max Pages로 메모리 제어
  • 최적화 — Static 모빌리티, WPO Disable Distance
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: VSM 기본 설정 및 확인

Project Settings에서 Shadow Map Method를 Virtual Shadow Maps로 설정하세요. r.Shadow.Virtual.Visualize 1로 섀도우 맵 타일을 시각화하고, 오픈월드의 나무/건물 그림자 품질을 확인하세요.

실습 2: VSM 캐시 최적화

r.Shadow.Virtual.Cache.StaticSeparate 1을 설정하여 정적 오브젝트의 섀도우 캐시를 최적화하세요. stat ShadowRendering으로 섀도우 렌더링 비용을 측정하고, 동적/정적 오브젝트의 캐시 효율을 비교하세요.

심화 과제: VSM과 Nanite 연동 최적화

Nanite 메시의 VSM 렌더링 성능을 프로파일링하고, r.Shadow.Virtual.MaxPhysicalPages를 조정하여 대규모 오픈월드에서 VRAM 사용량과 품질의 균형을 찾으세요. One Pass Projection 옵션의 효과도 측정하세요.