Unreal

[UE] 동적 해상도

굥굔 2023. 9. 1. 16:44

https://docs.unrealengine.com/5.0/ko/dynamic-resolution-in-unreal-engine/

 

동적 해상도

언리얼 엔진 의 Dynamic Resolution, 동적 해상도 시스템 개요입니다.

docs.unrealengine.com


동적 해상도

렌더링 파이프라인 최적화 3가지 중 하나.

핵심 아이디어 : 네이티브 해상도로 렌더링하지 않고 렌더링 해상도를 낮춘 뒤, 스케일을 키우되 시각적 충실도는 네이티브 해상도와 동일한 수준으로 (어떻게..?) 유지할 수 있도록 렌더링 파이프라인을 변경하여 퍼포먼스를 높임.

 

Dynamic Resolution (동적 해상도)는 이전 프레임의 GPU 작업 부하에 따라 1차 스크린 퍼센티지를 조정. 우선 과도하게 렌더링이 한 프레임은 되어야 함. 해상도 조정이 필요한 경우 휴리스틱에 기반.

휴리스틱이란 의미를 사전에서 찾아보면 '시간이나 정보가 불충분하여 합리적인 판단을 할 수 없거나, 굳이 체계적이고 합리적인 판단을 할 필요가 없는 상황에서 신속하게 사용하는 어림짐작의 기술 ' (어림짐작..)

화면에 오브젝트가 갑자기 많이 잡히거나 프레임에 비싼 이펙트가 들어오면 GPU렌더 시간이 늘어나게 되고 이는 화면 해상도를 낮추게 된다. 전에 GPU 병목 현상을 직접 알아봤다.

 

코드를 통해 활성화 가능

GEngine->GetDynamicResolutionStatus()->SetEnabled(true);

활성화를 하면 stat unit 콘솔 명령어를 실행했을 때 DynRes 부분도 활성화 된다.

스크린 퍼센테이지로 보인다.

 

동적 해상도 활성화 이후, 콘솔 명령어로 스크린 퍼센티지 및 해상도를 낮추기 전까지 사용할 최대 예산 설정. 안 하면 기본 값 사용.

아래와 같은 콘솔 명령어 존재함.

콘솔 변수  기본값 설명
r.DynamicRes.MinScreenPercentage 50 스크린 퍼센티지 최소치를 설정합니다.
r.DynamicRes.MaxScreenPercentage 100 렌더 타깃 할당에 사용되는 1차 스크린 퍼센티지 최대치를 설정합니다.
r.DynamicRes.FrameTimeBudget 33.3 프레임 예산을 (밀리초 단위로) 설정합니다.

 

동적 해상도 크루즈

비행기가 이상적인 속도로 목적지에 도달하기 위해 자유롭게 이동할 수 있는 순항(크루즈) 범위라고 생각하면 된다.

번호 콘솔 변수 설명
1   r.DynamicRes.FrameTimeBudget 프레임 시간 예산 - 프레임의 시간 예산으로 밀리초(ms) 단위입니다.
2 r.DynamicRes.TargetedGPUHeadRoom** 목표 GPU 여유 공간 - GPU 에 남은 공간이 이 밑으로 떨어지면 늘려 예산 초과를 방지합니다 (프레임 예산 백분율 단위입니다). 출시 플랫폼 또는 활성화한 렌더링 기능에 따라 달라질 수 있습니다. 예를 들어 모션 블러는 비용에 여유 공간이 있어야 카메라 이동의 빠른 회전을 처리할 수 있습니다.
3 r.DynamicRes.ChangePercentageThreshold** 퍼센티지 변화 한계치 - 퍼센티지 변화량이 최소 이 이상 되어야 실제 할당 크기를 조정합니다. 해상도 크기가 매우 비슷한데도 계속 바뀌지 않도록 하는 데 좋습니다. 값이 너무 작으면 해상도가 계속 바뀔 수 있고, 너무 크면 GPU 예산 초과 위험이 높아집니다.
4 r.DynamicRes.MinResolutionChangePeriod** 최소 해상도 변경 주기 - 최소 이 프레임 수를 넘으면 해상도 변경을 허용합니다. 이 명령에는 여러가지 용도가 있습니다. 측정 노이즈에도 불구하고 지정한 1차 스크린 퍼센티지로 GPU 소모를 모델링하는 휴리스틱 신뢰성 향상일 수도 있고, 템포럴 업샘플의 입력 샘플 오프셋 간섭을 피하기 위해서일 수도 있습니다. 이 간섭은 프레임별 오프셋 지터링과 해상도 변경 사이 발생하여 안티에일리어싱 차이의 원인이 될 수 있습니다.

 

카메라 컷 도중 또는 비싼 비주얼 이펙트가 발생할 때처럼 동적 해상도가 매우 빠르게 예산을 초과하는 경우가 있는데 휴리스틱으로는 이게 언제 발생할지 예측할 수 없다. 이 경우 "panic" (패닉) 스위치를 사용하면 예산 초과인 프레임 수를 감소시킬 상황이 발생했을 때 해상도를 빠르게 낮출 수 있다. 휴리스틱이 가용 GPU 타이밍이 예산을 초과한 프레임을 연속 N (일정 숫자) 개 발견한 경우, 즉시 예산 초과 타이밍에 맞서기 위해 해상도를 적응시킨다. 히스토리도 자동 리셋.

정리하면 패닉 스위치를 사용하여 프레임수를 빠르게 낮추는 방법임.

  1. 카메라 컷 이후, 프레임 렌더링 비용이 최소 몇 프레임 동안 크게 비싸집니다.
  2. 동적 해상도가 패닉 반응으로 해상도를 빠르게 낮춰 보정하여 서서히 정상 상태로 돌아옵니다.

C++ 에서 동적 해상도 휴리스틱 대체

엔진 제공 렌더링 휴리스틱은 DynamicResolution.cpp에 있다. 그 구조는 휴리스틱을 게임 코드에서 플러그인으로 완전 대체할 수 있게 되었다.

휴리스틱을 수정하거나 대체해야하는 경우에는 전체 휴리스틱을 다시 작성하면 된다!

IDynamicResolutionState 및 ISceneViewFamilyScreenPercentage 를 구현하면 기본 동적 해상도 상태를 대체할 수 있다고 한다.

GEngine->ChangeDynamicResolutionStateNextFrame(
			new FMyGameSpecificDynamicResolutionState());