버추얼 섀도 맵

영화 퀄리티 에셋과 다이내믹 라이팅으로 구현된 대규모 오픈 월드를 염두에 두고 디자인된 고해상도 섀도잉 사용에 관한 개요입니다.

Choose your operating system:

Windows

macOS

Linux

새로운 섀도 매핑 메서드인 버추얼 섀도 맵(VSM) 은 영화 퀄리티 에셋과 다이내믹 라이팅으로 구현된 대규모 오픈 월드에 일관된 고해상도 섀도잉을 제공하는 데 사용되며, 언리얼 엔진 5의 나나이트 가상화 지오메트리, 루멘 글로벌 일루미네이션 및 리플렉션, 월드 파티션 기능을 활용합니다.

버추얼 섀도 맵의 목적

버추얼 섀도 맵은 다음 목적을 달성하기 위해 개발되었습니다.

  • 고도로 상세한 나나이트 지오메트리에 맞춰 섀도 해상도를 크게 상승

  • 합리적이고 제어 가능한 퍼포먼스 비용으로 뛰어난 수준의 소프트 섀도 달성

  • 기본적으로 최소한의 조정만으로도 작동하는 단순한 솔루션 제공

  • 통합된 단일 경로로 수많은 스테이셔너리 라이트 섀도잉 기술을 대체

개념적으로 버추얼 섀도 맵은 단순한 초고해상도 섀도 맵입니다. 현재 구현 단계에서는 16k x 16k 픽셀의 가상 해상도를 보여줍니다. 클립맵을 사용하여 디렉셔널 라이트에 대한 해상도를 한층 높입니다. 적절한 메모리 비용으로 높은 퍼포먼스를 유지하기 위해 VSM은 섀도 맵을 각각 128x128 타일(또는 페이지)로 분할합니다. 페이지는 뎁스 버퍼 분석을 기반으로 화면상의 픽셀에 셰이드를 제공하는 데 필요한 만큼만 할당 및 렌더링됩니다. 퍼포먼스를 추가로 향상시키는 오브젝트 또는 라이트를 움직임으로써 인밸리데이션되지 않는 한 페이지는 프레임 사이에서 캐시됩니다.

나나이트는 프리섀도 및 오브젝트별(또는 인셋) 섀도 등의 스테이셔너리 라이트 섀도잉 기법 대부분을 지원하지 않습니다. 카메라 뷰어 근처의 캐스케이드 섀도 맵과 같은 스테이셔너리 라이트 섀도잉의 일부 동적인 부분은 작동하지만 기존 섀도 맵을 사용하는 나나이트와 스테이셔너리 라이트는 지원되지 않습니다. 프로젝트에서 나나이트를 사용 중인 경우 무버블 라이트 또는 버추얼 섀도 맵을 사용해야 합니다.

버추얼 섀도 맵 활성화하기

프로젝트 세팅의 엔진(Engine) > 렌더링(Rendering) 아래에 있는 섀도(Shadows) 섹션에서 버추얼 섀도 맵(Virtual Shadow Maps) 과 이전 언리얼 엔진 릴리즈에서 사용된 기존 섀도 맵(Shadow Maps) 가운데 프로젝트가 어떤 새도 맵 메서드(Shadow Map Method) 를 지원할지 설정할 수 있습니다.

기존 프로젝트의 경우 프로젝트 세팅 또는 콘솔 변수 r.Shadow.Virtual.Enable을 통해 선택해야 합니다. 새 프로젝트는 기본으로 버추얼 섀도 맵을 사용합니다.

vsm-project-settings.png

VSM이 활성화되면 기존 섀도 메서드는 어떻게 되나요?

활성화되면 VSM이 다음과 같은 언리얼 엔진의 여러 기존 섀도 맵을 대체합니다.

  • 2D 디스턴스 필드 및 섀도 인수 ‘섀도 맵'을 포함한 스테이셔너리 사전 연산된 섀도

  • 프리섀도

  • 오브젝트별/인셋 섀도

  • 캐스케이드 섀도 맵(CSM)

  • 로컬 라이트의 무버블 다이내믹 섀도

스태틱 라이트에서 완전히 구워진 섀도는 예전과 같이 작동합니다(루멘을 사용하지 않는 경우). 이 섀도의 기여는 구워진 라이트맵에서 완전히 표현되며 런타임에서는 라이팅이 전혀 평가되지 않습니다. 스테이셔너리 라이트는 구워진 라이트맵의 간접 디퓨즈 기여를 사용하지만 VSM이 활성화되면 직사광 및 섀도는 동적으로 평가됩니다(무버블 라이트와 동일).

디스턴스 필드 섀도는 대체되지 않고, 디렉셔널 라이트를 위해 버추얼 섀도 맵과 함께 사용할 수 있습니다. 디스턴스 필드 섀도는 캐스케이드 섀도 맵 프로퍼티 다이내믹 섀도 거리 무버블 라이트(Dynamic Shadow Distance Movable Light) 를 사용하여 디렉셔널 라이트에 설정된 무버블 라이트의 동적 섀도잉 디스턴스 너머에서 비나나이트 지오메트리를 대신합니다. 디스턴스 필드 섀도는 많은 비나나이트 폴리지를 사용하는 씬을 포함한 복잡한 씬의 런타임 비용을 줄일 수 있는 유용한 툴입니다.

가장 퍼포먼스가 좋은 옵션이고 가장 높은 퀄리티를 제공하므로 나나이트 지오메트리는 디스턴스와 무관하게 항상 버추얼 섀도 맵에 렌더링합니다. 콘솔 변수 r.Shadow.Virtual.UseFarShadowCulling 0 을 사용하여 비나나이트 지오메트리가 나나이트와 같은 방식으로 동작하도록 할 수 있습니다.

로컬 라이트(포인트 및 스포트 라이트)는 영향을 받지 않고, 이에 대해 디스턴스 필드 섀도를 선택하면 계속해서 활성 섀도 맵 메서드를 오버라이드합니다.

VSM의 높은 해상도와 정확도로 인해 컨택트 섀도 길이 프로퍼티로 제어되는 스크린 스페이스 컨택트 섀도 기능이 없이도 선명한 컨택트 섀도를 달성할 수 있습니다. 섀도 맵에 렌더링되지 않도록 설정된 오브젝트의 저렴한 섀도에 사용된 값을 가지고 있을 수는 있지만, 이는 VSM으로 생성되는 섀도보다 정확하지 않을 것이므로 권장되지 않습니다.

레이 트레이싱된 섀도는 일반적으로 가장 높은 퀄리티 솔루션을 제공하므로 VSM보다 우선시됩니다.

섀도 맵 레이 트레이싱을 통한 소프트 섀도

섀도 맵 레이 트레이싱(SMRT) 은 더 그럴듯한 소프트 섀도와 컨택트 경화를 생성하기 위해 버추얼 섀도 맵과 함께 사용되는 샘플링 알고리즘입니다. 섀도를 더 멀리 캐스트하는 오브젝트는 가까운 표면에 캐스트하는 오브젝트보다 부드러운 섀도를 갖습니다. 예를 들어, 아래의 메시는 길어서 섀도가 멀리까지 캐스트됩니다. 맨 아래 부분에 가까운 섀도는 멀리 있는 섀도보다 선명합니다.

vsm-softshadowscontacthardening.png

섀도 맵 레이 트레이싱을 활용한 포인트 라이트 캐스팅 소프트 섀도 및 컨택트 경화 섀도의 예시.

퍼센티지 클로저 필터링(Percentage-Closer Filtering, PCF)을 바탕으로 하는 이전 메서드는 블러가 과도하고 고해상도 지오메트리 및 섀도의 시각적 임팩트를 감소시킵니다.

균등하게 블러되는 퍼센티지 클로저 필터링, | 중요한 디테일 제거

그럴듯한 섀도를 생성하는 섀도 맵 레이 트레이싱 | 소프트 섀도 및 컨택트 경화

