오클루전 컬링
머티리얼, 셰이더, 텍스처(Materials, Shaders & Textures)

다이내믹 해상도

다이내믹 해상도는 개별 렌더 타겟을 동적으로 스케일링하여 GPU의 부하를 줄여주는 카메라 설정입니다. 애플리케이션의 프레임 속도가 감소하는 경우에는 일관된 프레임 속도를 유지하기 위해 점진적으로 해상도를 스케일다운할 수 있습니다. 성능 데이터가 애플리케이션의 GPU 바운드로 인해 프레임 속도가 떨어진다고 암시하는 경우 Unity는 이 스케일링 방식을 트리거합니다. 애플리케이션의 특정 GPU 과부하 섹션을 선점한 후 스크립트를 통해 스케일링을 제어하는 방식으로 스케일링을 수동으로 트리거할 수도 있습니다. 점진적으로 스케일링하면 다이내믹 해상도는 거의 눈에 띄지 않습니다.

지원되는 플랫폼

Unity supports dynamic resolution on Xbox One, PS4, Nintendo Switch, iOS, macOS and tvOS (Metal only), Android (Vulkan only), Windows Standalone and UWP (DirectX 12 only).

렌더 타겟에 대한 영향

다이내믹 해상도를 사용하는 경우 Unity는 렌더 타겟을 재할당하지 않습니다. 개념적으로는 Unity가 렌더 타겟을 스케일링하지만, 실제로 Unity는 앨리어싱을 사용합니다. 또한 스케일다운된 렌더 타겟은 원본 렌더 타겟의 작은 부분만 사용합니다. Unity가 전체 해상도로 렌더 타겟을 할당하면, 다이내믹 해상도 시스템이 스케일다운을 통해 다시 백업합니다. 이때 새 타겟을 재할당하지 않고 원본 타겟의 일부를 사용합니다.

렌더 타겟 스케일링

다이내믹 해상도를 사용하는 경우 렌더 타겟에 DynamicallyScalable 플래그가 생깁니다. 이 플래그를 설정하면 Unity가 다이내믹 해상도 프로세스의 일부로 이 렌더 텍스처를 스케일링해야 하는지 여부를 지정할 수 있습니다. 또한 카메라에 생기는 allowDynamicResolution 플래그를 사용하여 다이내믹 해상도를 설정하면, 덜 복잡한 씬에 다이내믹 해상도를 적용하는 경우에 렌더 타겟을 오버라이드할 필요가 없습니다.

MRT 버퍼

카메라에서 Allow Dynamic Resolution 을 활성화하면 Unity는 카메라의 모든 타겟을 스케일링합니다.

스케일링 제어

ScalableBufferManager를 통해 스케일을 제어할 수 있습니다. ScalableBufferManager를 이용하면 다이내믹 해상도 시스템에서 스케일링하도록 표시한 모든 렌더 타겟의 동적 너비와 높이 스케일을 제어할 수 있습니다.

As an example, assume your application is running at a desirable frame rate, but under some circumstances the GPU performance decreases, due to a combination of increased particles, post-effects and screen complexity. The Unity FrameTimingManager allows you to detect when the CPU or GPU performance start to decrease. So you can use the FrameTimingManager to calculate a new desired width and height scale to keep the frame rate within your desired range, and bring the scale down to that value to keep performance stable (either instantly or gradually over a set amount of frames). When the screen complexity reduces and the GPU is performing consistently, you may then raise the width and height scale back to a value that you’ve calculated the GPU can handle.

예제

This example script demonstrates basic use of the API. Add it to a Camera in your Scene, and check Allow Dynamic Resolution in the Camera settings. You also need to open the Player settings (menu: Edit > Project Settings, then select the Player category) and check the Enable Frame Timing Stats checkbox.

