동적 해상도

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

Windows
MacOS
Linux

DynamicRes_FN1.png

Dynamic Resolution (동적 해상도)는 이전 프레임의 GPU 작업 부하에 따라 1차 스크린 퍼센티지를 조정합니다. 해상도 조정이 필요한 경우 휴리스틱에 기반합니다. 예를 들어 화면에 오브젝트가 너무 많을 경우, 또는 프레임에 갑자기 비싼 이펙트가 들어오는 경우입니다. GPU 렌더링 시간이 늘어나므로 목표 프레임 속도를 유지하기 위해 화면 해상도를 낮춥니다.

동적 해상도 활성화

런타임에 동적 해상도 활성화

동적 해상도는 Game User Settings 노드의 부울 값으로 활성화시킬 수 있습니다. 블루프린트나 C++ 로 설정할 수 있습니다.

블루프린트 의 경우, 동적 해상도를 활성화하려면 Game User Settings 노드로 다음과 같이 기능을 선택합니다:

The Game User Settings node in Blueprint provides access to Dynamic Resolution settings.

C++ 의 경우, UGameUserSettings 에 부울 값을 다음과 같이 설정하면 됩니다:

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

SetEnabledfalse 를 설정하면 비활성화됩니다.

게임 스레드 로직에 동적 해상도를 실제 활성화 또는 비활성화하는 최종 프로그래밍적 제어가 있으며, 블루프린트를 사용해서 런타임 활성화하면 코드의 설정보다 우선합니다. 게임 유저 세팅을 원래 상태로 복원하는 방법은 다음과 같습니다:

GEngine->GameUserSettings->ApplyNonResolutionSettings();

동작 모드로 동적 해상도 제어

Operation Mode (동작 모드)로 동적 해상도 오버라이드 방식과 게임에서의 사용 방식을 설정할 수 있습니다. 이를 제어하려면 프로젝트의 (Xbox One, PlayStation 4 등) 플랫폼별 구성 파일( 또는 디바이스 프로파일)에 다음 콘솔 명령을 사용하면 됩니다.

r.DynamicRes.OperationMode

프로젝트의 플랫폼에 대한 동작 모드 방식을 설정하는 값은 다음과 같습니다.

  • 1 - (C++ 또는 블루프린트에서 설정하는) Game User Settings 상태에 따라 동적 해상도를 활성화합니다.

  • 2 - Game User Settings 상태와 무관하게 동적 해상도를 활성화합니다.

동적 해상도 활성화 이후, 다음 콘솔 변수로 최소 최대 스크린 퍼센티지 및 해상도를 낮추기 전까지 사용할 최대 예산을 설정합니다. 따로 설정하지 않아도 이미 기본값이 설정되어 있습니다.

콘솔 변수

기본값

설명

r.DynamicRes.MinScreenPercentage

50

스크린 퍼센티지 최소치를 설정합니다.

r.DynamicRes.MaxScreenPercentage

100

렌더 타깃 할당에 사용되는 1차 스크린 퍼센티지 최대치를 설정합니다.

r.DynamicRes.FrameTimeBudget

33.3

프레임 예산을 (밀리초 단위로) 설정합니다.

UE4 에서 디바이스 프로파일 창을 사용하여 구성 파일을 설정하면 관리해 줍니다. 이 창은 파일 메뉴의 편집 > 개발자 툴 > 디바이스 프로파일 로 열 수 있습니다.

동적 해상도 일시 중지 및 다시 시작

때로는 동적 해상도를 전체 프로젝트에는 사용하지만 메인 로비같은 곳에는 사용하지 않을 수도 있습니다. 그럴 때는 동작 모드로 동적 해상도를 일시 중지하고 다시 시작할 수 있습니다. 동적 해상도의 동작 모드를 설정하는 콘솔 변수는 다음과 같습니다.

r.DynamicRes.OperationMode

설명

0

비활성화 (기본)

1

GameUserSettings 에 사용된 세팅에 따라 활성화됩니다.

2

GameUserSettings 에 사용된 세팅과 무관하게 활성화됩니다.

아래 표는 특정 동작 모드를 활성화 또는 비활성화했을 때 사용할 수 있는 여러가지 상태에 대한 요약 및 GameUserSettings 에 주는 영향입니다.