SMRT 알고리즘은 광원을 향해 여러 개의 레이를 발사하여 작동하지만, 기존 레이 트레이싱처럼 지오메트리와의 교차점을 평가하는 대신 여러 개의 샘플을 레이와 함께 버추얼 섀도 맵으로 투영 및 테스트하여 소프트 섀도잉 및 컨택트 경화를 달성합니다. 섀도 레이는 로컬 라이트의 소스 반경(Source Radius) 또는 디렉셔널 라이트의 소스 각도(Source Angle) 를 사용하여 라이트를 기반으로 분포됩니다.

vsm-local-light-source-radius.png

vsm-directional-light-source-angle.png

로컬 라이트 소스 반경

디렉셔널 라이트 소스 각도

작은 소스 각도로 시작하는 디렉셔널 라이트와 달리 로컬 라이트는 기본 소스 반경이 없습니다. 각각 적절한 값으로 설정되면 SMRT는 소스 반경이 10인 포인트 라이트를 사용한 아래 예시와 같이 컨택트 경화와 함께 리얼타임 소프트 섀도잉을 생성합니다.

소스 반경이 0인 포인트 라이트

소스 반경이 10인 포인트 라이트

반그림자 섀도 퀄리티 제어

반그림자 섀도의 부드러움과 퀄리티는 로컬 및 디렉셔널 라이트에 대해 콘솔 변수로 설정됩니다. 여기에는 대부분의 씬에 일반적으로 좋은 자체 엔진 퀄리티 세팅이 포함됩니다.

반그림자의 노이즈는 사용되는 레이의 수에 영향을 받으며, 로컬 및 디렉셔널 라이트는 모두 섀도 의 엔진 퀄리티가 에픽(Epic) 으로 설정된 경우 기본적으로 8개의 레이를 사용합니다.

콘솔 변수 r.Shadow.Virtual.SMRT.RayCountLocalr.Shadow.Virtual.SMRT.RayCountDirectional 을 사용하여 레이의 수를 조절합니다. 레이의 수가 적으면 반그림자에서 노이즈가 보입니다. 연결된 콘솔 변수를 0으로 설정하면 SMRT가 비활성화되고 단일 샘플 하드 섀도로 되돌아갑니다.

디렉셔널 라이트 소스 각도: 5.0 | SMRT 레이 카운트: 1

디렉셔널 라이트 소스 각도: 5.0 | SMRT 레이 카운트: 7(기본)

또한, 각 레이 경로에서 사용된 섀도 샘플 수는 로컬 및 디렉셔널 라이트에 대해 설정되어 최대의 부드러움을 제어할 수 있습니다. 섀도 맵 샘플이 적을수록 렌더링 비용이 낮지만 라이트의 섀도로 달성 가능한 반그림자 부드러움의 정도가 제한됩니다. 섀도 엔진 퀄리티 세팅보다 더 미세한 컨트롤을 위해 콘솔 변수 r.Shadow.Virtual.SMRT.SamplesPerRayLocalr.Shadow.Virtual.SMRT.SamplesPerRayDirectional 은 사용되는 샘플 수를 조정합니다. 4~8개의 샘플 값을 사용하는 것이 효과적입니다.

슬라이더를 드래그하면 소스 각도가 5.0인 디렉셔널 라이트가 0, 2, 8(기본값)개의 섀도 맵 샘플을 사용할 때 어떻게 되는지 볼 수 있습니다.

섀도 맵 레이 트레이싱의 제한 사항

SMRT의 퀄리티는 디폴트 세팅으로도 대체로 좋지만, 진짜 지오메트리에 테스트하는 대신 단일 섀도 맵 프로젝션의 데이터를 사용한다는 점에서 본질적으로 제한 사항이 있습니다.

반그림자 크기 제한

섀도의 반그림자는 샘플이 레이 원본에서 갈라져서 레이 자체의 이상적인 테스트에 비해 과도하게 ‘구부러지는' 현상을 피하기 위해 로컬 및 디렉셔널 라이트에 대해 범위 제한됩니다. 로컬 라이트의 소스 반경과 디렉셔널 라이트의 소스 각도에 적절한 값을 사용하면 지나치게 극단적인 결과를 피하고 레이가 여러 방향으로 갈라지는 정도를 제한할 수 있습니다. 값이 너무 크면 퍼포먼스에도 영향을 미치며 카메라가 가까이 가면 섀도 반그림자가 시각적으로 뒤틀리게 됩니다.

vsm-penumbrashrinkage.gif

로컬 및 디렉셔널 라이트는 콘솔 변수 r.Shadow.Virtual.SMRT.MaxRayAngleFromLightr.Shadow.Virtual.SMRT.RayLengthScaleDirectional 을 사용하여 범위 제한의 정도를 조절할 수 있습니다.

일관되지 않은 반그림자

버추얼 섀도 맵은 첫 번째 뎁스 레이어만을 저장하여 첫 번째 이후 오클루더의 교차점이 단순 반복작업에서 누락되기 때문에 오클루더가 오버랩되는 경우 다양한 라이트 누수 아티팩트가 발생할 수 있습니다. 이렇게 라이트가 새는 유형은 오클루전 이전의 뎁스 씬을 바탕으로 첫 오클루더 이후의 뎁스를 추정하는 틈새 채우기 휴리스틱을 사용해 해결할 수 있습니다.

이는 라이팅 누수 문제를 해결할 때 유용하지만 라이트에 평행한 표면의 반그림자 크기를 축소시킵니다. 현재로서는 반그림자 크기를 적절하게 유지하는 것 외에 이 이펙트에 대처할 직접적인 방법이 없습니다.

vsm-smrt-inconsistent_penumbra.png

일관되지 않은 반그림자 섀도의 예시.

반그림자 아티팩트

기본으로 버추얼 섀도 맵은 레이 원본(리시버 픽셀) 주변에 샘플이 있다는 것만을 보장합니다. 알고리즘이 레이를 지나갈 때 섀도 데이터가 존재하지 않고 매핑되지 않은 페이지를 만날 수 있습니다. 이 임팩트를 줄이기 위해 페이지 매핑을 약간 확장하고 반복작업 도중에 여러 예비 전환을 마련하는 등 다양한 기술이 사용됩니다. 그럼에도 누락된 페이지로 인한 아티팩트가 특히 부드러운 반그림자로 확대된 화면의 가장자리에서 나타날 수 있습니다. 이러한 아티팩트는 섀도 영역에서 지저분하게 새는 라이트로 나타납니다. VSM의 다른 제한 사항과 마찬가지로 이 문제 또한 대체로 섀도 반그림자 수를 적절하게 유지하고 반그림자가 화면 대부분을 뒤덮는 정도로까지 확대하지 않으면 피할 수 있습니다.

디렉셔널 라이트 클립맵

단일 버추얼 섀도 맵은 넓은 영역을 뒤덮기에 해상도가 부족합니다. 디렉셔널 라이트는 카메라 주변으로 범위를 확장하는 클립맵 구조를 사용하며, 각 클립맵 레벨은 자체 16K VSM을 갖습니다. 각 클립맵 레벨의 해상도는 같지만 이전 클립맵의 두 배 반경을 커버합니다.

디렉셔널 라이트 클립맵 시각화

버추얼 섀도 맵 페이지 시각화

디렉셔널 라이트 클립맵 시각화

버추얼 섀도 맵 페이지 시각화

기본으로 클립맵 레벨 6부터 22까지는 할당된 버추얼 섀도 맵 페이지 테이블입니다. 이는 디폴트 세팅이 카메라 위치로부터 64cm(2^6)를 커버하는 가장 상세한 클립맵, 약 40km(2^22cm)를 커버하는 가장 넓은 클립맵을 갖는다는 뜻입니다. 버추얼 클립맵 레벨에 아무것도 없는 경우 비용이 경미하므로 이 기본값은 카메라 주변에서 해상도가 매우 높은 대규모 씬을 커버하는 데 좋습니다.

첫 번째 레벨과 마지막 레벨은 콘솔 변수 r.Shadow.Virtual.Clipmap.FirstLevelr.Shadow.Virtual.Clipmap.LastLevel 을 사용하여 조절할 수 있습니다.