마우스 오른쪽 버튼을 클릭하거나 화면을 한 손가락으로 탭하면 높이 및 너비 해상도가 scaleWidthIncrementscaleHeightIncrement 변수의 양만큼 각각 감소합니다. 두 손가락으로 탭하면 동일한 인크리먼트만큼 해상도가 증가합니다.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DynamicResolutionTest : MonoBehaviour
{
    public Text screenText;

    FrameTiming[] frameTimings = new FrameTiming[3];

    public float maxResolutionWidthScale = 1.0f;
    public float maxResolutionHeightScale = 1.0f;
    public float minResolutionWidthScale = 0.5f;
    public float minResolutionHeightScale = 0.5f;
    public float scaleWidthIncrement = 0.1f;
    public float scaleHeightIncrement = 0.1f;

    float m_widthScale = 1.0f;
    float m_heightScale = 1.0f;

    // Variables for dynamic resolution algorithm that persist across frames
    uint m_frameCount = 0;

    const uint kNumFrameTimings = 2;

    double m_gpuFrameTime;
    double m_cpuFrameTime;

    // Use this for initialization
    void Start()
    {
        int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width);
        int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height);
        screenText.text = string.Format("Scale: {0:F3}x{1:F3}\nResolution: {2}x{3}\n",
            m_widthScale,
            m_heightScale,
            rezWidth,
            rezHeight);
    }

    // Update is called once per frame
    void Update()
    {
        float oldWidthScale = m_widthScale;
        float oldHeightScale = m_heightScale;

        // One finger lowers the resolution
        if (Input.GetButtonDown("Fire1"))
        {
            m_heightScale = Mathf.Max(minResolutionHeightScale, m_heightScale - scaleHeightIncrement);
            m_widthScale = Mathf.Max(minResolutionWidthScale, m_widthScale - scaleWidthIncrement);
        }

        // Two fingers raises the resolution
        if (Input.GetButtonDown("Fire2"))
        {
            m_heightScale = Mathf.Min(maxResolutionHeightScale, m_heightScale + scaleHeightIncrement);
            m_widthScale = Mathf.Min(maxResolutionWidthScale, m_widthScale + scaleWidthIncrement);
        }

        if (m_widthScale != oldWidthScale || m_heightScale != oldHeightScale)
        {
            ScalableBufferManager.ResizeBuffers(m_widthScale, m_heightScale);
        }
        DetermineResolution();
        int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width);
        int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height);
        screenText.text = string.Format("Scale: {0:F3}x{1:F3}\nResolution: {2}x{3}\nScaleFactor: {4:F3}x{5:F3}\nGPU: {6:F3} CPU: {7:F3}",
            m_widthScale,
            m_heightScale,
            rezWidth,
            rezHeight,
            ScalableBufferManager.widthScaleFactor,
            ScalableBufferManager.heightScaleFactor,
            m_gpuFrameTime,
            m_cpuFrameTime);
    }

    // Estimate the next frame time and update the resolution scale if necessary.
    private void DetermineResolution()
    {
        ++m_frameCount;
        if (m_frameCount <= kNumFrameTimings)
        {
            return;
        }
        FrameTimingManager.CaptureFrameTimings();
        FrameTimingManager.GetLatestTimings(kNumFrameTimings, frameTimings);
        if (frameTimings.Length < kNumFrameTimings)
        {
            Debug.LogFormat("Skipping frame {0}, didn't get enough frame timings.",
                m_frameCount);

            return;
        }

        m_gpuFrameTime = (double)frameTimings[0].gpuFrameTime;
        m_cpuFrameTime = (double)frameTimings[0].cpuFrameTime;
    }
}

참고 항목


  • 2018–09–20 편집 리뷰를 거쳐 페이지 게시됨

  • Unity 2017.4에서 다이내믹 해상도에 대한 설명 추가됨

  • Dynamic Resolution support for macOS (Metal only), Windows Standalone and UWP (DirectX 12 only) added in 2019.1

오클루전 컬링
머티리얼, 셰이더, 텍스처(Materials, Shaders & Textures)