Отрисовка в Unreal Engine
Введение в отрисовку в игровых движках
Отрисовка — это процесс создания конечного изображения (кадра) на экране из набора объектов в сцене.
Программное обеспечение, используемое для отрисовки кадра, называется модулем отрисовки, и эти модули обычно классифицируются в зависимости от решаемой задачи:
Автономная отрисовка: ориентирована на качество, когда время обработки не так важно. Обычно используется в приложениях, в которых время отрисовки не имеет значения по сравнению с качеством отрисовки конечного кадра.
Отрисовка в реальном времени: ориентирована на высокую производительность и быструю отрисовку кадров. Типичные целевые значения частоты кадров в реальном времени составляют 30 (33 мс), 60 (16 мс) и 120 (8 мс) кадров в секунду (FPS), но фактическая частота кадров может меняться со временем в зависимости от ряда факторов. В проектах с отрисовкой в реальном времени нужно искать баланс между производительностью и качеством, чтобы поддерживать постоянную частоту кадров. Модули отрисовки в реальном времени обычно используются в интерактивных медиа, таких как видеоигры, симуляции и архитектурная визуализация.
Unreal Engine предлагает мощный набор инструментов отрисовки в реальном времени, отвечающий потребностям различных платформ: от мобильных устройств до мощных настольных компьютеров. Unreal Engine способен выполнять высококачественную отрисовку как в реальном времени, так и в автономном режиме. С его помощью можно создавать что угодно — от интерактивных 2D- и 3D-изображений на мобильных, консольных и настольных платформах до заключительных кадров в видео для кино и телевидения.
В отличие от других движков реального времени, доступных на рынке, Unreal Engine предлагает множество фирменных функций, ориентированных на быструю работу в реальном времени. Цель — снизить сложность разработки и быстрее получить результаты, сохранив при этом высокое качество и производительность.
Важную роль в упрощении разработки играют такие функции, как Система глобального освещения и отражений Lumen, Виртуализированная геометрия Nanite и Виртуальные карты теней. Эти функции обеспечивают оптимальную работу приложений как на консолях, так и на компьютерах. Мобильные платформы поддерживают динамическое освещение и рабочие процессы с предварительно рассчитанным освещением, которые требуют предварительного запекания освещения в текстурах.
Введение в отрисовку в Unreal Engine
Для вывода изображения (или кадра) на экран игровые движки выполняют ряд шагов, часто называемых конвейером отрисовки. В этом разделе описывается, как Unreal Engine осуществляет вывод с помощью своего пути отложенной отрисовки по умолчанию. При необходимости также проводится сравнение с процессом отложенной отрисовки в Unity.
В движке Unity применяются три различных конвейера отрисовки: Built-In (Встроенный), Universal (Универсальный) и High Definition (Высокого разрешения). Каждый конвейер имеет свою область применения и обычно выбирается перед началом проекта.
Unreal Engine использует унифицированный конвейер отрисовки, который масштабирует отдельные функции исходя из целевой платформы — от портативных и мобильных устройств до новейших консолей и ПК. Это означает, что вы можете выбрать путь отрисовки и поддерживаемые функции, лучше всего отвечающие проекту, не привязываясь к одному пути.
Конвейер отрисовки Unreal Engine можно использовать с отложенной отрисовкой по умолчанию или настроить на работу с использованием пути прямой отрисовки. Кроме того, вы можете включить путь мобильной отрисовки, чтобы приложение хорошо работало на низкопроизводительных устройствах, включив модуль мобильной отрисовки Vulkan. Дополнительную информацию о функциях отрисовки, поддерживаемых для каждого пути отрисовки, см. в разделе Supported Features by Rendering Path (Поддерживаемые функции в зависимости от пути отрисовки).
На изображении ниже представлена высокоуровневая визуализация шагов, которые Unreal Engine выполняет в каждом кадре для отрисовки конечного изображения с использованием пути отложенной отрисовки:
Процесс выполнятся слева направо, при этом шаги с 2 по 5 выполняются параллельно.
Ниже приводятся дополнительные сведения о каждом из этих шагов конвейера отрисовки и о том, что требуется для отрисовки каждого кадра.
Подготовка сцены и затенение
Unreal Engine имеет три основных потока — игровой (ЦП), поток отрисовки и поток GPU.
Перед началом процесса отрисовки игровой поток (или поток ЦП) собирает преобразования всех объектов в сцене. Это включает обработку всех анимаций, физических симуляций и применение искусственного интеллекта (ИИ) перед получением окончательного преобразования каждого объекта.
Затем информация о преобразованиях передаётся в поток отрисовки ЦП. Поток отрисовки запускает процесс исключения, который создаёт список видимых объектов в текущем поле зрения камеры и удаляет все прочие объекты, которые не видны камере. Эти объекты не требуется отрисовывать, и их исключение из отрисовки повышает производительность.
Данный процесс включает следующие шаги (по порядку):
Исключение по расстоянию: удаление всех объектов, находящихся дальше определённого расстояния от камеры.
Исключение в соответствии с пирамидой видимости: удаление объектов, которые не видны внутри пирамиды (конуса) видимости камеры.
Исключение загороженных объектов: точная проверка видимости всех оставшихся объектов в сцене. Этот метод требует много ресурсов и поэтому применяется в конце процесса исключения загороженных объектов, когда оставшиеся видимые объекты дополнительно проверяются на предмет того, не загорожены ли они другими объектами.
Окончательный список видимых объектов передаётся в поток ГП, чтобы начать процесс отрисовки.
Аналог в Unity
Движок Unity выполняет в своём конвейере отрисовки исключение в соответствии с пирамидой видимости и исключение загороженных объектов. Кроме того, он может выполнять исключение по расстоянию с помощью API CullingGroup. Сочетание этих методов даёт окончательный список видимых объектов в сцене.
Отрисовка геометрии
На этом шаге Unreal Engine просматривает список видимых объектов в сцене и подготавливает их к следующему шагу, на котором он преобразует 3D-данные о вершинах в данные пикселей, отображаемых на экране.
Шейдеры вершин
Шейдер — это фрагмент кода, который выполняется непосредственно на GPU и производит ряд вычислений. Шейдеры весьма эффективны, и GPU может производить множество шейдерных вычислений параллельно.
Шейдер вершин последовательно выполняет следующие задачи:
Преобразует локальные положения вершин в позиции в мире: данные вершин объекта хранятся в локальном пространстве, но при размещении объекта в мире информацию о вершинах необходимо преобразовать в координаты в пространстве мира.
Обрабатывает затенение и окрашивание вершин: шейдер вершин обрабатывает сглаживание вершин, а также все данные о цвете вершин в самом объекте.
При необходимости применяет дополнительные смещения к позициям вершин: шейдер вершин может сместить позицию любой вершины на экране для достижения определённых эффектов. Это осуществляется посредством материала объекта и называется смещением позиции в мире.
Проход в глубину
Перед отрисовкой отдельных объектов Unreal Engine выполняет проход в глубину или предварительный проход по оси Z, чтобы определить расположение объектов относительно друг друга. Такой подход исключает многократную отрисовку одних и тех же пикселей Unreal Engine. Это называется избыточной отрисовкой и может существенно снижать производительность. Движок пытается, насколько возможно, избежать этого.
Вызовы отрисовки
После прохода вглубину GPU отрисовывает каждый объект, одновременно изображая все полигоны с одинаковыми свойствами, такие как сетки и материалы. Это называется вызовом отрисовки.
Все полигоны объекта, которым назначен один и тот же материал, обрабатываются в одном вызове отрисовки. Однако для каждого уникального материала требуется отдельный вызов отрисовки. Например, для каждого объекта на экране нужен как минимум один вызов отрисовки, но их может потребоваться и больше в зависимости от количества материалов, назначенных объекту.
Функция Виртуализированная геометрия Nanite Unreal Engine одновременно отрисовывает все полигоны всех объектов из заданного материала. Ресурсы памяти кадров больше не ограничиваются количеством полигонов, вызовами отрисовки или памятью, занимаемой сетками.
Аналог в Unity
Конвейер отрисовки Unity выполняет схожие шаги, производя проход вглубину и используя вызовы отрисовки для изображения объектов в сцене.
Растеризация и геометрический буфер
Процесс растеризации преобразует 3D-данные вершин в 2D-данные пикселей, которые отображаются на экране. Этот процесс начинается после того, как шейдер вершин завершает обработку всех своих данных.
В геометрическом буфере (GBuffer) Unreal Engine хранится ряд изображений с информацией о геометрии в сцене. Эти изображения обычно включают информацию о базовом цвете, нормали мира, металлическом отливе, шероховатости и глянце объектов в сцене. Данные изображения в GBuffer компонуются таким образом, чтобы получить конечное изображение, которое вы видите на экране.
Процесс преобразования этих составных изображений происходит для каждого отрисовываемого кадра и для каждого вызова отрисовки, в котором данные вершин преобразуются в данные пикселей, в результате чего отрисовываются надлежащие части изображений в GBuffer.
Аналог в Unity
В пути отложенной отрисовки Unity также используется GBuffer для хранения важной информации о сцене. В Unity буфер GBuffer содержит схожую информацию об объектах (которая называется немного по-другому): альбедо, глянец, нормаль, а также данные излучения/освещения.
Отрисовка текстур
Unreal Engine отрисовывает текстуры, используя подгрузку текстур для оптимизации загрузки текстур в сцену. Система подгрузки текстур использует мип-карты. Это предварительно рассчитанная последовательность изображений одной текстуры в разных разрешениях. Данные карты можно рассматривать как уровни детализации (LOD) для текстур, а не для сеток. Движок автоматически создаёт MIP-карты, в которых разрешение каждого изображения в два раза меньше предыдущего.
Unreal Engine транслирует MIP-карту текстуры во время игрового процесса в зависимости от расстояния до камеры. Это делается автоматически, чтобы оптимизировать передаваемый трафик и потребление памяти, а также снизить уровень шума вдали от камеры.
Для создания MIP-карт размеры текстур должны быть кратны степени двойки. Обычно текстуры имеют размеры 3840×2160 пикселей (4K) и 1920×1080 пикселей (HD). Обратите внимание, что текстуры не обязательно должны иметь определённое соотношение сторон. Например, текстура с размером 1920×480 пикселей также будет поддерживать MIP-карты.
Аналог в Unity
Система подгрузки мип-карт Unity использует мип-карты текстур для подгрузки текстур во время выполнения. Подобно Unreal Engine, эта система автоматически подгружает соответствующую MIP-карту текстуры в зависимости от расстояния до камеры и угла её обзора.
Пиксельные шейдеры и материалы
После полной отрисовки объектов в GBuffer движок Unreal Engine начинает затенять каждый объект на экране, используя свойства материала объекта, с помощью пиксельных шейдеров.
Пиксельный шейдер выполняет ряд вычислений для изменения цвета пикселя на экране. Пиксельные шейдеры обрабатываются GPU и чрезвычайно эффективны. Они обеспечивают работу системы материалов Unreal Engine и используются при расчёте освещения, тумана, отражений и эффектов постобработки.
В системе материалов используются шаблоны шейдеров на языке высокого уровня для программирования шейдеров (HLSL) наряду с Редактором материалов для создания окончательных материалов, которые применяются к объектам на экране. Эти материалы могут иметь параметры, такие как текстуры, определяющие внешний вид каждого объекта.
Аналог в Unity
Для создания шейдеров в проекте Unity предлагает несколько готовых шейдеров (которые эквивалентны материалам в Unreal Engine), а также с граф шейдеров. Редактор материалов Unreal Engine эквивалентен графу шейдеров Unity.
Отражения
После затенения всех объектов в сцене Unreal Engine начинает отрисовку отражений объектов, исходя из свойств их материалов.
Для отрисовки отражений в сцене Unreal Engine использует четыре системы. Эти системы применяются в следующем порядке:
Захват отражений: данные рассчитываются предварительно и сохраняются в статичной кубической карте в определённом месте.
Отражения на плоскости: захватываются отражения от плоскости и отражения, падающие на неё.
Отражения в пространстве экрана (SSR): доступная на экране информация используется для отрисовки точных отражений объектов в реальном времени.
Отражения Lumen: рассчитываются отражения для всего диапазона значений шероховатости в сцене. Такие отражения поддерживают небесный свет, прозрачные материалы покрытий, полупрозрачность и даже однослойные материалы воды.
Unreal Engine сочетает три метода, отдавая приоритет отражениям в пространстве экрана. Затем движок обращается к плоскостным отражениям и, наконец, к захвату отражений. Конечный результат расчёта отражений объединяется с данными шероховатости, глянца и металлического отлива в буфере.
Если вы используете глобальное освещение Lumen, будут автоматически использоваться отражения Lumen. Однако вы также можете использовать отражения Lumen без глобального освещения Lumen. В этом случае Unreal Engine будет использовать прописанное освещение с отражениями Lumen.
Аналог в Unity
В Unity схожую функциональность обеспечивают зонды отражения, которые используются для предварительного расчёта данных отражения в сцене.
Статичное освещение и тени
После отрисовки отражений Unreal Engine отрисовывает статичное освещение и тени для всех объектов в сцене.
Unreal Engine использует свою систему Глобальное освещение Lightmass для предварительного расчёта данных освещения в сцене. Информация об освещении и тенях хранится в текстуре UV-развёртки карты освещения, и эта текстура смешивается с базовым цветом объекта при отрисовке объекта в сцене.
Эта система очень быстрая, но требует больше памяти и предварительного расчёта всякий раз, когда происходит изменение сцены.
Система глобального освещения Lightmass хорошо подходит для проектов, ориентированных на мобильные и низкопроизводительные устройства.
Аналог в Unity
Progressive Lightmapper (Прогрессивный модуль создания карт освещения) и Enlighten Baked Global Illumination (Прописанное глобальное освещение Enlighten) в Unity обеспечивают схожую функциональность при предварительном расчёте освещения сцены.
Динамическое освещение и тени
После отрисовки статичного освещения Unreal Engine отрисовывает динамическое (в реальном времени) освещение и тени с помощью своей динамической системы глобального освещения Lumen.
Lumen — это полностью динамическая система глобального освещения и отражений, разработанная для консолей нового поколения и высокопроизводительных ПК. Система использует несколько методов трассировки лучей для расчёта глобального освещения и отражений в необходимом масштабе.
Lumen поддерживает бесконечные рассеянные отражения и безупречно работает с системой Виртуализированной геометрии Nanite. Кроме того, Lumen работает совместно с виртуальными картами теней для создания мягких теней высокого разрешения в режиме реального времени.
Lumen обеспечивает отражения Lumen, которые рассчитываются для всего диапазона значений шероховатости в сцене. Такие отражения поддерживают небесный свет, прозрачные материалы покрытий, полупрозрачность и даже однослойные материалы воды.
При использовании в сцене Lumen заменяет отражения в пространстве экрана.
Аналог в Unity
Unity обеспечивает динамическое освещение сцены с помощью системы Enlighten Realtime Global Illumination (Глобальное освещение в реальном времени Enlighten). Эта система обеспечивает глобальное освещение в реальном времени, используя предварительно рассчитанную информацию о видимости и карты освещения для расчёта непрямых отражений света во время выполнения.
Этим она отличается от Lumen, поскольку Lumen не требует никаких предварительно рассчитанных данных для получения непрямых отражений света.
Туман и прозрачность
После отрисовки динамического освещения и теней Unreal Engine отрисовывает эффекты тумана и прозрачности.
Unreal Engine отрисовывает эффекты тумана с помощью своей системы тумана с экспонентой высоты, которая рассчитывает плотность тумана исходя из высоты и расстояния от камеры. Кроме того, система может генерировать объёмный туман.
Для прозрачных объектов, отрисовываемых на данном шаге процесса, используется прозрачный материал. При использовании пути отложенной отрисовки Unreal Engine отрисовывает прозрачность исходя из информации, доступной в GBuffer. В качестве альтернативы вы можете настроить материал таким образом, чтобы он использовал путь прямой отрисовки, что даст более точный эффект прозрачности.
Аналог в Unity
Unity поддерживает линейный, экспоненциальный и экспоненциальный квадратичный туман в сцене.
Эффекты постобработки
После отрисовки тумана и прозрачности Unreal может применить к изображению дополнительные эффекты. Эти эффекты называются эффектами постобработки, так как они применяются после обработки конечного изображения. Эффекты основаны на пиксельном шейдере и используют информацию из GBuffer.
Распространённые эффекты постобработки включают ореол (свечение), глубину резкости, сумеречные лучи, преобразование динамического диапазона и размытие в движении.
На этом шаге постобработки Unreal Engine может применить Временное сверхвысокое разрешение (TSR). TSR — это не зависящий от платформы модуль временного повышения разрешения, используемый Unreal Engine для отрисовки великолепных изображений в формате 4K. Изображения требуют в разы меньше ресурсов за счёт одновременного выполнения некоторых затратных вычислений отрисовки для многих кадров сразу.
В цепочке отрисовки временное сверхвысокое разрешение устанавливается после применения глубины резкости. Разрешение повышается для всех последующих эффектов, например для размытия в движении, ореола и т. д.
После применения этих эффектов к GBuffer Unreal Engine отрисовывает окончательное изображение на экране.
В результате описанных выше шагов создаётся один кадр на экране. Эти шаги повторяются с частотой от 30 до 60 раз в секунду в зависимости от целевой частоты кадров в игре.
Аналог в Unity
Unity включает решения постобработки, основанные на выбранном конвейере отрисовки. Многие из доступных эффектов аналогичны тем, что есть в Unreal Engine.
Кроме того, в Unity 6 имеется собственная функция Spatial-Temporal Post-processing (STP) (Пространственно-временная постобработка). Это программный модуль масштабирования, использующий методы пространственной и временной дискретизации для получения высококачественного сглаженного изображения.
Обзор функций отрисовки в Unreal Engine
Теперь, когда вы понимаете, какие шаги выполняет Unreal Engine для отрисовки кадра на экране, вы готовы узнать больше о конкретных функциях отрисовки, доступных в движке.
Дополнительную информацию о функциях отрисовки Unreal Engine см. в разделе Lighting the Environment (Освещение окружения).