주어진 픽셀에 할당된 해상도는 클립맵의 원점, 즉 카메라로부터 떨어진 거리의 함수입니다. 이는 콘솔 변수 r.Shadow.Virtual.ResolutionLodBiasDirectional 을 사용하는 섀도 엔진 퀄리티로 설정됩니다. 0의 값은 카메라의 원근 투영을 바탕으로 필요한 해상도를 선택합니다. 에일리어싱 투영(섀도가 라이트 방향과 거의 평행한 표면에 캐스트될 경우)은 고해상도에서도 여전히 가능하지만 해상도 바이어스를 통해 부분적으로 감소될 수 있습니다. 텍스처 밉 바이어스와 마찬가지로 값을 -1 낮추면 섀도 해상도가 두 배가 되며 그에 해당하는 퍼포먼스 절충이 발생합니다. 기본값이 -1.5인 에픽 섀도 엔진 퀄리티는 많은 씬에서 합리적인 밸런스를 제공합니다.

로컬 라이트

스포트 라이트는 클립맵 대신 단일 16K VSM과 밉 체인을 사용하여 섀도 레벨 오브 디테일을 처리합니다. 이와 유사하게 포인트 라이트는 16K VSM 큐브 맵을 각 면에 하나씩 사용합니다.

로컬 라이트는 기존 섀도 맵과 비교해 크게 높은 해상도를 제공합니다. 아주 큰 로컬 라이트로 버추얼 해상도 이상을 실행할 수 있지만 이 경우 가능한 곳에서는 디렉셔널 라이트를 사용하도록 주의해야 합니다.

스포트 라이트로 라이팅된 씬

스포트 라이트에 대한 버추얼 섀도 맵 페이지

화면 픽셀 크기를 섀도 맵 스페이스에 투영하여 적절한 밉 레벨을 선택합니다. 디렉셔널 라이트와 마찬가지로 섀도 엔진 퀄리티 세팅 또는 콘솔 변수 r.Shadow.Virtual.ResolutionLodBiasLocal 을 사용하여 해상도에 바이어스를 줄 수 있습니다.

라이트별 해상도 제어는 불가능하지만 추후 릴리즈에 추가될 수 있습니다.

코어스 페이지

렌더링이 필요한 페이지를 표시하는 주요 메서드로 뎁스 버퍼 분석이 사용됩니다. 하지만 볼류메트릭 포그 및 포워드 렌더링된 반투명 등 섀도를 더 임의적인 위치에서 샘플링해야 하는 시스템도 있습니다. 대다수 시스템은 다른 구조를 통해 필터링되고 블러 처리되는 저해상도 섀도 데이터만을 필요로 합니다.

이런 상황에서 섀도를 사용하려면 코어스 페이지(Coarse Page) 를 표시하여 최소한 샘플링 전체 영역에서 저해상도 섀도 데이터가 사용되도록 합니다. 로컬 라이트는 루트 밉 페이지를 표시하고 디렉셔널 라이트는 아주 낮은 디테일로 여러 페이지를 표시하여 약간의 코어스 클립맵을 형성합니다. 씬에 따라서 코어스 페이지는 퍼포먼스 문제를 일으킬 수 있습니다. 특히 나나이트가 아닌 다이내믹 지오메트리의 경우 더 그렇습니다. 사실상 저해상도 섀도를 아주 넓은 영역에 렌더링하는 것이므로 드로 콜 병목 구간을 유발할 수 있기 때문입니다.

콘솔 변수 r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0 을 사용하여 코어스 페이지에 비나나이트 오브젝트를 렌더링하는 것을 비활성화하여 실험해 보는 것이 좋습니다.

많은 씬, 특히 나나이트 지오메트리로 주로 구성된 씬에는 볼류메트릭 포그 및 유사한 대상에 비나나이트 오브젝트가 섀도를 캐스팅할 필요가 없습니다. 이를 비활성화하면 성능이 크게 향상될 수 있습니다.

로컬 라이트 코어스 페이지는 필요하지 않은 경우 r.Shadow.Virtual.MarkCoarsePagesLocal 로 끌 수 있습니다. 디렉셔널 라이트 코어스 페이지는 r.Shadow.Virtual.MarkCoarsePagesDirectional 로 끌 수 있으며, 아니면 코어스 페이지가 표시된 클립맵 레벨 범위를 r.Shadow.Virtual.FirstCoarseLevelr.Shadow.Virtual.LastCoarseLevel 로 수정할 수 있습니다.

향후 릴리즈에서는 지금처럼 과도하게 코어스 페이지를 사용하는 대신, 현지화된 페이지에 이 이펙트를 미리 직접 표시하는 세련된 솔루션이 추가될 것입니다.

시각화

버추얼 섀도 맵에 대한 시각화 옵션은 뷰 모드(View Modes) 드롭다운 메뉴를 이용해 버추얼 섀도 맵 을 선택하여 레벨 뷰포트에서 액세스할 수 있습니다.

레벨 뷰포트 버추얼 섀도 맵 뷰 모드 옵션

시각화 옵션은 다음과 같습니다.

시각화 이름

설명

섀도 마스크(Shadow Mask)

셰이딩에서 사용하는 최종 섀도 마스크입니다.

클립맵/밉 레벨(Clipmap/Mip Level)

디렉셔널 라이트용으로 선택된 클립맵 또는 로컬 라이트용 밉 레벨입니다.

버추얼 페이지(Virtual Page)

버추얼 페이지 어드레스를 시각화합니다.

저장된 페이지(Cached Page)

저장된 페이지는 초록색으로, 저장되지 않은 페이지는 빨간색으로 표시됩니다. 스태틱 페이지만 저장(다이내믹은 미저장)된 페이지는 파란색으로 표시됩니다.

기본으로 버추얼 섀도 맵 시각화는 디렉셔널 라이트의 결과를 표시합니다. 월드 아웃라이너 에서 라이트를 선택하여 해당 라이트의 시각화를 볼 수 있습니다.

또한 콘솔을 사용하여 시각화를 활성화할 수 있는데(Shipping 빌드에서는 예외), 이는 라이브 게임의 프로파일링 및 디버깅에 유용합니다. 에디터에서 설정된 사항이 있는 경우 에디터의 유저 인터페이스를 통한 모든 모드 선택을 오버라이드합니다.

시각화 이름

설명

r.Shadow.Virtual.Visualize [mode]

레벨 뷰포트 또는 콘솔 명령을 통해 뷰 모드 시각화가 버추얼 섀도 맵으로 설정되면 이 명령은 디스플레이할 채널을 지정합니다. "[mode]" 자리에 아래 이름을 사용하여 해당 시각화를 활성화합니다. Cachevpage 가 시각화에 사용되는 두 가지 일반적인 이름이며 none 은 VSM 시각화를 비활성화합니다.

  • mask

  • mip

  • vpage

  • cache

  • raycount

  • clipmapvirtual

ShowFlag.VisualizeVirtualShadowMap

시각화 모드가 지정된 경우 버추얼 섀도 맵 시각화를 활성화합니다.

r.Shadow.Virtual.Visualize.Layout

버추얼 섀도 맵 시각화에 대한 레이아웃을 선택합니다.

  • 0 은 전체화면

  • 1 은 섬네일

  • 2 는 분할 화면

r.Shadow.Virtual.Visualize.DumpLightNames

버추얼 섀도 맵을 사용하는 현재 라이트의 목록을 콘솔에 출력합니다.

일부 빌드/런타임 환경설정에서 라이트의 이름이 에디터에서의 이름과 다를 수 있습니다.

r.Shadow.Virtual.Visualize.LightName [light name]

이름별로 라이트를 지정합니다. 부분 또는 전체 일치가 허용됩니다.

