[UE] 동적 해상도
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 (일정 숫자) 개 발견한 경우, 즉시 예산 초과 타이밍에 맞서기 위해 해상도를 적응시킨다. 히스토리도 자동 리셋.
정리하면 패닉 스위치를 사용하여 프레임수를 빠르게 낮추는 방법임.
- 카메라 컷 이후, 프레임 렌더링 비용이 최소 몇 프레임 동안 크게 비싸집니다.
- 동적 해상도가 패닉 반응으로 해상도를 빠르게 낮춰 보정하여 서서히 정상 상태로 돌아옵니다.
C++ 에서 동적 해상도 휴리스틱 대체
엔진 제공 렌더링 휴리스틱은 DynamicResolution.cpp에 있다. 그 구조는 휴리스틱을 게임 코드에서 플러그인으로 완전 대체할 수 있게 되었다.
휴리스틱을 수정하거나 대체해야하는 경우에는 전체 휴리스틱을 다시 작성하면 된다!
IDynamicResolutionState 및 ISceneViewFamilyScreenPercentage 를 구현하면 기본 동적 해상도 상태를 대체할 수 있다고 한다.
GEngine->ChangeDynamicResolutionStateNextFrame(
new FMyGameSpecificDynamicResolutionState());