Game User Settings = False

Game User Settings = True

일시정지됨

일시정지 안됨

일시정지됨

일시정지 안됨

OperationMode=0

아니오

아니오

아니오

아니오

OperationMode=1

아니오

아니오

아니오

OperationMode=2

아니오

아니오

C++ 에서 동적 해상도 상태를 제어하고 확인하는 함수는 다음과 같습니다.

동작

C++ 함수

Pause 일시정지

GEngine->PauseDynamicResolution();

Resume 재개

GEngine->ResumeDynamicResolution();

Check Status (Disabled/Enabled or Paused) 상태 확인 (활성화 여부 또는 일시정지)

GEngine->GetDynamicResolutionStatus();

블루프린트에서 이 표의 Pause (일시정지) 및 Resume (다시 시작) C++ 함수에 제공되는 기능은 Set Dynamic Resolution Enabled 노드 활성화 또는 비활성화와 같습니다. 상태를 확인하려면 Is Dynamic Resolution Enabled 노드를 사용하세요.

통계 사용

동적 해상도 퍼포먼스 디버깅을 위해 사용할 수 있는 통계 화면이 몇 가지 있습니다. 물결표 (`) 키를 눌러 콘솔을 열고 다음 명령 중 하나를 입력하면 사용할 수 있습니다.

  • Stat Unit 은 전반적인 프레임 시간은 물론 게임 스레드, 렌더링 스레드, GPU 시간을 살펴봅니다.

  • Stat UnitGraph 는 Stat Unit 데이터로 그래프를 그립니다.

  • Stat Raw 는 Stat UnitGraph 에 필터를 적용하지 않은 데이터를 출력합니다.

Stat Unit

Stat Unit 을 호출하면, 씬의 동적 해상도 활성화 여부가 DynRes 줄에 바로 나타납니다.

DynResOFF.png

활성화하면, DynRes 라벨은 1차 스크린 퍼센티지와 2차 스크린 퍼센티지를 표시합니다.

DynResON.png

양 축 스케일을 조절했음을 잊지 않도록 X 및 Y 에 대한 1차 스크린 퍼센티지가 표시됩니다. GPU 가 그리는 픽셀 수는 실제로 Screen Percentage x Screen Percentage 에 비례합니다.

예로 1920x1080 또는 1280x720 입니다.

Stat UnitGraph 및 Stat Raw

Stat UnitGraph 를 호출하면, 동적 해상도가 선택한 1차 스크린 퍼센티지를 나타내는 그래프를 그립니다.

StatUnitGraph.png

  1. 타이밍 (필터 적용 또는 원시)

  2. 목표 프레임 시간 한계치

  3. 동적 해상도 최대 스크린 퍼센티지

  4. 동적 1차 스크린 퍼센티지 커브

UnitGraph 는 동적 해상도가 선택한 1차 스크린 퍼센티지를 표시할 수 있습니다. 하지만, 그 커브는 스크린 퍼센티지 x 스크린 퍼센티지를 사용하여 GPU 가 그리는 픽셀 양에 비례합니다.

또한 Stat Raw 를 사용하여 필터 적용 및 해제 토글하여 UnitGraph 의 필터를 적용하지 않은 (원시) 타이밍을 구할 수 있습니다. 원시 타이밍을 표시할 때는 그래프의 타이밍 레이블이 바뀝니다.

원시 타이밍

필터 적용 타이밍

콘솔 창을 사용하여 필터 적용 또는 미적용 타이밍을 토글합니다. Stat Raw 토글 전 반드시 Stat UnitGraph 를 입력해야 합니다.

동적 해상도 크루즈

UE4 의 동적 해상도 구현은 이전에 사용되던 것과 약간 다른데, 단일 해상도에 (1080p, 900p, 720p) 한정되기 보다는 지정한 범위 내 필요에 따라 바꿀 수 있기 때문입니다. 이 예제 그래프에서 이 모델은 콘솔 변수가 제어하는 것을 보여줍니다. 모든 것이 정상 작동하고 예산이 지정한 프레임에 예산이 초과되지 않았을 때 지정한 범위 (3) 내 동적 해상도가 자동 조절하는 방식을 보여줍니다. 이 범위는 비행기가 이상적인 속도로 목적지에 도달하기 위해 자유롭게 이동할 수 있는 순항(크루즈) 고도 범위라고 생각하면 됩니다. 비행기처럼, 해상도 역시 해상도화 퍼포먼스 사이 균형을 유지하는 데 필요한 만큼 오르내릴 수 있습니다.

이 모델은 데모 용이며 지정한 씬에서 벌어지는 모든 것을 고려하지 않습니다. 예를 들어 CPU 와 동기화되지 않은 GPU 가 어떻게 보이는지, 심지어 휴리스틱이 해상도 변경량을 제대로 추측하고 있는지 같은 것도 잘 잡아내지 못하고 있습니다. 그 목적은 동적 해상도 콘솔 변수 작동 방식을 보여주는 "이상적인" 상황을 명확히 하는 것입니다.

FrameGPUGraph.png

번호

콘솔 변수

설명

1

r.DynamicRes.FrameTimeBudget

프레임 시간 예산 - 프레임의 시간 예산으로 밀리초(ms) 단위입니다.

2

r.DynamicRes.TargetedGPUHeadRoom**

목표 GPU 여유 공간 - GPU 에 남은 공간이 이 밑으로 떨어지면 늘려 예산 초과를 방지합니다 (프레임 예산 백분율 단위입니다). 출시 플랫폼 또는 활성화한 렌더링 기능에 따라 달라질 수 있습니다. 예를 들어 모션 블러는 비용에 여유 공간이 있어야 카메라 이동의 빠른 회전을 처리할 수 있습니다.

3

r.DynamicRes.ChangePercentageThreshold**

퍼센티지 변화 한계치 - 퍼센티지 변화량이 최소 이 이상 되어야 실제 할당 크기를 조정합니다. 해상도 크기가 매우 비슷한데도 계속 바뀌지 않도록 하는 데 좋습니다. 값이 너무 작으면 해상도가 계속 바뀔 수 있고, 너무 크면 GPU 예산 초과 위험이 높아집니다.

4

r.DynamicRes.MinResolutionChangePeriod**

최소 해상도 변경 주기 - 최소 이 프레임 수를 넘으면 해상도 변경을 허용합니다. 이 명령에는 여러가지 용도가 있습니다. 측정 노이즈에도 불구하고 지정한 1차 스크린 퍼센티지로 GPU 소모를 모델링하는 휴리스틱 신뢰성 향상일 수도 있고, 템포럴 업샘플의 입력 샘플 오프셋 간섭을 피하기 위해서일 수도 있습니다. 이 간섭은 프레임별 오프셋 지터링과 해상도 변경 사이 발생하여 안티에일리어싱 차이의 원인이 될 수 있습니다.

GPU 제약이 아닌 CPU 제약인 경우 동적 해상도와 스크린 퍼센티지에 사용되는 휴리스틱 히스토리 조정을 위해 사용할 수 있는 콘솔 변수는 다음과 같습니다.

콘솔 변수

설명

r.DynamicRes.HistorySize

히스토리 크기 - 휴리스틱 프레임 히스토리의 프 수입니다. 너무 짧으면 히스토리 노이즈가 너무 심해 안정성이 떨어질 수 있고, 너무 길면 조정이 매우 지연될 수 있습니다.

r.DynamicRes.CPUBoundScreenPercentage

CPU 제약 스크린 퍼센티지 - CPU 에 제약된 경우 목표로 삼을 1차 스크린 퍼센티지입니다. CPU 와 GPU 가 같은 메모리 대역폭을 공유하는 플랫폼에서는 스크린 퍼센티지를 낮게 설정하여 해상도를 낮추는 것이 좋습니다.

예산 초과 패닉

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

"패닉" 스위치를 켜서 해상도를 낮추기 전까지 GPU 예산 초과를 버틸 수 있는 최대 연속 프레임 수를 제어하는 콘솔 명령은 다음과 같습니다.

r.DynamicRes.MaxConsecutiveOverbudgetGPUFrameCount

이 그래프에서 프레임이 설정 예산 33.3 ms 를 초과하여 연속 2 프레임 이상 동안 급격히 점프했습니다. 패닉 스위치 가동, 프레임 예산 초과 방지를 위해 빠르게 해상도를 낮춥니다.

OverBudgetPanicGraph.png

  1. 예산을 초과한 최대 연속 GPU 프레임 수.

  2. GPU 와 렌더 스레드 사이 동기화가 이루어지지 않아 해상도 감지와 변경 사이 발생한 프레임 지연.

  3. 프레임 드랍 발동을 위한 패닉 감지 발생.

  4. 지정한 프레임에 대해 해상도 변경.

다음 (에픽게임즈 런처의 학습 탭에서 받을 수 있는 Infiltrator(잠입자) 데모에서 찍은) 캡처를 보면, Stat Raw 명령으로 카메라 컷 또는 화면에 비싼 비주얼 이펙트가 발생할 때 씬이 어떻게 작동하는지 명확히 알 수 있습니다.

이미지를 클릭하면 원본을 확인합니다.

  1. 카메라 컷 이후, 프레임 렌더링 비용이 최소 몇 프레임 동안 크게 비싸집니다.

  2. 동적 해상도가 패닉 반응으로 해상도를 빠르게 낮춰 보정하여 서서히 정상 상태로 돌아옵니다.

이미지를 클릭하면 원본을 확인합니다.

  1. 비용이 비싼 비주얼 이펙트가 발생하여 몇 프레임 이상 프레임 예산을 넘는 스파이크가 발생합니다.

  2. 동적 해상도가 패닉 반응으로 해상도를 빠르게 낮춰 보정하여 서서히 정상 상태로 돌아옵니다.

다양한 1차 스크린 퍼센티지로 콘텐츠 테스트

프로젝트에 동적 해상도가 활성화된 경우, 1차 스크린 퍼센티지를 낮췄을 때 의도한 것과 크게 달라보이지 않는지 테스트하여 확인해야 합니다. 낮은 해상도에서 애셋에 일부 디테일이 손실되어 원했던 모양이 유지되지 않을 수 있습니다. 바로 그 이유로 모든 에디터 뷰포트에서 슬라이더로 스크린 퍼센티지를 설정하여 테스트할 수 있습니다.

이미지를 클릭하면 원본을 확인합니다.

슬라이더로 뷰포트에 높고 낮은 스크린 퍼센티지를 적용하면서 레벨 콘텐츠를 확인합니다. 특히 아티스트는 슬라이더를 사용하여 프로젝트에 사용할 스크린 퍼센티지 상하한 범위에서 콘텐츠를 확인해야 합니다.

에디터 스크린 퍼센티지: | 100 (기본)

에디터 스크린 퍼센티지: | 50

스크린 퍼센티지 슬라이더를 조절할 때, 뷰포트(우하단)에 100 보다 큰 스크린 퍼센티지 값이 표시됩니다. 뷰포트 스크린 퍼센티지 값이 기본값 이외로 변경되었고 정상 해상도보다 높아 퍼포먼스 이슈가 생길 수 있다는 것을 알리기 위함입니다.

Editor_ScreenPercentageIndicator.png

스크린 퍼센티지 값이 기본값보다 높으면 에디터 속도가 느려질 수 있습니다. 이 경우 값을 기본값 100 으로 리셋해 보세요.

지원 플랫폼

현재 Xbox One, PlayStation 4 (PSVR 제외), Nintendo Switch, Oculus VR 이 동적 해상도를 지원합니다. 앞으로 지원 플랫폼을 늘릴 계획입니다.

허용되지 않은 플랫폼에 동적 해상도를 활성화하는 것은 위험하며 의도하지 않은 결과를 초래할 수 있습니다. 잘못된 GPU 타이밍으로 인해 해상도를 불필요하게 떨어뜨리거나 아니면 너무 높여 프레임이 떨어지는 상황이 포함될 수 있습니다. 결국 게임플레이 경험을 망칠 수 있습니다. 기본적으로 엔진에서는 허용되지 않는 플랫폼을 사용할 수 없습니다.

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

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

예를 들어 프로젝트에서 게임 플레이 코드로 다음 프레임에 일어날 일에 대한 힌트를 주거나 하기 위해 기본 휴리스틱을 대체해야 하는 경우, 전체 휴리스틱을 다시 작성하면 됩니다. IDynamicResolutionStateISceneViewFamilyScreenPercentage 를 구현하면 기본 동적 해상도 상태를 대체할 수 있습니다. 예:

GEngine->ChangeDynamicResolutionStateNextFrame(new FMyGameSpecificDynamicResolutionState());

이제 렌더러는 스크린 퍼센티지 수학 관련 모든 곳에 100 으로 나누지 않도록 ResolutionFraction (해상도 분수)를 사용합니다. 이름이 "scale" (스케일)이 아닌 fraction (분수)인 이유는 업스케일 비율이 TAA 업샘플로 이루어지기 때문에, 또는 공간 업스케일은 사실 해상도 분수 분의 1 값으로 표현되기 때문입니다. 예:

해상도 분수 = 스크린 퍼센티지 / 100 = 1 / 업스케일 인수

한계

동적 해상도의 현재 한계는 다음과 같습니다.

  • 디자인 상 멀티 월드 에디터에서 플레이를 지원하지 않습니다.

  • TAAU 를 활성화하면, VR 에 작동합니다. 곧 멀티샘플 안티에일리어싱(MSAA)을 지원할 예정입니다.

  • API 는 모바일 렌더러와 완벽 호환됩니다. 하지만 뷰 크기가 1차 스크린 퍼센티지 상한에 설정된 렌더 타깃 버퍼와 같지 않게 유지하려는 노력은 없었습니다.

  • 가우시안 뎁스 오브 필드(DoF) 및 디스턴스 필드 앰비언트 오클루전(DFAO)에 해상도 변경 관련 이슈가 있습니다.

자주 묻는 질문

동적 해상도 관련 자주 묻는 일반적인 질문은 다음과 같습니다.

동적 해상도 휴리스틱을 대체할 수 있나요?

네, C++ 모듈식 플러그인식으로 디자인했습니다. 언리얼 엔진 4 는 하나의 휴리스틱만 유지하나, 구조 상 독립형 커스텀 휴리스틱을 만들어 게임플레이 코드나 시퀀서로 커스텀 게임 스레드 이벤트를 발동시킬 수 있습니다.

동적 해상도는 2차 스크린 퍼센티지를 아무렇게나 해도 되나요?

네. r.SecondaryScreenPercentage.GameViewport 콘솔 변수를 사용하면 됩니다.

추가 정보는 스크린 퍼센티지와 템포럴 업샘플 문서를 참조하세요.

2차 스크린 퍼센티지의 동적 해상도를 제어할 수 있나요?

아니오, 불가능하며 의도된 것입니다. 템포럴 안티에일리어싱 히스토리는 바꾸지 않는 것이 좋으며, 2차 스크린 퍼센티지를 동적으로 바꿀 필요가 없는 이유이기도 합니다.

ScreenPercentage 에 대한 FPostProcessSettings 의 함수가 동적 해상도에서 무시되는 이유는 무엇인가요?

포스트 프로세스 볼륨 세팅에서 스크린 퍼센티지를 구성하여 스케일을 수동으로 높이고 낮추는 이전 메커니즘의 일부였습니다. 동적 해상도를 사용하면 GPU 작업 부하에 따라 자동 처리해 주니 더이상 수동 설정할 필요가 없습니다.

에디터에 동적 해상도 표시 플래그 옵션이 없는 이유는 무엇인가요?

글로벌 그리고 게임 스레드에서 전적으로 발생하기 때문입니다. 스크린 퍼센티지 표시 플래그는 1차 스크린 퍼센티지 만 토글합니다.

에디터 뷰포트에 동적 해상도가 지원되지 않는 이유는 무엇인가요?

현재 동적 해상도는 PIE 를 사용하지 않는 Xbox One ,PlayStation 4, Nintendo Switch 만 지원합니다. 사용하는 (Vulkan, D3D12 같은) 플랫폼을 지원하면, PIE 로 에디터 안에서 사용할 수 있을 것입니다.

머티리얼에서 1차 / 2차 스크린 퍼센티지에 액세스할 수 있나요?

아니오, 불가능합니다. 머티리얼 렌더링은 해상도와 독립적입니다.

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