Мои Уведомления
Привет, !
Мой Аккаунт Мои Финансы Мои Подписки Мои Настройки Выход
Руководство API скрипты

Динамическое разрешение

Динамическое разрешение — это Камеракомпонент, который создает изображение определенной точки обзора в вашей сцене. Вывод либо рисуется на экране, либо фиксируется в виде текстуры. Подробнее
Параметр See in Словарь
позволяет динамически масштабировать отдельные цели рендеринга, чтобы уменьшить нагрузка на GPU. В случаях, когда частота кадров приложения снижается, вы можете постепенно уменьшать разрешение, чтобы вместо этого поддерживать постоянную частоту кадров. Unity запускает это масштабирование, если данные о производительности предполагают, что частота кадров вот-вот уменьшится из-за того, что приложение привязано к графическому процессору. Вы также можете инициировать масштабирование вручную, вытеснив особенно интенсивно использующий GPU раздел приложения и управляя масштабированием с помощью скрипта. При постепенном масштабировании динамическое разрешение может быть практически незаметным.

Совместимость конвейера рендеринга

Поддержка динамического разрешения зависит от того, какой конвейер рендеринга использует ваш проект.

Функция Встроенный конвейер рендеринга Универсальный конвейер рендеринга (URP) Конвейер рендеринга высокого разрешения (HDRP)
Динамическое разрешение Да (1) Да (1) Да (2)

Notes:

  1. Встроенный конвейер рендеринга и Универсальный конвейер рендеринга ( URP) оба поддерживают динамическое разрешение, как описано в этом документе.
  2. конвейер рендеринга высокого разрешения (HDRP) поддерживает динамическое разрешение, но вы включаете и используете его другим способом. Для получения информации о динамическом разрешении в HDRP см. Динамическое разрешение в HDRP.

Поддерживаемые платформы

Unity поддерживает динамическое разрешение на Xbox One, PS4, Nintendo Switch, iOSмобильной операционной системе Apple. Подробнее
См. в Словарь
, macOS и tvOS (только Metal), Android (только Vulkan ), Windows Standalone и UWP (только DirectX 12).

Влияние на цели визуализации

При динамическом разрешении Unity не перераспределяет цели рендеринга. Концептуально Unity масштабирует цель рендеринга; однако на самом деле Unity использует псевдонимы, а уменьшенная цель рендеринга использует только небольшую часть исходной цели рендеринга. Unity выделяет целевые объекты рендеринга с их полным разрешением, а затем система динамического разрешения уменьшает их масштаб и снова увеличивает, используя часть исходного целевого объекта вместо повторного выделения нового целевого объекта.

Масштабирование целей рендеринга

При динамическом разрешении цели визуализации имеют флаг DynamicallyScalable. Вы можете указать, должна ли Unity масштабировать эту текстуру рендерингаСпециальный тип текстуры, который создается и обновляется во время выполнения. Чтобы использовать их, сначала создайте новую текстуру рендеринга и назначьте одну из ваших камер для рендеринга в нее. Затем вы можете использовать Render Texture в материале, как обычную текстуру. Подробнее
См. в Словарь
в рамках процесса динамического разрешения или нет. Камеры также имеют флаг allowDynamicResolution, который можно использовать для настройки динамического разрешения, чтобы не было необходимости переопределять цель рендеринга, если вы просто хотите чтобы применить динамическое разрешение к менее сложной сценеСцена содержит окружение и меню вашей игры. Думайте о каждом уникальном файле сцены как об уникальном уровне. В каждой сцене вы размещаете свое окружение, препятствия и декорации, по сути проектируя и создавая свою игру по частям. Подробнее
См. в Словарь
.

Буферы MRT

Когда вы включаете Разрешить динамическое разрешение на камере, Unity масштабирует все цели этой камеры.

Управление масштабированием

Вы можете управлять масштабом с помощью ScalableBufferManager. ScalableBufferManager позволяет управлять динамической шириной и масштабом высоты для всех целей рендеринга, которые вы отметили для масштабирования системы динамического разрешения.

В качестве примера предположим, что ваше приложение работает с желаемой частотой кадров, но при некоторых обстоятельствах производительность графического процессора снижается из-за сочетания увеличения количества частиц, пост-эффектов и сложности экрана. Unity FrameTimingManager позволяет определить, когда производительность процессора или графического процессора начинает снижаться. Таким образом, вы можете использовать FrameTimingManager для расчета нового желаемого масштаба ширины и высоты, чтобы поддерживать частоту кадров в нужном диапазоне, и уменьшить масштаб до этого значения, чтобы поддерживать стабильную производительность ( либо мгновенно, либо постепенно в течение заданного количества кадров). Когда сложность экрана уменьшится, а графический процессор будет работать стабильно, вы можете снова увеличить масштаб ширины и высоты до значения, которое, по вашим расчетам, может обрабатывать графический процессор.

Пример

Этот пример сценария демонстрирует базовое использование API. Добавьте его к камере в вашей сцене и установите флажок Разрешить динамическое разрешение в настройках камеры. Вам также необходимо открыть настройки Player (меню: Edit > Project Settings, затем выберите категорию Player) и установить флажок Enable Статистика синхронизации кадров.

Щелчок мышью или касание экрана одним пальцем снижает разрешение по высоте и ширине на величину, указанную в scaleWidthIncrement и scaleHeightIncrement переменные соответственно. Нажатие двумя пальцами повышает разрешение на тот же шаг.

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; } }

См. также


  • Документация по динамическому разрешению добавлена в 2017.4
  • Поддержка динамического разрешения для macOS (только Metal), Windows Standalone и UWP (только DirectX 12) добавлена в 2019.1.
Вы можете отблагодарить автора, за перевод документации на русский язык. ₽ Спасибо
Руководство Unity 2021.3