이 콘솔 변수를 사용하여 선택된 라이트를 지우려면 전혀 일치하지 않는 라이트 이름을 지정합니다. 큰따옴표(")를 사용하는 것은 지정된 라이트가 없는 상태로 초기화할 수 있는 방법입니다.

시각화 모드 활성화는 버추얼 섀도 맵의 퍼포먼스에 작지만 측정 가능한 효과를 미칩니다. 퍼포먼스 프로파일링 전에 시각화를 비활성화해야 합니다.

캐싱

이전 프레임의 섀도 맵 페이지 재사용은 특히 복잡한 씬에서 버추얼 섀도 맵의 높은 퍼포먼스를 유지하는 데 매우 중요합니다. 캐싱은 기본으로 활성화되지만 콘솔 변수 r.Shadow.Virtual.Cache 0 을 통해 디버그 목적으로 비활성화할 수 있습니다.

페이지는 화면상의 픽셀에 대해서만 렌더링되므로, 디스오클루전의 움직임 때문에 카메라 비저빌리티를 변경하면 렌더링해야 할 새 페이지가 드러날 수 있습니다. 일반적으로 카메라 움직임이 적절하게 부드럽다면 새 페이지의 주요 소스가 되지는 않습니다. 주의해야 할 것들로는 오브젝트 근처의 빠른 움직임, 큰 디스오클루전, 카메라 컷 등이 있습니다.

대부분의 씬에서 가장 많은 작업 소스가 씬 지오메트리의 변화로 인해 다시 그려야 하는 섀도 맵 페이지로부터 옵니다. 저장 페이지 인밸리데이션의 일반적인 소스는 다음을 포함합니다.

  • 라이트 움직임 또는 회전은 해당 라이트의 모든 저장된 페이지를 인밸리데이션합니다.

  • 씬에서 움직이거나 추가 또는 제거되는 섀도를 캐스트하는 지오메트리는 라이트의 관점에서 바운딩 박스와 겹치는 페이지를 인밸리데이션합니다.

  • 여기에는 실제로 움직이지 않아도 렌더링 상태 인밸리데이션을 트리거하는 프리미티브 컴포넌트의 블루프린트 세팅 프로퍼티 등의 오브젝트가 포함될 수 있습니다.

  • 월드 포지션 오프셋(WPO) 또는 픽셀 뎁스 오프셋(PDO)과 같이 메시 포지션을 수정할 수 있는 머티리얼을 사용하는 지오메트리.

느리게 움직이는 라이트가 있거나 시간의 변화에 따라 움직이는 디렉셔널 라이트가 있는 경우 VSM 페이지는 전혀 저장되지 않습니다. 아주 사소한 방향의 차이는 알아볼 수 없으므로, 시간 변화와 같은 상황에서는 변화의 양을 아주 작게 양자화하여 저장된 페이지가 몇 프레임 동안 유지되게 합니다.

향후 릴리즈에서는 우선순위 시스템 및 프레임별 업데이트 예산을 추가하여 렌더링 섀도의 비용에 대한 미세한 조정이 가능하도록 함으로써 캐싱을 개선할 것입니다. 예를 들어 너무 많은 페이지에 업데이트가 필요한 경우 섀도 해상도를 일시적으로 낮출 수 있습니다.

캐시 인밸리데이션 관리하기

먼저 인밸리데이션을 시각화한 다음 그 원인을 찾아 줄이면 캐시 인밸리데이션을 줄일 수 있습니다. 저장된 페이지 시각화가 좋은 출발점입니다.

버추얼 섀도 맵 저장된 페이지 시각화

저장된 페이지 시각화

이 시각화에서 완전히 저장된 페이지는 녹색 으로 셰이딩됩니다. 새 페이지 또는 인밸리데이션된 페이지는 빨간색 으로 셰이딩됩니다. 카메라를 움직이면 화면 가장자리, 클립맵 경계 및 가려지지 않은 지오메트리 근처에 작은 빨간색 링이 보일 것입니다. 스태틱 카메라를 사용하면 대부분의 새 페이지에서 캐시 인밸리데이션이 발생합니다.

독립 스태틱 캐싱이 활성화된 경우(아래 참조) 부분 저장된 페이지(스태틱 부분만 유효함)는 파란색 으로 표시됩니다.

문제 영역이 확인되면 콘솔 변수 r.Shadow.Virtual.Cache.DrawInvalidatingBounds 1 을 사용하여 인밸리데이션의 원인이 되는 오브젝트 바운드의 시각화를 켜는 것이 유용한 경우가 많습니다. 이러한 오브젝트와 바운드를 검사하여 섀도를 인밸리데이션하는 오브젝트인지, 바운드가 가능한 만큼 타이트한지 확인합니다. 인밸리데이션 오브젝트가 잠재적으로 바운드 내에서 겹칠 수 있는 모든 페이지가 인밸리데이션되어야 하므로 낮은 라이트 각도와 결합된 약간 부풀려진 바운드는 불필요한 인밸리데이션을 유발할 수 있습니다.

버추얼 섀도 맵 저장된 페이지 인밸리데이션된 바운드 시각화

저장된 페이지 및 바운드 인밸리데이션 시각화

나나이트 오브젝트의 섀도에 전체적으로 있는 인밸리데이션은 건너뛸 수 있지만 비나나이트 오브젝트는 그렇지 않습니다. 이런 이유로 빌딩과 같이 큰 섀도를 캐스팅하는 오브젝트는 나나이트를 사용하도록 하는 것이 중요합니다.

복잡한 씬에서는 이러한 시각화를 사용해도 인밸리데이션의 원인을 정확히 찾기 어려울 수 있습니다. 도움이 될 수 있는 또 다른 도구로 표시(Show) > 시각화(Visualize) 의 레벨 뷰포트에 있는 VSM 인밸리데이션을 유발하는 지오메트리만 그리기(Draw only Geometry Causing VSM Invalidation) 시각화 모드입니다.

버추얼 섀도 맵 VSM 인밸리데이션을 유발하는 지오메트리만 그리기 시각화

활성화되면 캐시 인밸리데이션을 유발하지 않는 지오메트리는 숨겨집니다.

구현 디테일로 인해 VSM 인밸리데이션을 유발하는 지오메트리만 그리기(Draw Only Geometry Causing VSM Invalidation) 모드에서 별도의 렌더링 패스를 거치고 맨 위에 그려지는 섀도잉(파티클과 비주얼 이펙트 등)과 관련이 없는 오브젝트가 표시되는 경우가 있습니다.

메인 씬 렌더링이 어떤 페이지가 매핑 및 인밸리데이션되는지에 다르게 영향을 미치므로 이 시각화를 사용하는 동안에는 통계가 안정적이지 않습니다. 다른 시각화 모드로 시작한 다음 이 모드로 다시 확인하는 것이 좋습니다.

씬 캡처 컴포넌트에는 전체 캐시가 인밸리데이션될 수 있는 알려진 문제가 존재합니다.

비나나이트 디포메이션 및 폴리지

스켈레탈 애니메이션을 사용하여 디폼될 수 있는 지오메트리, 또는 월드 포지션 오프셋이나 픽셀 뎁스 오프셋을 사용하는 머티리얼은 항상 모든 프레임에서 저장된 페이지를 인밸리데이션합니다. 정의에 따라 이러한 경우는 더 많은 비용이 드는 나나이트가 아닐 것입니다. 따라서 이러한 기능이 조심스럽게 사용되고 바운드가 컨트롤되는지 확인하는 것이 매우 중요합니다.

그래스 및 폴리지와 같은 경우에는 컨택트 섀도만 사용하는 것으로 고해상도 섀도 맵을 충분히 대체합니다. 높은 디테일 섀도가 전경에 필요한 경우 퍼포먼스 비용 완화에 도움이 되도록 다음을 고려합니다.

  • 비나나이트 오브젝트는 r.Shadow.RadiusThreshold 와 같은 정규 섀도 CPU 컬링 세팅을 계속해서 준수합니다. 이를 사용하면 이러한 오브젝트를 버추얼 섀도 맵에 렌더링하는 비용을 제어하는 데 도움이 됩니다.

  • 폴리지가 많은 씬에서는 r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0 을 사용하여 코어스 페이지에서 비나나이트 오브젝트를 비활성화하는 것이 좋습니다. 또는 필요하지 않은 경우 코어스 페이지 전체 비활성화를 고려해 보세요.

  • 메시 LOD를 사용하여 이펙트가 더 이상 보이지 않는 거리에서 WPO/PDO를 사용하지 않는 머티리얼로 전환합니다. 경우에 따라 원거리에 있는 이러한 오브젝트에 대한 다이내믹 섀도 캐스팅을 끄고 스크린 스페이스 컨택트 섀도를 전적으로 활용하는 것도 가능합니다.

디렉셔널 라이트의 경우 사용할 수 있는 추가 옵션이 있습니다.

  • 디스턴스 필드 섀도는 라이트의 캐스케이드 섀도 맵 섹션에 의해 설정된 다이내믹 섀도 거리 무버블 라이트 를 벗어난 비나나이트 지오메트리를 대신합니다. 원거리에 있는 비나나이트 오브젝트에 대해 디스턴스 필드 섀도로 전환하면 이 지오메트리에 나나이트가 제공하는 미세한 LOD 스케일링이 없으므로 퍼포먼스가 크게 향상될 수 있습니다.

  • 경우에 따라 WPO/PDO를 제거하는 머티리얼 LOD를 생성하는 것이 효과적이지 않을 수 있지만 원거리에서 이러한 트랜스포메이션의 최종 이펙트는 작습니다. r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange 를 사용하여 이러한 머티리얼로부터의 캐시 인밸리데이션이 무시되는 거리(센티미터 단위)를 설정합니다.

    이로 인해 섀도에 ‘얼룩'이 생기고 모션이 큰 경우 오브젝트의 셀프 섀도가 부정확할 수 있습니다. 하지만 이 아티팩트가 퍼포먼스와 편의성의 합리적인 절충인 경우가 많습니다.

독립 스태틱 캐싱

이 기능은 실험단계 입니다.

많은 씬은 절대 움직이지 않는 많은 스태틱 지오메트리와 아주 작은 양의 다이내믹(무버블) 지오메트리로 구성됩니다. 기본으로, 상대적으로 저렴한 다이내믹 지오메트리가 페이지를 인밸리데이션하고, 이로 인해 다이내믹 부분 업데이트를 위해 많은 비용이 드는 스태틱 지오메트리가 다시 렌더링됩니다.

이러한 경우 최적화 개선을 위해 r.Shadow.Virtual.Cache.StaticSeparate 1 을 사용하여 선택적으로 독립 스태틱 캐싱(Separate Static Caching) 모드를 활성화할 수 있습니다. 이 모드는 지정된 페이지의 스태틱 지오메트리가 다이내믹 지오메트리와는 독립적으로 캐싱될 수 있도록 물리적 페이지 풀의 크기를 2배 늘립니다. 다이내믹 지오메트리가 움직여도 스태틱 지오메트리를 다시 그릴 필요가 없습니다. 대신 저장된 스태틱 페이지가 맨 위에 적은 비용으로 합성될 수 있습니다. 에인션트의 협곡 샘플 프로젝트와 같은 경우 다이내믹 엘리먼트가 상대적으로 저렴하면서 스태틱 터레인의 비용이 아주 높으므로 퍼포먼스 최적화가 커질 수 있습니다.

이 모드를 사용하는 동안 씬에서 액터의 모빌리티를 정확하게 설정하는 것이 중요합니다. 특히 스태틱 모빌리티로 설정된 액터가 움직이는 경우(또는 월드 포지션 오프셋을 사용하는 머티리얼이나 지원되지 않는 머티리얼을 사용하는 경우) 다이내믹 및 스태틱 저장된 페이지를 모두 인밸리데이션하여 게인 없이 오버헤드만 발생합니다. 반대로 너무 많은 비용의 지오메트리가 무버블 모빌리티로 설정된 경우 독립적으로 캐싱하는 데 따른 이점이 많지 않을 수 있습니다.

버추얼 섀도 맵 통계는 스태틱 캐싱이 얼마나 잘 작동하고 있는지 파악할 수 있는 대략적 개요를 얻을 수 있는 좋은 방법입니다. 특히 ‘인밸리데이션된' 스태틱 페이지의 수는 0에 가까워야 합니다. 스태틱 캐시를 주기적으로 인밸리데이션하고 이를 무버블로 전환하는 인스턴스를 찾는 것이 스태틱 캐시의 유효성을 유지하는 데 있어 중요한 방법입니다.

나나이트에는 월드의 오브젝트 모빌리티를 확인하는 데 도움이 되는 고급 시각화 모드가 포함되어 있으며, 이는 버추얼 섀도 맵에도 유용합니다.

버추얼 섀도 맵 나나이트 VSM 스태틱 시각화

나나이트의 고급 버추얼 섀도 맵 스태틱 시각화 모드

이 시각화 모드는 두 가지 방법 중 하나를 사용하여 활성화할 수 있습니다.

  • r.Nanite.Visualize.Advanced 1 을 사용하여 나나이트의 고급 시각화 옵션을 활성화한 다음 레벨 뷰포트를 사용하여 뷰 모드(View Mode) > 나나이트 시각화(Nanite Visualization) 를 선택하고 시각화 옵션 목록에서 버추얼 섀도 맵 스태틱(Virtual Shadow Map Static) 을 선택합니다.

    이미지를 클릭하면 최대 크기로 볼 수 있습니다.

  • 또는 r.Nanite.Visualize vsmstatic 명령을 사용하여 버추얼 섀도 맵 스태틱 시각화를 활성화할 수 있습니다.

GPU 프로파일링 및 최적화

언리얼 엔진은 프로젝트에서 퍼포먼스를 체크하는 툴을 제공합니다. GPU 프로파일링 또는 플랫폼별 툴은 퍼포먼스 문제를 해결하고 디버깅하기에 좋은 시작점입니다.

VSM 비용이 높아지는 두 가지 주요 분야는 섀도 뎁스와 섀도 프로젝션(라이트 아래에 있음)입니다. 각 카테고리 내에서는 서로에 대해 비교적 독립적으로 절충할 수 있습니다.

stat gpu 및 관련된 카운터 등 통계 표시에 사용되는 명령은 특히 프로젝트 퍼포먼스가 CPU 바운드인 경우 타이밍이 안정적이지 않다는 점을 유의해야 합니다.

섀도 뎁스

섀도 뎁스(Shadow Depth) 카테고리는 지오메트리를 섀도 맵으로 렌더링하는 비용을 나타냅니다.

GPU 프로파일 섀도 뎁스

  • RenderVirtualShadowMaps(Nanite) 는 VSM으로 렌더링된 모든 나나이트 지오메트리를 포함합니다. 모든 디렉셔널 라이트는 단일 나나이트 패스로 렌더링되며, 모든 로컬 라이트는 두 번째 패스에서 렌더링됩니다.

  • RenderVirtualShadowMaps(Non-Nanite) 는 비나나이트 지오메트리의 렌더링을 처리합니다. 각 가시 라이트는 기존의 섀도 맵 렌더링과 마찬가지로 다양한 오브젝트 및 인스턴스에 대한 개별 드로 콜과 함께 별도의 패스를 갖습니다. VSM 패스를 따르는 아틀라스(Atlas)큐브맵(Cubemap) 은 다른 유사 패스와 함께 기존 섀도 맵을 렌더링합니다. 아직 일부 지오메트리 타입은 버추얼 섀도 맵 경로에서 지원되지 않으며, 이런 타입은 이전 경로를 따릅니다. 지원되지 않는 지오메트리 캐스팅 섀도가 없는 경우 이러한 패스는 새도 맵 스토리지를 실행 또는 할당하지 않습니다. 이러한 패스 및 관련 오버헤드는 CVar r.Shadow.Virtual.ForceOnlyVirtualShadowMaps 1 을 사용하여 전체적으로 비활성화할 수 있습니다. 이 경우 지원되지 않는 지오메트리 유형은 섀도를 캐스트하지 않습니다.

VSM의 섀도 뎁스 패스의 비용은 렌더링이 필요한 섀도 페이지 및 지오메트리의 수와 직접적으로 관련되어 있습니다. 비나나이트 지오메트리는 나나이트 지오메트리보다 VSM 렌더링 비용이 높습니다. 따라서 낮은 폴리 메시를 포함하여 지원되는 모든 지오메트리에서 나나이트를 활성화하는 것이 좋습니다. 유일한 예외는 나나이트 가상화 지오메트리에서 아직 지원하지 않는 기능입니다.

그려지는 페이지 수 이해하기

사용되는 VSM 페이지에 대한 화면상의 통계는 페이지 사용량, 잠재적 문제 해결법 위치에 대한 정보를 제공합니다.

통계를 활성화하려면 다음 콘솔 변수를 사용합니다.

  • r.ShaderPrintEnable 1

  • r.Shadow.Virtual.ShowStats 1 (또는 2를 사용하여 페이지 통계만 표시)

버추얼 섀도 맵 페이지 통계

통계 이름

설명

물리적 페이지(Physical Pages)

버추얼 섀도 맵이 사용할 수 있는 물리적 페이지의 최대 수입니다.

할당됨(Allocated)

현재 뷰에 의해 요청되는 섀도 맵 페이지의 총 수입니다. 항상 최대 페이지보다 적어야 하며, 그렇지 않으면 손상이 발생할 수 있습니다. (아래에 있는 문제 및 제한 사항 섹션을 참조하세요.)

지워짐(Cleared)

현재 프레임에서 지워진 새 페이지의 수입니다.

저장됨(Cached)

버추얼 섀도 맵 페이지 캐시에 이미 있어서 현재 프레임에서 렌더링할 필요가 없는 페이지 수입니다. 저장된 페이지의 비용은 매우 낮으며 퍼포먼스에 거의 영향을 미치지 않습니다. 독립 스태틱 캐싱이 활성화되면 저장된 스태틱 페이지와 저장된 다이내믹 페이지로 분할됩니다.

인밸리데이션됨(Invalidated)

이전 프레임에서 저장될 수 있었지만 다이내믹 지오메트리에 의해 인밸리데이션된 페이지의 수입니다. 이 페이지들은 가려주던 것이 움직였기 때문에 다시 렌더링되어야 합니다. 독립 스태틱 캐싱을 사용할 때 스태틱 페이지의 인밸리데이션 수는 0이거나 이에 가까워야 합니다. 인밸리데이션되는 스태틱 페이지 수가 많은 경우 인밸리데이션을 유발하는 액터가 무버블로 전환되어야 합니다.

병합됨(Merged)

독립 스태틱 캐싱이 활성화될 때 이 숫자는 (저장되지 않은 페이지로 인해) 병합된 다이내믹 및 스태택 페이지의 수를 나타냅니다.

총 페이지 수는 화면상의 각 픽셀에 영향을 미치는 라이트 수의 평균 함수입니다. 화면 해상도, 섀도 해상도(해상도 LOD 바이어스에 대한 콘솔 변수 사용), 라이트 크기, 섀도 캐스팅 라이트의 수를 줄여서 낮출 수 있습니다.

섀도 뎁스의 퍼포먼스가 낮은 경우, 일반적으로 많은 수의 페이지가 사용되거나 VSM 캐싱을 악화시키는 다이내믹 인밸리데이션이 많이 발생하는 것과 관련이 있습니다. 캐시 인밸리데이션 진단 및 감소에 대한 자세한 내용은 캐싱 섹션을 참조하세요.

비나나이트 퍼포먼스 개선

캐싱 향상 외에 비나나이트 섀도 렌더링의 퍼포먼스를 개선하는 몇 가지 방법이 있습니다.

비나나이트 오브젝트 퍼포먼스 개선을 위해 다음을 고려하세요.

  • 프로젝트에 대해 가능한 많은 지오메트리에서 나나이트를 활성화합니다.

    • 나나이트 지오메트리는 버추얼 섀도 맵에 더 효율적으로 렌더링되며 폴리곤 수와 무관하게 모든 사례에서 선호되어야 합니다.

    • 나나이트 지오메트리는 비나나이트 지오메트리를 가리고 허위 캐시 인밸리데이션을 방지할 수 있습니다. 따라서 비나나이트 오브젝트만 나나이트 자체의 지원을 받지 않아야 합니다(예: 오브젝트 디포밍(스킨을 입힌 메시), 또는 월드 포지션 오프셋(WPO)과 픽셀 뎁스 오프셋(PDO)을 사용하는 머티리얼).

  • 비나나이트 오브젝트에는 전체 메시 LOD 계층구조가 설정되어야 합니다.

    • 비나나이트 메시에 LOD가 설정되어 있는 것이 중요하며 그렇지 않으면 작은 페이지로 렌더링할 때 막대한 비용이 듭니다.

    • 가능한 경우 이펙트가 보이는 거리를 벗어난 비디포밍 메시(WPO/PDO 머티리얼 없음)로 전환하는 것이 좋습니다.

  • CPU 컬링 콘솔 변수는 여전히 비나나이트 메시를 버추얼 섀도 맵으로 렌더링하는 데 있어 유용합니다.

    • 콘솔 변수 r.Shadow.RadiusThreshold 를 사용하여 버추얼 섀도 맵으로 렌더링되는 비나나이트 오브젝트의 CPU 컬링 값을 조정합니다. 원거리에 있는 작은 오브젝트의 비용 제어에 도움이 될 수 있습니다.

  • 비나나이트 오브젝트의 원거리 섀도잉에 디스턴스 필드 섀도를 사용합니다.

    • 디렉셔널 라이트의 경우 캐스케이드 섀도 맵과 마찬가지로 어느 정도 거리를 벗어난 디스턴스 필드 섀도로 전환해야 하는 경우가 많습니다. 버추얼 섀도 맵을 사용하면 비나나이트 지오메트리만 디스턴스 필드 섀도 사용으로 전환되고 나나이트 지오메트리는 전체 디테일의 섀도를 계속 갖게 됩니다.

  • 코어스 페이지에서 비나나이트 지오메트리를 비활성화하면 퍼포먼스가 증가할 수 있습니다.

    • 코어스 페이지에서 비나나이트 지오메트리를 비활성화하면 비나나이트 지오메트리가 일반적으로 큰 페이지로 렌더링하는 데 비효율적이므로 퍼포먼스 게인이 클 수 있습니다.

버추얼 섀도 맵 통계에서 비나나이트 인스턴스 수에 대한 인사이트를 제공할 수 있습니다.

버추얼 섀도 맵 페이지 통계

통계 이름

설명

총(Total)

GPU 컬링에 대한 총 비나나이트 인스턴스 입력의 수입니다. 인스턴스는 각 버추얼 섀도 맵 밉/클립맵 레벨에 대해 별도로 컬링됩니다. 예를 들어 하나의 스태틱 메시 인스턴스에는 교차하는 각 포인트 라이트에 대해 48개의 인스턴스(8개 밉 레벨 * 6개 큐브맵 페이스), 각 디렉셔널 라이트에 대해 17개의 인스턴스(기본 환경설정에 17개의 클립맵 레벨이 있음) 등이 있을 수 있습니다.

그려짐(Drawn)

컬링 이후 모든 버추얼 섀도 맵으로 실제로 그려지는 인스턴스의 수입니다.

컬링된 HZB(HZB Culled)

라이트의 관점에서 (나나이트 지오메트리에 의해) 가려져서 제거된 인스턴스의 수입니다.

컬링된 페이지 마스크(Page Mask Culled)

필수 페이지와 겹치지 않아 제거된 인스턴스의 수입니다. 예를 들어 이는 이미 저장된 영역에 그릴 때 제거되는 스태틱 메시를 나타냅니다.

컬링된 비어 있는 렉트(Empty Rect Culled)

필수 페이지와 겹치지 않아 제거된 인스턴스의 수입니다. 예를 들어 이는 이미 저장된 영역에 그릴 때 제거되는 스태틱 메시를 나타냅니다.

컬링된 프러스텀(Frustum Culled*)

뷰 프러스텀 외부에 있는 인스턴스의 수입니다.

섀도 프로젝션

섀도 프로젝션 카테고리는 섀도 맵 레이 트레이싱을 사용하는 섀도 맵 샘플링의 비용입니다. 이 패스는 Lights | DirectLighting | UnbatchedLights 에 위치해 있으며 일반적으로 관련된 라이트당 하나의 VSM 프로젝션이 있습니다. 가장 비용이 높은 패스는 VirtualShadowMapProjection 의 주요 SMRT 루프입니다. 나머지는 비용이 상대적으로 낮습니다.

프로젝션 패스가 RayCount:Adaptive 대신 RayCount:Static 으로 라벨이 지정된 경우 느린 경로를 선택합니다.

이 섹션에 설명된 VSM 프로젝션 패스는 다음 섹션에서 설명하는 실험단계 기능 원 패스 프로젝션(One Pass Projection)과 다릅니다.

GPU 프로파일 섀도 프로젝션

섀도 프로젝션은 화면에서 사용되는 섀도 맵 샘플의 총 수를 나타내는 함수이며, 퍼포먼스는 페이지 또는 캐싱의 수에 의존하지 않습니다.

SMRT가 사용될 때는 다음 요소가 영향을 미칩니다.

  • 평균 픽셀당 라이트

    • 라이트가 화면에서 많은 영역에 닿을수록 렌더링 비용이 높아집니다. 화면상에서 적은 영역을 덮는 픽셀은 비용이 낮지만 라이트당 고정된 비용이 있습니다.

    • 여러 개의 거대 라이트로 화면의 픽셀 대부분을 덮는 일은 피해야 합니다.

  • 픽셀당 레이

    • 적응형 레이 수로 인해 퍼포먼스에 영향을 미치는 섀도의 가시적인 부드러움입니다. 레이 또는 샘플 수를 줄이기 전에 로컬 라이트의 소스 반경 또는 디렉셔널 라이트의 소스 각도를 줄여 보세요.

  • 레이당 샘플

섀도 엔진 퀄리티 설정에 의해 설정되었지만 필요한 경우 추가로 조정할 수 있습니다. 자세한 정보는 이 페이지의 섀도 맵 레이 트레이싱 섹션을 참조하세요.

일반적으로 섀도 프로젝션 비용은 섀도 뎁스 비용보다 제어(퀄리티와 노이즈 사이에서 절충)하기 쉽습니다.

원 패스 프로젝션

이 기능은 실험단계입니다. 이 섹션의 콘솔 변수 이름은 변경될 가능성이 높습니다.

작은 라이트는 비용이 더 낮지만 여전히 고정된 패스 오버헤드를 갖습니다. 이를 해결하기 위해 씬 내 로컬 라이트의 대부분이 하나의 패스에서 섀도를 효율적으로 평가하는 단일 패스 섀도 프로젝션을 개발하고 있습니다. 이런 라이트의 섀도 기여는 클러스터 셰이딩을 통해 한 번에 적용될 수 있습니다.

이 경로는 콘솔 변수 r.UseClusteredDeferredShading 1r.Shadow.Virtual.OnePassProjection 1 을 통해 활성화됩니다. 작은 로컬 라이트가 많은 씬의 경우 이를 통해 퍼포먼스를 상당히 향상할 수 있습니다.

다음과 같은 특정 라이트 기능을 사용하면 원 패스 프로젝션이 활성화되어도 라이트가 일괄 처리되지 않습니다.

  • 텍스처 프로파일

  • 라이트 함수

  • 라이팅 채널

  • 렉트 라이트

  • 디렉셔널 라이트(전체화면을 커버하므로 일괄 처리에 따른 이점이 없음)

아래 캡처에서 왼쪽은 라이트별로 발생하는 섀도 프로젝션 패스, 오른쪽은 원 패스 프로젝션입니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

왼쪽의 디폴트 경로에서 각 로컬 라이트는 라이트당 여러 개의 패스와 함께 하나씩 누적됩니다. 작은 화면 영역을 커버하는 작은 라이트에는 비효율적입니다.

오른쪽의 새 경로에서 그림자가 지는 모든 로컬 라이트가 단일 클러스터 셰이딩 패스에서 함께 일괄 처리됩니다(BatchedLights ). 디렉셔널 라이트는 별도의 패스에서 이루어지며, 전체 스크린을 커버하므로 이는 일괄 처리의 이점이 아닙니다.

각 로컬 라이트는 개별적으로 반투명 볼륨에 주입됩니다. 프로젝션에 비해 퍼포먼스에 있어서는 문제가 적지만 향후 함께 일괄 처리될 가능성이 높습니다.

원 패스 프로젝션이 활성화되면 r.Shadow.Virtual.OnePassProjection.MaxLightsPerPixel 을 기본값 16에서 조정함으로써 픽셀별로 완전히 필터링된 그림자가 진 라이트의 수를 제한할 수 있습니다. 이는 퍼포먼스 제어에도 유용하고 소량의 일시적인 그래픽 메모리를 절약할 수 있습니다.

지정된 픽셀(또는 실제로 클러스터 디퍼드 셰이딩 파일)에서 그림자가 진 라이트가 최대 수보다 많은 경우 비용이 높지 않은 싱글 하드 섀도 룩업을 사용하여 추가로 라이트에 그림자가 지게 할 수 있습니다. 값이 너무 적극적으로 설정되면 시각적 단절을 유발할 수 있지만 수를 벗어난 라이트에 대한 섀도를 전체적으로 비활성화하는 것보다는 양호합니다.

이 패스는 개발 중이며 디폴트로 활성화되지 않습니다. 로컬 라이트에 (씬에서 지원되지 않는 일부 지오메트리 유형으로 인해) 버추얼 섀도 맵과 클래식 섀도 맵이 모두 있을 때 원 패스 프로젝션 경로에서 후자를 무시하여 이러한 섀도가 사라질 위험이 있습니다.

r.Shadow.Virtual.ForceOnlyVirtualShadowMaps 를 이미 사용 중인 경우 원 패스 프로젝션을 활성화하는 것이 안전합니다. 현재 제한이 해소되면 사용된 디폴트 경로가 될 가능성이 높습니다.

지원되는 플랫폼

버추얼 섀도 맵은 현재 PlayStation 5, Xbox Series S|X, 사양을 충족하는 그래픽 카드가 탑재되고 최신 DirectX 12 드라이버를 사용하는 PC에서 지원됩니다.

  • NVIDIA: Maxwell 세대 카드 이상

  • AMD: GCN 세대 카드 이상

  • DirectX 12 Agility SDK 지원이 포함된 Windows 10 이상의 모든 버전(버전 1909.1350 이상) 및 Windows 11이 지원됩니다.

    • Windows 10 버전 1909 — 리비전 번호가 .1350을 초과하거나 같아야 합니다.

    • Windows 10 버전 2004 및 20H2 — 리비전 번호가 .789를 초과하거나 같아야 합니다.

    • DirectX 12(셰이더 모델 6.6 atomics 포함) 또는 Vulkan(VK_KHR_shader_atomic_int64)

  • 최신 그래픽 드라이버

문제 및 제한 사항

버추얼 섀도 맵은 아직 개발 중입니다. 현재 알려진 문제와 제한 사항이 몇 가지 있으며, 이 기능은 현재 고사양 컴퓨터 및 차세대 콘솔을 대상으로 하고 있습니다.

여러 라이트의 퍼포먼스

작은 로컬 라이트가 많은 씬에서의 퍼포먼스는 여전히 진행 중인 작업입니다. 현재 최적의 전략은 원 패스 프로젝션을 활성화하고 인밸리데이션에 주의하여 가능한 많은 페이지의 캐싱을 유지하는 것입니다. 여러 개의 로컬 라이트는 비나나이트 지오메트리보다 나나이트 지오메트리에서 퍼포먼스가 더 뛰어나므로 원거리에 있는 비나나이트 지오메트리에서 적극적인 컬링 또는 섀도 캐스팅 비활성화가 많은 도움이 될 수 있습니다. 경우에 따라 멀리 있는 라이트에서의 다이내믹 섀도 캐스팅을 전체적으로 비활성화하고 스크린 스페이스 컨택트 섀도만 전적으로 활용하는 것이 바람직할 수 있습니다.

향후에는 알고리즘 강화와 퀄리티 절충은 물론 이러한 상황에서의 스로틀링 업데이트를 위해 컨트롤이 개선될 것입니다.

로우 폴리 지오메트리

높은 커버처와 스무드 노멀을 사용하는 로우 폴리 지오메트리에서 아티팩트가 보일 수 있습니다. 이를 ‘섀도 터미네이터 문제'라고 합니다. 레이 트레이싱과 기타 높은 정확도의 가시성 쿼리에서 발생하기도 합니다. 이 문제는 실제 로우 폴리 지오메트리와 ‘스무드' 셰이딩 노멀 사이의 불일치에서 비롯됩니다. 터미네이터 근처의 영역에서 이러한 페이스 중 일부가 지오메트리 상 섀도 안에 있지만 비지오메트리 셰이딩 노멀이 라이트를 살짝 마주합니다. 섀도 룩업에 대한 노멀 기반 바이어스를 사용하여 이 아티팩트를 해결하는 것이 일반적입니다. 이 특정 아티팩트는 버추얼 섀도 맵으로 더 확실하게 확인할 수 있는데, 나나이트 지오메트리에서 높은 디테일의 섀도를 제공하도록 디폴트로 설정되어 있기 때문입니다.

이를 해결하는 최선의 방법은 이러한 오브젝트/영역에서 폴리곤 수를 늘리는 것입니다. 지오메트리와 셰이딩 노멀 사이의 다이버전스를 제한하면 섀도 퀄리티에 부정적인 영향을 미치지 않으면서 이러한 아티팩트를 줄이거나 없앨 수 있습니다. 나나이트를 사용하면 직관적이면서 더 적은 비용으로 더 많은 폴리곤을 추가할 수 있습니다. 문제가 되는 오브젝트에서 나나이트를 사용할 수 없는 경우 더 높은 디테일 LOD(레벨 오브 디테일)를 추가하는 것이 효과적인 경우가 많은데, 오브젝트가 카메라 근처에 있을 때 이러한 아티팩트가 대체로 보이기 때문입니다.

지오메트리를 추가할 수 없는 경우 버추얼 섀도 맵 노멀 바이어스는 r.Shadow.Virtual.NormalBias (기본값 0.5)를 사용하여 늘릴 수 있습니다. 씬 전체의 섀도 퀄리티에 부정적인 영향을 미치므로 콘텐츠 조정이 불가능한 경우, 특히 미세한 디테일의 영역에서 이를 고려해야 합니다.

아래 예시에서 아티팩트는 배경에 높은 디테일 지오메트리가 있는 카메라 근처의 낮은 폴리곤 구체에서 보입니다. 구체에 폴리곤을 추가하면 배경의 디테일한 랜드스케이프에 부정적인 영향을 미치지 않고 아티팩트를 개선합니다.

낮은 폴리곤 지오메트리 | 기본 노멀 바이어스(0.5)

높은 폴리곤 지오메트리 | 기본 노멀 바이어스(0.5)

바이어스를 조정하면 아티팩트도 개선되지만 배경 지오메트리에서 미세한 디테일을 가시적으로 잃게 됩니다.

낮은 폴리곤 지오메트리 | 기본 노멀 바이어스(0.5)

낮은 폴리곤 지오메트리 | 증가한 노멀 바이어스(1.0)

가상 현실

가상 현실은 버추얼 섀도 맵에서 아직 완전히 지원되지 않습니다. 오른쪽 눈에 디렉셔널 라이트가 있는 아티팩트가 있을 가능성이 있습니다.

화면 분할

화면 분할은 최소한의 테스트를 받았으며 퍼포먼스가 좋지 않을 수 있습니다.

물리적 페이지 풀의 오버플로

버추얼 섀도 맵을 사용하면 모든 라이트에 대해 씬에 있는 모든 섀도 데이터가 하나의 큰 텍스처 풀에 저장됩니다. 기본 풀 크기는 섀도 엔진 퀄리티 세팅의 영향을 받지만 고해상도 섀도를 사용하는 많은 라이트를 사용하여 씬에서 조정해야 할 수 있습니다.

또는 저사양의 하드웨어에서 비디오 메모리 절감을 위해 조정해야 할 수도 있습니다.

페이지 풀 크기는 r.Shadow.Virtual.MaxPhysicalPages 를 사용하여 조정할 수 있습니다. r.ShaderPrintEnable 1r.Shadow.Virtual.ShowStats 2 를 연속으로 사용하여 버추얼 섀도 맵 통계를 활성화하면 현재 페이지 풀 사용에 관한 통계가 표시됩니다.

VSM 물리적 페이지 통계

버추얼 섀도 맵 화면 통계의 현재 페이지 풀 사용 예시.

페이지 의 수가 최대 페이지 를 초과하는 경우 손상이 발생하는데, 경우에 따라 체커보드 패턴으로 나타나거나 섀도가 손상 또는 누락됩니다. 섀도 페이지 풀 오버플로가 발생하는 경우 화면과 로그에 경고가 표시됩니다.

최대 페이지 초과 아티팩트

페이지 풀의 페이지 수 초과에 따른 손상된 버추얼 섀도 맵의 예시.

이 경우 페이지 풀의 크기를 늘리거나 섀도 해상도 또는 버추얼 섀도 맵 캐스팅 라이트의 수를 줄입니다.

씬 캡처

경우에 따라 씬 캡처 컴포넌트로 인해 버추얼 섀도 맵 캐시 전체가 인밸리데이션될 수 있습니다. 일반적인 증상으로는 버추얼 섀도 맵 통계의 인밸리데이션 이 낮고, 저장된 페이지 역시 낮거나 간혹 0을 나타내기도 하며, 저장된 페이지 시각화가 균일한 빨간색을 나타내는 현상이 있습니다.

이 문제가 발생하면 씬 캡처 액터가 문제를 유발하는지 확인할 수 있도록 씬에서 씬 캡처 액터를 숨기거나 제거해 보시기 바랍니다.

현재 씬 캡처 비활성화 이외에는 이 문제를 피할 수 있는 다른 방법이 없습니다.

머티리얼

단순한 서브서피스 머티리얼만 지원됩니다. 서브서피스 프로파일과 투과는 아직 구현되지 않았습니다. 이를 사용하는 머티리얼은 마치 불투명인 것처럼 섀도 처리됩니다.

섀도 해상도

버추얼 섀도 맵은 기존 섀도 맵과 비교해 상당한 해상도 증가를 보여주지만 얕은 라이트 각도(또는 에일리어싱 투영) 및 아주 큰 로컬 라이트가 사용 가능한 버추얼 해상도를 소진시킬 수 있습니다. 이 경우 그 자체가 박스 형태의 섀도로 나타나고 지오메트리 표면에 따른 바이어스 문제가 발생할 수 있습니다.

디렉셔널 라이트 클립맵은 해상도 소진 문제에 훨씬 덜 민감하지만, 마찬가지로 매우 좁은 카메라 필드 오브 뷰에 의해 소진될 수 있습니다.

섀도 맵과 에일리어싱 투영 문제를 해결하는 단순한 솔루션은 없습니다. 버추얼 섀도 맵을 사용하는 경우에도 최악의 상황을 피하고 퍼포먼스와 해상도의 균형을 맞출 수 있도록 주의를 기울여야 합니다.

맵 체크 경고

버추얼 섀도 맵은 일부 부정확한 맵 체크 경고를 일으킵니다.

  • 라이팅을 다시 빌드해야 합니다 메시지는 버추얼 섀도 맵이 활성화된 경우 표시되지 않습니다. 그러나 루멘 글로벌 일루미네이션 및 리플렉션 기능을 사용하지 않는 경우에는 라이팅을 다시 빌드해야 하는 경우가 있습니다. 스테이셔너리 다이렉트 라이팅이 버추얼 섀도 맵 활성화로 인해 다이내믹해져도 스테이셔너리 간접광은 여전히 구워진 상태입니다.

  • 프리섀도 관련 경고는 버추얼 섀도 맵 사용 시에 관련이 없으므로 무시해도 됩니다.