Асинхронная потоковая передача данных
Потоковая передача данных — это метод оптимизации, предназначенный для уменьшения скачков, вызванных загрузкой графических ресурсов и компиляцией шейдеров. При использовании этого метода данные загружаются в оперативную память (RAM) не всем объемом сразу: сначала загружаются только необходимые данные, а остальные — постепенно по запросу.
Ресурсы загружаются и передаются в GPU отдельными асинхронными потоками. После этого ресурсы синхронизируются и добавляются в виртуальную сцену на стороне CPU.
В UNIGINE асинхронная потоковая передача данных включена по умолчанию. Вы можете отключить асинхронную потоковую передачу данных в UnigineEditor или через консоль:
- В UnigineEditor откройте окно Settings и перейдите в раздел Streaming. Здесь вы можете переключить режим потоковой передачи текстур и/или мешей.
- В консоли запустите соответствующие команды, которые переключают режим потоковой передачи текстур и/или мешей.
Существует два основных режима потоковой передачи — асинхронный (Async) и принудительный (Force). Режим Force обеспечивает принудительную загрузку всех ресурсов, необходимых для каждого кадра одновременно (например, захват последовательностей кадров, рендеринг предварительного просмотра нод, прогрев и т.д.).
Система потоковой передачи обеспечивает асинхронную загрузку следующих данных в RAM:
- Все исполняемые файлы текстур и текстуры с включенной опцией Unchanged, включая кубические карты, карты воксельных проб и карты запеченных теней.
- Меши объектов ObjectMeshStatic, ObjectMeshClutter, ObjectMeshCluster, ObjectGuiMesh и DecalMesh.
Процедурно сгенерированные объекты, такие как ObjectMeshClutter, генерируются в отдельном потоке, что значительно снижает затраты на производительность.
Вы можете получить общую информацию о потоковых ресурсах, используя консольные команды render_streaming_meshes_info и render_streaming_textures_info.
Также можно вывести на экран список загруженных ресурсов и подробную информацию о них с помощью консольных команд render_streaming_meshes_list и render_streaming_textures_list.
Асинхронная компиляция шейдеров#
Помимо асинхронной загрузки мешей и текстур, система потоковой передачи обеспечивает асинхронную компиляцию и загрузку шейдеров.
Для этого также предусмотрены 2 режима — асинхронный (Async) и принудительный (Force). В принудительном режиме все шейдеры, необходимые для текущего кадра, компилируются и загружаются в оперативную память одновременно в текущем потоке. По умолчанию используется асинхронный режим.
Количество скомпилированных и загруженных шейдеров можно посмотреть в инструменте Performance Profiler.
Ограничения на использование памяти#
Все аллокации памяти для графических ресурсов ограничены размером выделенной памяти, которая включает в себя как оперативную память, так и видеопамять.
Вы можете ограничить объем доступной приложению памяти, чтобы избежать сбоев и найти баланс между производительностью и потреблением памяти. Для этого есть два основных параметра:
- Usage Limit VRAM/RAM — лимиты на использование ОЗУ и видеопамяти, которые ограничивают потребление определенным процентом от выделенной памяти. Однако следует помнить, что если система потоковой передачи превысит лимит использования видеопамяти, она начнет использовать ОЗУ для загрузки графических ресурсов. Если это превысит лимит использования оперативной памяти, приложение завершит работу с ошибкой.
- Free space VRAM/RAM — свободное пространство на ОЗУ и в видеопамяти, определяющее, сколько памяти дополнительно резервируется для аллокаций на каждый кадр. Эти параметры гарантируют, что в текущем кадре всегда будет достаточно памяти для загрузки ресурсов. Значения должны определяться эмпирически, в зависимости от приложения.
Вы можете указать ограничения на использование и свободное пространство с помощью UnigineEditor или консоли:
- В UnigineEditor откройте окно Settings, перейдите в раздел Streaming и укажите необходимые значения.
-
В консоли передайте необходимые значения соответствующим командам:
Потоковая передача текстур#
Потоковая система автоматически управляет текстурами. Существует два режима потоковой передачи текстур:
- режим Asynchronous, обеспечивающий асинхронную загрузку текстур;
- режим Forced для одновременной принудительной загрузки текстур, необходимых для текущего кадра.
Для оптимизации потоковой передачи текстур вы можете включить загрузку mip-карты текстур, что значительно повышает производительность за счет уменьшения потребления памяти при потоковой передаче текстур. Эта функция позволяет загружать правильную mip-карту в текущий момент. Когда включена загрузка mip-карт, текстуры, которые в данный момент не используются, выгружаются.
Чтобы включить и настроить загрузку mip-карт через UnigineEditor, выполните следующие действия:
- Откройте окно Settings и перейдите в раздел Streaming.
- Установите флажок Mipmaps и укажите требуемое значение Mipmaps Density.
Mipmaps Density устанавливает плотность отображения mip-карт относительно разрешения экрана и помогает определить, какая mip-карта должна быть загружена в текущий момент. Вы можете задать разные значения для разных настроек качества. Например, вы можете установить плотность менее 1 для пресета низкого качества. В этом случае движок загрузит мип-карты с низким разрешением, и текстуры будут выглядеть размытыми.
Кроме того, для достижения желаемого визуального эффекта в некоторых материалах может потребоваться настроить значение Texture Streaming Density Multiplier для каждой текстуры.
Принудительная потоковая передача текстур в материалах с постэффектами#
Чтобы обеспечить доступность всех текстур для постэффектов при необходимости, для всех постматериалов по умолчанию установлен режим принудительной потоковой передачи. Вы можете найти эту настройку в разделе Material Editor.
Однако, если некоторые текстуры в материале постэффекта постоянно меняются (с помощью кода, трекера и т.д.), рекомендуется указать принудительный режим потоковой передачи для каждой текстуры:
- В параметре Material Editor установите значение Setting For Each Texture в параметре Textures Streaming Mode для вашего материала для постэффектов.
- Включите и выключите принудительную потоковую передачу для каждой текстуры в отдельности на панели Parameters редактора материалов.
Эти настройки переопределяют глобальные настройки потоковой передачи текстур, указанные в окне Settings.
Потоковая передача мешей#
Меши можно загружать в оперативную память и видеопамять отдельно для более эффективной работы с геометрией. Это позволяет устранить утечки памяти: меши, участвующие в коллизиях и пересечениях, можно загружать только в оперативную память в том случае, если они в данный момент не отрисовываются.
Существует два режима потоковой передачи мешей в RAM/VRAM:
- Асинхронный режим, обеспечивающий асинхронную загрузку мешей.
- Принудительный режим для одновременной принудительной загрузки мешей, необходимых для текущего кадра.
Асинхронная загрузка в RAM и VRAM отличается. Даже если меш не был загружен в видеопамять вовремя, это не влияет на поведение приложения (вы можете заметить только некоторую задержку). Однако, если меш не был загружен в память вовремя, это может привести к неправильному физическому поведению объектов в сцене.
Прежде всего, мы настоятельно рекомендуем вам использовать физические формы (shape) для обнаружения столкновений и пересечений, поскольку это быстрее. Если по какой-то причине это вам не подходит, воспользуйтесь следующими методами:
- Загружайте меши и сохраняйте их в памяти, пока они существуют. В API некоторых объектов на основе меша эта функциональность предусмотрена. Это может частично решить проблему с некорректным поведением, однако загруженными могут оставаться только несколько мешей.
-
Используйте систему предварительной выборки, которая позволяет асинхронно предварительно загружать меши, участвующие в коллизиях и пересечениях, в память перед их использованием:
- Установите режим предварительной выборки Radius.
- Укажите физический радиус (для столкновений) и/или радиус, в пределах которого рассчитываются пересечения.
- Укажите радиус предварительной выборки, который должен превышать значения радиуса столкновения и пересечения.
Вы также можете предварительно загрузить все меши, для которых вычисляются коллизии и пересечения (режим предварительной выборки Full), однако это значительно увеличит использование оперативной памяти.
- В API некоторых mesh-объектов, а также API класса MeshRender также есть методы, которые позволяют реализовать пользовательскую логику предварительной выборки для предварительной загрузки мешей.
Асинхронно передаваемые меши не должны изменяться. Единственный способ изменить такой меш — сделать его процедурным. Процедурный меш — это меш, созданный с помощью кода, такие меши имеют определенный режим потоковой передачи — они всегда сохраняются в памяти после создания и никогда не выгружаются, пока объект не будет уничтожен через код или меш не вернется в свой обычный режим (потоковая передача из исходного файла). API объектов на основе меша позволяет переключать меш в процедурный режим и применять изменения.