Как устроены технологии графики в современных играх
Gamedev
Empty Node

Nanite: cистема виртуализированной геометрии в Unreal Engine 5

Данная статья является переводом раздела документации Unreal Engine 5. Ссылка на оригинал находится в конце статьи.

Обзор системы виртуализированной геометрии в Unreal Engine 5, которая позволяет визуализировать огромное количество объектов с детализацией пиксельного масштаба.

Nanite — это новая система виртуализированной геометрии в Unreal Engine 5 которая использует новый внутренний формат мешей и технологию рендеринга для визуализации деталей в масштабе пикселей и большого количества объектов. Она грамотно работает только с теми деталями, которые можно увидеть, и не более того. Формат данных Nanite обладает высокой степенью компрессии и поддерживает стриминг на уровне мелких структурных единиц, с автоматическим уровнем детализации.

Преимущества системы Nanite

  • Увеличение сложности геометрии на несколько порядков — большее количество треугольников и объектов, обрабатываемых в режиме реального времени, чем это было возможно ранее.
  • Теперь, бюджеты на кадр больше не ограничены количеством полигонов, вызовами на отрисовку и использованием памяти для геометрии.
  • Теперь можно напрямую импортировать исходный арт кинематографического качества, такой как скульптуры, сделанные в ZBrush или сканы полученные при помощи фотограмметрии.
  • Используйте высокополигональную детализацию вместо запекания деталей в текстуры типа Normal Map.
  • Уровени Детализации обрабатываются автоматически и больше не требует ручной настройки LOD'ов для отдельно взятых мешей.
  • Потери в качестве практически полностью отсутствуют, особенно это касается переходов между LOD'ами.

Примечание: Несмотря на то, что данные преимущества могут в значительной степени изменить устоявшиеся «правила игры», на практике, некоторые ограничения всё же остаются. Например, количество экземпляров (instance), количество треугольников выделяемых на меш, сложность материала, выходное разрешение и производительность должны быть тщательно измерены для любой комбинации контента и оборудования. По мере выхода новых версий Unreal Engine 5, производительность системы Nanite будет повышаться, а её возможности расширяться.

В чём разница между Nanite Mesh и Static Mesh

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

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

Nanite меши поддерживают несколько UV-разверток (UV каналов) и Vertex Colors (Цвета вершин). Материалы назначаются на секции (sections) меша. Эти материалы могут использовать различные модели затенения и динамические эффекты, которые могут быть сделаны при помощи шейдеров. Назначение материалов можно менять динамически, как и в любом другом Статическом Меше. Системе Nanite не требуется какой-либо дополнительный процесс для запекания материалов.

Виртуальные Текстуры (Virtual Textures) не обязательно использовать вместе с системой Nanite, но это крайне рекомендуется. Virtual Textures — это ортогональная функция Unreal Engine с схожими целями для текстурных данных (texture data), которые Nanite достигает с помощью данных меша (mesh data).

Несмотря на то, что подход к работе с Nanite мешами схож с тем подходом который используется для статических мешей, многие из привычных вещей всё еще не поддерживаются. Дополнительные сведения смотрите в разделе «Поддерживаемые функции» на этой странице.

Как работает система Nanite?

Система Nanite максимально органично интегрируется в существующие рабочие процессы движка, используя новый подход к хранению и рендерингу геометрических данных (mesh data).

  • Во время импорта: меши анализируются и разбиваются на иерархические кластеры состоящие из групп треугольников (clusters of triangle groups).
  • Во время рендеринга: на разных уровнях детализации в зависимости от положения камеры, эти кластеры меняются (swapped) прямо на лету, и идеально без всяких швов соединяются с соседними кластерами, внутри одного и того же объекта. Стриминг (потоковая передача) данных выполняется по запросу, по этому в памяти должны находится только видимые детали. Система Nanite выполняется в своём собственном проходе рендеринга (rendering pass), который полностью обходит традиционные вызовы отрисовки (draw calls). Для инспектирования Nanite pipeline вы можете использовать соответствующие режимы Визуализации (Visualization modes).

Примечание: Поскольку Nanite полагается на возможность быстрой потоковой передачи геометрических данных с диска по запросу. Для хранения данных используемых непосредственно во время выполнения рекомендуется использовать твердотельные накопители (SSD).

Для каких типов Мешей следует использовать Nanite

Система Nanite, как правило, должна быть активирована везде где это возможно. Любые Статические Меши для которых она активирована буду рендериться быстрее, а также занимать меньше памяти и места на диске.

Если говорить точнее, то Меш будет хорошим кандидатом для работы с Nanite, если он:

  • Содержит много треугольников или имеет треугольники очень маленького размера (на экране).
  • Имеет множество экземпляров в сцене.
  • Действует как основной окклюдер (блокатор) для остальной Nanite геометрии.

Полной противоположностью этих правил, будет что-то вроде небесной сферы: на экране её треугольники будут большими, они ничего не загораживают, а на сцене она находится в единственном экземпляре.

В Early Access некоторые сценарии использования Nanite не поддерживаются. Дополнительные сведения смотрите в разделе «Поддерживаемые функции» на этой странице.

Включение поддержки Nanite для мешей

Активировать систему Nanite для поддерживаемой геометрии можно следующими способами: в процессе импортирования; открыв индивидуальный Mesh Editor; через функцию пакетного выбор (batch selection) в Content Browser.

Для преобразования геометрии каждого меша в формат Nanite требуется некоторое время. В крупных проектах использование общего Derived Data Cache (DDC) особенно полезно, если у вас много Nanite ассетов. Для получения дополнительной информации, обратитесь к разделу документации Shared DDC.

Импортирование Static Mesh

При импорте меша который будет работать совместно с Nanite, просто поставьте галочку Build Nanite, в соответствующем диалоговом окне.

СОВЕТ: Если вы не используете освещение, предварительно рассчитанное с помощью Lightmass, рекомендуем отключить опцию Generate Lightmap UVs.

Если данная опция включена, наличие высоко-детализированной геометрии может значительно увеличить время импорта и обработки/сборки данных Static Mesh'а. Кроме того, это свойство добавляет дополнительный UV-канал, который может содержать значительный объем данных для мешей с очень высокой плотностью полигонов. Если ваш проект не требует наличия запеченного освещения, то в дополнительных расходах, подобного рода, нет никакой необходимости.

Пакетный выбор и редактирование отдельных ассетов

Если ваш проект уже наполнен различным контентом, и вы хотите активировать Nanite, у вас есть два варианта: настройка ассетов в пакетном режиме с помощью Content Browser или настройка отдельно взятых ассетов через их собственные редакторы.

С помощью Content Browser выберите нужные вам Static Mesh Assets, кликните ПКМ и выберите пункт Nanite → Enable.

Кроме того, вы можете открыть Static Mesh Assets и Geometry Collections (разрушенные меши управляемые физикой Chaos) в соответствующих редакторах и включить Nanite через панель Details.

Для Static Meshes:

  • Откройте Static Mesh Asset.
  • На панели Details в разделе Nanite Settings, поставьте галочку напротив Enabled.
  • Нажмите кнопку Apply Changes.

Для Geometry Collections:

  • Откройте Geometry Collection Asset.
  • На панели Details в разделе Nanite, поставьте галочку напротив Enable Nanite.

Поддерживаемые функции Nanite

В последующих разделах описывается, как лучше всего работать с системой Nanite в проектах для Unreal Engine 5 Early Access.

Геометрия

Nanite можно активировать для Static Meshes и Geometry Collections.

Меш работающий в режиме Nanite можно использовать в качестве компонентов следующих типов (Component types):

  • Static Mesh
  • Instanced Static Mesh
  • Hierarchical Instanced Static Mesh
  • Geometry Collection

В настоящее время функционал Nanite ограничен твердотельными мешами (rigid meshes). Они составляют более 90% геометрии, любой типичной сцены для проектов и являются первоначальной целью разработки Nanite. Nanite поддерживает динамическое перемещение, вращение и неравномерное масштабирование твердотельных мешей, но не поддерживает общую деформацию меша, будь то динамический или статический меш. Это значит, что любое из положений Nanite меша является более сложным, чем может быть выражено в одной матрице 4x3, умноженной на весь меш.

Деформацию не поддерживают следующие элементы:

  • Скелетные анимации (Skeletal animation)
  • Цели морфинга (Morph Targets)
  • Смещение мировой позции (World Position Offset) в Материалах
  • Сплайновые меши (Spline meshes)

Кроме того, Nanite меши не поддерживают следующие вещи:

  • Custom Depth или Stencil
  • Рисование по вершинам (Vertex painting) на экземплярах
  • В частности, это означает цветовую окраску вершин для каждого экземпляра при помощи режима Mesh Paint.
  • Поддерживаются Vertex Colors, которые были импортированны вместе с исходным мешем.

Максимальное количество экземпляров, которое может присутствовать в сцене, ограничено двумя миллионами. В это число входят все экземпляры, которые передаются в потоковом режиме, а не только те, что работают в режиме Nanite. Учитываются только те экземпляры, которые передаются в потоковом режиме. Данное направление будет активно улучшаться в будущих релизах Unreal Engine.

Касательные к вершинам (Per vertex tangents) не хранятся в Static Mesh если те работают в режиме Nanite. Вместо этого, касательное пространство (tangent space) неявным образом выводится в пиксельный шейдер. Данные о касательных (Tangent data) не сохраняются с целью уменьшения размера данных. При использовании данного подхода, в касательном пространстве существует отличие, которое может вызвать разрывы на ребрах/краях. Однако, на данный момент это не является существенной проблемой, а добавление поддержки касательных к вершинам планируется в следующих выпусках Unreal Engine.

Материалы

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

ПРИМЕЧАНИЕ: Неподдерживаемые материалы буду использовать стандартный материал и выводить оповещение в Output Log с дополнительными деталями.

  • Любые Blend Mode за исключением Opaque. Включая режимы смешивания Masked и Translucent
  • Отложенные Декали (Deferred Decal). Например, использование Nanite меша для Mesh Decals. Поддерживаются меши-декали (Decal meshes) проецируемые на Nanite меши.
  • Wireframe
  • Pixel Depth Offset
  • World Position Offset
  • Custom Per-Instance Data
  • Two Sided

Материалы, которые используют нижеследующие элементы, при применении к Nanite мешам могут визуализироваться не корректно или выглядеть сломанными.

  • нод Vertex Interpolator
  • Custom UVs

Рендеринг

В данный момент не поддерживаются следующие возможности рендеринга:

  • Фильтрация объектов в зависимости от вида, при помощи:
  • Scene Capture вместе с: Hidden Components, Hidden Actors, Show Only Components, Show Only Actors.
  • Minimum Screen Radius
  • Distance culling
  • Всё что угодно, фильтруемое посредством FPrimitiveSceneProxy::IsShown()
  • Forward Rendering
  • Stereo rendering for Virtual Reality
  • Split Screen
  • Multisampling Anti-Aliasing (MSAA)
  • Lighting Channels
  • Трассировка Лучей по отношению к полностью детализированному Nanite мешу. Функции Ray Tracing поддерживаются, но лучи пересекают грубое представление модели (называемое Прокси-Мешем), вместо полностью детализированного Nanite меша.
  • Некоторые режимы визуализации пока не поддерживают отображение Nanite мешей.

ВНИМАНИЕ: Будьте осторожны при использовании некоторых режимов визуализации в Static Mesh Editor, особенно при просмотре высоко-детализированной геометрии. Viewing Normals и UV может вызвать проблемы с производительностью редактора и его отзывчивостью.

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

Nanite в данный момент поддерживает PlayStation 5, Xbox Series S|X, и PC с видеокартами, которые соответствуют спецификациям указанным ниже, и используют драйвера последних версий с DirectX 11 или 12:

  • NVIDIA: Карты поколения Maxwell или более новые
  • AMD: Карты поколения GCN или более новые

Nanite Proxy Mesh и настройки точности

Nanite Static Meshes обладают дополнительными свойствами которые управляют точностью репрезентации Nanite, а грубое представление, которое генерируется на основе высоко-детализированного меша, называется Proxy Mesh (Прокси Меш).

Эти настройки можно найти в редакторе Static Mesh Editor на панели Details в разделе Nanite Settings.

Точность положения вершин

Nanite квантует (quantizes) позиции вершин меша, чтобы максимизировать плотность памяти и минимизировать занимаемое место на диске. Размер шага квантования (quantization step) — это степень двойки, которую можно выбрать в соответствии с требованиями отдельных мешей, с помощью свойства Position Precision. Значение Auto, которое стоит по умолчанию, позволяет Nanite выбрать подходящую точность, в зависимости от размера меша и плотности треугольников. Кроме того, точность можно изменить вручную, чтобы повысить её или оптимизировать место занимаемое на диске.

ПРИМЕЧАНИЕ: Всегда будет существовать что-то такое, что может быть достигнуто только путём тонкой и точной ручной настройки. Однако, предполагается, что эвристические правила для режима Auto будут продолжать улучшаться, и данный режим станет подходящим компромиссом или, по крайней мере, хорошей отправной точкой для большинства обрабатываемых мешей..

Квантование (Quantization) — это форма сжатия информации с потерями, а сжатие с потерями особенно сложно контролировать при работе с частями модульных мешей или другими мешами, которые имеют общие границы. Особенно, если эти границы необходимо идеально подгонять друг к другу, чтобы в геометрии не появлялись различные дыры или зазоры. Для обеспечения однородности, квантование происходит в ненормализованных координатах объекта, отцентрованных относительно начала координат меша. Это гарантирует, что процесс квантования никогда не приведёт к появлению зазоров, если сетки используют одинаковые настройки точности, а смещение (translation) между центрами мешей кратно этой точности.

Proxy Mesh

Многие части Unreal Engine нуждаются в доступе к традиционному буферу вершин (vertex buffer), который нужен для мешей визуализируемых традиционным способом. Когда Nanite активирован для статического меша, он генерирует грубое представление, которое доступно и используется там, где высокодетализированные данные Nanite использовать невозможно.

Proxy Mesh — это сгенерированное представление, используемое, в таких случаях (например) когда требуется сложная коллизия или когда платформа не поддерживает рендеринг Nanite. Помимо этого, Proxy Mesh используется в Lightmass, если меш имеет запеченное статическое освещение.

Параметр Proxy Triangle Percent представляет собой процент треугольников из исходного, высоко-детализированного меша, который используется для генерации грубого представления. Текстовое поле принимает значения от 0 до 100, где более высокий процент приводит к сохранению большего количества деталей исходного меша. Значение 100 указывает на то, что децимация/прореживание не выполняется. Вне зависимости от того насколько низким будет значение Proxy Triangle Percent, Пркоси Меш не может быть ужат меньше 2000 треугольников.

В тех случаях, когда Nanite применяется к мешу, который имеет мене 2000 треугольников, в качестве Пркоси Меша будет автоматически использоваться исходный меш. Это происходит из-за того, что в процентном диапазоне для грубого представления, используется жестко запрограммированный минимум в 2000 треугольников.

В Static Mesh Editor вы можете переключаться между полностью детализированным представлением Nanite и сгенерированным представлением Nanite Proxy Mesh, используя команду Show → Nanite Proxy или сочетание Ctrl+N.

В приведенном ниже сравнении показано высоко-детализированное представление Nanite меша по сравнению с созданным (сгенерированным) Прокси Мешем, который используется в тех случаях когда рендеринг Nanite не поддерживается. Это пример меша из технического демо Unreal Engine 5 «Valley of the Ancient Sample».

ПРИМЕЧАНИЕ: В Early Access, статистика по треугольникм и вершинам, которая отображается в Static Mesh Editor, относится только к Прокси Мешу, независимо от того, активирована система Nanite или нет. Чтобы узнать исходное количество треугольников, необходимо временно отключить Nanite на самом меше.

Увеличение значения Proxy Triangle Percent восстанавливает процент детализации исходного меша для представления Proxy Mesh, что может потребоваться, когда платформы или функции не поддерживают рендеринг с помощью Nanite. В приведённом ниже примере показано сравнение между исходным сгенерированным Прокси Мешем и Прокси Мешем с высоким процентом восстановления деталей и примерно в два раза большим количеством треугольников.

Использование Custom Proxy Mesh LOD'ов для мешей работающих в режиме Nanite

Прокси Мешb используются для таких функций движка, как сложные коллизии на уровне полигонов, трассировка лучей, запекание света и т.д. Они также используются для прямой отрисовки (drawing) при работе на платформах, где Nanite не поддерживается.

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

Меши работающие в режиме Nanite используют слот LOD0 для автоматически сгенерированного прокси-меша. Что бы использовать свой собственный прокси (custom proxy), или набор LOD'ов, следуйте следующим шагам:

  • Выставите для параметра Proxy Triangle Percent значение 0, так чтобы прокси был таким маленьким насколько это вообще возможно, поскольку при использовании данного подхода он будет игнорироваться.
  • Добавьте один или более LOD'ов так чтобы меш использовал традиционную систему LOD.
  • В Static Mesh Editor перейдите на панель Details и в разделе LOD Settings найдите параметр Minimum LOD. Установите значение равное 1. Это позволит игнорировать прокси-меш генерируемый системой Nanite.
  • Сложная коллизия (Complex collision) — это особый случай, который требует настройки. Используйте свойство LOD for Collision чтобы выбрать LOD который будет использоваться для коллизий. Это может быть любой LOD, включая LOD 0.

ПРИМЕЧАНИЕ: Использование данного подхода с тем, чтобы сделать Nanite проекты автоматически совместимыми с платформами, не поддерживающими Nanite, может оказаться неосуществимым во всех случаях. Nanite может эффективно обрабатывать очень большое количество экземпляров, но если Nanite отключен, может возникнуть огромное количество вызовов отрисовки для традиционного конвейера рендеринга. Вы можете протестировать проект полностью отключив систему Nanite, с помощью консольной команды r.Nanite 0. Дополнительные сведения смотрите в разделе «Переменные и команды консоли» на этой странице.

Производительность и проблемы с контентом

В большинстве случаев, Nanite отлично масштабируется вместе с разрешением экрана. Это делается на основе двух ключевых методов: мелко-блочный (на уровне мелких структурных единиц) уровень детализации и отсечение на основе окклюзии (occlusion culling). Обычно это означает, что, независимо от геометрической сложности исходных данных в сцене, количество треугольников, которые Nanite пытается нарисовать на экране, довольно-таки постоянно, и пропорционально количеству пикселей. Nanite следует принципу, по которому нет смысла рисовать больше треугольников, чем пикселей.

Существуют определенные типы контента, которые нарушают методы, используемые системой Nanite для масштабирования. Однако, это вовсе не значит, что её вообще не следует использовать для контента подобного рода. Это не значит что при рендеринге она не будет работать быстрее традиционного пайплайна.

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

Совокупная геометрия

Совокупная геометрия (Aggregate geometry) означает множество крошечных разрозненных предметов, которые на расстоянии становятся объемами (volume), например, волосы, листья и трава. Это нарушает как метод уровня детализации (LOD), так и метод отсечени на основе окклюзии (occlusion culling).

Прежде всего, Nanite меш является, по сути, структурой иерархического уровня детализации, которая основана на способности упрощать маленькие треугольники в большие треугольники и выбирать более крупный (coarser) треугольник, в тех случаях когда система определяет, что разница меньше чем можно заметить. Этот подход отлично работает на непрерывных поверхностях (continuous surfaces) и не очень хорошо работает с совокупностями (aggregates), которые издалека выглядят как частично прозрачное облако, а не твёрдая поверхность.

Таким образом, система Nanite с большей вероятностью определит, что она не может уменьшать совокупности (aggregates) так же агрессивно, как это было бы с обычными твердыми поверхностями (solid surfaces). Это приводит к тому, что для того же количества покрывающих пикселей отрисовывается значительно больше треугольников.

Вторая оптимизация, которую совокупности (aggregates) выводят из строя, — это удаление/отсечение скрытых частей (occlusion culling). Несмотря на то, что отсечение выполняется на уровне мелких структурных единиц, степень её детализации не зависит от пикселя. Геометрия, заполненная дырами — и, что еще хуже, множественные слои такой геометрии, — вызывает чрезмерную перерисовку (overdraw), поскольку необходимо выстроить множество слоёв глубины (depth layers), прежде чем эта область на экране перекроет всё, что находится за ней.

Один из способов подумать об этом — рассмотреть область на экране, размером 8x8 пикселей и количество слоёв глубины, которое необходимо нарисовать перед заливкой каждого пикселя. Эта чрезмерная перерисовка (overdraw) означает, что для того же количества покрытых пикселей (pixels covered) Nanite пытается нарисовать больше треугольников. что само-собой приводит к замедлению рендеринга

Листва (Foliage) — это наиболее очевидный, частный, случай данной проблемы, но даже это не означает, что Nanite вообще не следует использовать с мешами данного типа. Естественно, леса, наполненные кронами, сделанными из отдельно смоделированных листьев, почти наверняка не будут работать должным образом, однако использование Nanite для стволов и веток деревьев вполне может сработать. Плющ растущий на стенах зданий тоже может нормально работать, поскольку в идеальных случаях за ним находится только один слой твердой поверхности. Можете поэкспериментировать и посмотреть, что для ваших проектов будет работать хорошо, а что не очень. Для подтверждения хорошей производительности Nanite с определенными типами мешей используйте инструменты профилирования.

Поверхности расположенные вплотную

Метод отсечения геометрии на основе окклюзии (Occlusion culling) вместе с традиционными низкополигональными мешами при работе в больших масштабах, делает подход с использованием китбашинга (kitbashing workflows) практически невозможными из-за конкретных практических ограничений. Мелко-структурная природа отсечения геометрии применяемая в системе Nanite позволяет использовать такой подход с меньшим количеством голвной боли..

Как было сказано в разделе «Совокупная геометрия», перерисовка (overdraw) может происходить из-за того, что скрытые поверхности находятся очень близко, прямо под видимыми поверхностями. Если какая-либо геометрия находится глубоко под видимой поверхностью, Nanite обнаруживает её и отбраковывает/отсекает без значительных затрат в плане производительности. Так что в большинстве случаев этот процесс можно считать бесплатным. Однако, если в сцене есть сложенная геометрия, которая находится близко друг к другу около самой верхней поверхности, Nanite не сможет определить, какая из них находится сверху или снизу, что приведет к отрисовке обеих. Эта конкретная проблема представляет собой наихудший сценарий, когда Nanite не знает, какая поверхность находится наверху, и вместо этого просто рисует все имеющиеся слои. Подобная неточность, к сожалению, соотносится с размером экрана и расстоянием (масштабируется относительно них). Поэтому, 10 сантиметров которые разделяют разные поверхности могут выглядеть хорошо, при близком рассмотрении, но при увеличении дистанции до объекта, разница в расстоянии может стать меньше пикселя, что и приводит к перерисовке.

Данный пример из демонстрационного проекта Unreal Engine 5 «Valley of the Ancients» показывает, насколько плотно расположенные друг над другом поверхности (stacked surfaces) могут привести к множеству перерисовок. Стопа персонажа показана для масштабе, чтобы показать насколько малые область на экране могут быть использованы на больших расстояниях.

Перемещая камеру так, чтобы посмотреть вниз, на ту область, где стоит персонаж, и на эти сложенные друг на друга поверхности, режим визуализации Overdraw может показать, как именно рендерятся эти сложенные поверхности.

Данный режим визуализации — это наиболее э ффективный способ, нахождения подобных проблем. Несмотря на то, что предполагается некоторое количество перерисовок, чрезмерное их количество приведет к увеличению затрат на отсечение/отбраковку (culling) и растеризацию в Nanite, а масштабирование Nanite станет менее эффективным, вне зависмости от сложности самой сцены.

Фасетные нормали

Можно легко импортировать высоко-детализированный меш с фасетными нормалями (faceted normals) и не заметить этого. Вам следует проявить осторожность, чтобы избежать появления фасетных нормалей, поскольку малое количество общих вершин в меше может повысить его стоимость, как с точки зрения производительности рендеринга, так и с точки зрения размера данных. В идеале, количество вершин меша должно быть меньше количества треугольников. Если это соотношение составляет 2:1 или выше, то, вероятно, возникла проблема, особенно если треугольников много. Соотношение 3:1 означает, что меш является полностью фасетным, и каждый треугольник имеет три вершины, ни одна из которых не является общей с другим треугольником. Чаще всего это происходит потому, что нормали не совпадают, поскольку они не сглажены.

Имейте в виду, что чем больше вершин, тем больше данных. Еще это значит, что необходимо выполнять больше работы по преобразованию вершин и соотношение выше 2: 1 может привести к значительному замедлению. Их преднамеренное использование при моделировании твердых поверхностей не должно вызывать проблем, и у вас нет причин не использовать их. Однако, полностью «граненые» меши с очень высокой плотностью полигонов, будут стоить вам намного дороже чем можно представить.

Кроме того, импортированные жесткие нормали (hard normal thresholds),, на поверхностях органического типа с высокой плотностью полигонов, созданные в сторонних DCC пакетах, могут привести к ненужным расходам со стороны Nanite.

Возьмем, к примеру, два меша на изображении показанном внизу. Меш слева имеет фасеточные нормали, а справа - сглаженные нормали. Режим визуализации Nanite's Triangles показывает заметную разницу в количестве треугольников, используемых для отрисовки каждого из них.

Уровень производительности для типичного конента

В целях сравнения, следующие тайминги GPU были взяты из технической демонстрации Unreal Engine 5 «Lumen in the Land of Nanite» для PlayStation 5:

  • Усредненное разрешение ренлеринга составляет 1400p с темпоральным повышением до 4K.
  • ~2.5 миллисекунды (мс) чтобы отбраковать и растеризовать все Nanite меши (которые были практически всем что есть в данной демонстрации).
  • Практически вся использованная геометрия представляла собой Nanite меши.
  • Практически не требует затрат на CPU, так как он на 100% работает на GPU.
  • ~2мс чтобы оценить материалы для всех Nanite мешей.
  • Низкая стоимость CPU с 1 вызовом отрисовки (draw call) на материал, присутствующий в сцене.

Если рассматривать эти временные значения GPU все вместе, то в сумме? это примерно 4.5ms, что соответствует проходу глубины (depth prepass) плюс основному проходу (base pass) в Unreal Engine 4. Это делает систему Nanite хорошо подходящей для игровых проектов, которые ориентированны на 60 FPS.

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

Размер данных

Из-за микродетализации, которой способна достигать система Nanite, можно предположить, что объем геометрических данных значительно увеличится, что в свою очередь приведет к увеличению размеров игровых архивов и времени загрузок для игроков. Однако, на самом деле, все не так страшно. Фактически, формат для хранения мешей в Nanite значительно меньше стандартного формата Static Mesh, поскольку в Nanite используется специальное кодирование (сжатие) мешей.

В качестве примера возьмем Unreal Engine 5 Valley of the Ancients, здесь Nanite меши в среднем потребляют 14,4 байта на треугольник. Это означает, что в среднем Nanite меш состоящий из одного миллиона треугольников будет занимать на диске ~ 13,8 мегабайт (МБ).

Если сравнить традиционную низкополигональный меш и его карту нормалей с высокополигональным Nanite мешем, вы увидите что-то вроде этого:

Однако, размер сжатого пакета — это не весь размер ассета. Помимо этого, необходимо учитывать уникальные текстуры, используемые только этим мешем. Многие материалы, используемые мешами, имеют свои собственные уникальные текстуры, состоящие из различных карт, таких как Normal, BaseColor, Metallic, Specular, Roughness и Mask.

В этом конкретном ассете используются только две текстуры (BaseColor и Normal), именно поэтому он не так требователен к месту на диске, как ассет со множеством других уникальных текстур. Например, обратите внимание, что размер Nanite меша с ~ 1,5 миллионами треугольников, меньше (19,64 МБ), чем текстура карты нормалей в разрешении 4K.

Общий размер сжатого пакета с мешем и его текстурами:

  • Низкополигональный меш: 31.04MB
  • Высокополигональный меш: 49.69MB

Поскольку Nanite меш уже очень детализирован, мы можем попробовать заменить уникальную карту нормалей (normal map) на тайловую детализированную карту нормалей, которая используется совместно с другими ассетами. Хотя в данном случае это приведет к некоторой потере качества, она довольно мала и определенно намного меньше, чем разница в качестве между низкополигональной и высокополигональной версиями. Таким образом, Nanite меш с 1,5M треугольников может выглядеть лучше и быть меньше, чем низкополигональный меш с картой нормалей в разрешении 4k.

Общий размер сжатого архива (package) с мешем в режиме Nanite и его текстурами, составляет: 27.83MB

Существует множество экспериментов, которые можно провести с разрешением текстур и детализированными картами нормалей, но это конкретное сравнение должно продемонстрировать, что размеры данных Nanite мешей не слишком отличаются от данных, с которыми художники уже знакомы.

Наконец, мы можем сравнить компрессию Nanite со стандартным форматом Static Mesh, используя высоко-полигональные меши, идентичные на уровне LOD0.

Ассет использующий сжатие Nanite (с размером 19,64 МБ) в 7,6 раза меньше, чем ассет использующий стандартное сжатие Static Mesh с 4 LOD'ами.

ПРИМЕЧАНИЕ: Сжатие Nanite и размер данных — это ключевая область, которая будет улучшена в последующих версиях Unreal Engine.

Общие советы по размеру данных и взгляд в будущее

Системы Nanite и Virtual Texturing в сочетании с быстрыми SSD уменьшили беспокойство по поводу бюджета времени выполнения (runtime budgets) для геометрии и текстур. Сейчас самая большая проблема — это как доставить эти данные конечному пользователю.

Размер данных на диске — является важным фактором при рассмотрении способов распространения контента — на физических носителях или посредством загрузки через Интернет — а технология сжатия может не так много. Средняя пропускная способность интернета у конечного пользователя, размеры оптических носителей и размеры жёстких дисков не масштабируются с той же интенсивностью, что и пропускная способность жесткого диска и задержка доступа, вычислительная мощность GPU и программные технологии, такие как Nanite. По этому, передача этих данных конечным пользователям оказывается сложной задачей.

Эффективный рендеринг высоко-детализированных мешей — это меньшая проблема для Nanite, в то время как хранение всех его данных на диске, теперь является ключевой областью, которую необходимо контролировать. Помимо сжатия, в будущих релизах Unreal Engine должны появиться инструменты для поддержки более агрессивного повторного использования повторяющихся деталей, а также инструменты, позволяющие обрезать данные на поздних этапах производства, чтобы привести размер пакета в соответствие, позволяя искусству безопасно выходить за пределы своей шкалы качества, а не недооценивать ее.

Что касается будущего развития системы Nanite, можно провести множество параллелей с тем, как управлять данными текстуры, для создания которых потребовалось несколько десятилетий отраслевого опыта, например:

  • Тайлинг текстур
  • Наложение UV (UV stacking) и зеркалирование
  • Текстуры Детализации
  • Отчёты по текстурной памяти
  • Снижение MIP уровней для окончательно упакованных данных

Подобные стратегии исследуются и разрабатываются для геометрии в Unreal Engine 5.

Режимы визуализации

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

В основном вьюпорте откройте выпадающее меню View Modes, перейдите в Nanite Visualization и выберите нужный вариант.

Например, режим визуализации Overview показывает визуализируемую сцену по центру экрана, и отдельные режимы визуализациии вокруг него в качестве вспомогательных источников информации.

Помимо этого доступны следующие режимы визуализации:

Консольные команды и переменные

Для отладки и конфигурирования системы Nanite можно использовать следующие консольные переменные и статистические данные:

Вы можете включить или выключить рендеринг Nanite, прямо во время исполнения, используя консольную переменную r.Nanite 0. Отключение Nanite — это хороший способ эмулировать платформу, на которой Nanite не поддерживается.

Режимы визуализации прокси мешей

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

  • 0 это стандартный режим и если он выбран, выполняется рендеринг прокси-мешей или LOD'ов управляемых в экранном пространстве. Он включает в себя распознавание Min LOD в свойствах Static Mesh Editor (описано в разделе Proxy Mesh выше).
  • 1 отключает рендеринг мешей работающих в режиме Nanite.
  • 2 работает подобно режиму 1, но позволяет активировать режим визуализации Show → Nanite Proxy в Static Mesh Editor чтобы отрендерить Nanite прокси.

Режимы визулизации прокси мешей 1 и 2 полезны для сцен, которые имеют гораздо больше число экземпляров, чем могло бы нормально поддерживаться без использования системы Nanite, позволяя открывать сцену в редакторе на платформах, не поддерживающих Nanite. Например, в демонстрационном проекте Unreal Engine 5 «Valley of the Ancients» отключение системы Nanite привело бы к появлению десятков тысяч регулярных вызовов отрисовки, что само-собой значительно затруднило даже обычное открытие карты на не поддерживаемой платформе.

Команды для вывода статистики

При вводе в консоль команды Nanitestats, в правой части экрана появляется статистика по отсечению геометрии.

Аргументы используются для того чтобы определить какую именно статистику по работе Nanite выводить на экран. Когда аргумент отсутствует, используется основной вид.

Nanitestats List выводит список доступных представлений:

  • Primary
  • VSM_Directional
  • VSM_Perspective
  • ShadowAtlas0
  • ShadowAtlas1
  • ShadowAtlas2

Чтобы выбрать определенный вид, введите команду Nanitestats и аргумент который вы хотите использовать. Например, Nanitestats VSM_Directional.

Для видов (или представлений), которые используют двух-проходную отбраковку на основе окклюзии, статистика разбивается на отдельные сегменты для проходов Main и Post.

Управление размером пула потоковой передачи данных

Управление объемом памяти, выделенным для хранения потоковых данных (streaming data ) Nanite осуществляется с помощью консольной переменной r.Nanite.Streaming.StreamingPoolSize. Использование более крупных пулов сокращает количество операций ввода-вывода (IO) и декомпрессии при перемещении по сцене, но происходит это за счёт увеличения потребляемого объема памяти.

В случае с Early Access, если размер пула недостаточно большой чтобы вместить все данные, необходимые для изображения (view), может произойти перегрузка/пробуксовка кэша там, где потоковая передача никогда не останавливается даже для неподвижного изображения.

ПРИМЕЧАНИЕ: Данную консольную переменную нельзя изменить в процессе выполнения. Её необходимо определять в конфигурационном файле (.ini).

Настройка максимального количества кластеров

Вы можете указать максимальное количество кандидатов и видимых кластеров используемых за один проход, с помощью консольных переменных r.Nanite.MaxCandidateClusters и r.Nanite.MaxVisibleClusters. Их значения используются для определения размеров промежуточных буферов, а их значения по умолчанию (8388608 и 2097152 соответственно) были выбраны для работы в распространенных сценариях рендеринга игр.

В Early Access нет механизма для динамического изменения размера этих буферов, или автоматического понижения качества при их переполнении.

Это может привести к тому, что артефакты рендеринга будут слишком малы из-за сложности сцены и обычно проявляются как отсутствующая или мигающая геометрия. Когда возникают подобные артефакты, используйте Nanitestats для определения консервативных границ (conservative bounds) для кандидатов и видимых кластеров (посмотрите статистику для CLUSTERSSW и CLUSTERSHW). Если говорить о занимаемой памяти, то в настоящее время, размер кластера-кандидата (candidate cluster) составляет 12 байт, а размер видимого кластера - 16 байт.

ПРИМЕЧАНИЕ: Данную консольную переменную нельзя изменить в процессе выполнения. Её необходимо определять в конфигурационном файле (.ini).

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

Ссылка на оригинал статьи:

{ "author_name": "Empty Node", "author_type": "self", "tags": ["unrealengine5","unrealengine4","unrealengine","ue5","ue4","naniteue5","nanite"], "comments": 12, "likes": 72, "favorites": 97, "is_advertisement": false, "subsite_label": "gamedev", "id": 776190, "is_wide": true, "is_ugc": true, "date": "Fri, 25 Jun 2021 15:24:31 +0300", "is_special": false }
(function (w, d, css, imgs) { var teaser = d.querySelector('.' + css.root); var isFeed = d.querySelector('[air-module="module.feed"]'); if (teaser) { teaser.classList.add(css.sitename); if (isFeed) { teaser.classList.add(css.index); } else { teaser.classList.add(css.entry); } loadImages(imgs).then(function () { teaser.classList.add(css.loaded); }); } function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = d.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); }; }(window, document, { root: 'pixonic-banner', index: 'pixonic-banner--index', entry: 'pixonic-banner--entry', loaded: 'pixonic-banner--loaded', sitename: 'pixonic-banner--' + (window.__codename || 'vc') }, [ 'https://leonardo.osnova.io/f78d51cb-71d0-5ce2-90de-b2c88340b6b6/', ]));
0
12 комментариев
Популярные
По порядку
Написать комментарий...

Комментарий удален

2

А вот бы им взять и сравнить скорость и качество сцены из их-же ПРОШЛОГО движка.
Ну что-то взять, сделанное на анриале4, и показать эту же сцену на анриале5.
Сразу бы стало видно а) качество, как портится картинка этим нанитом, и б) какой прирост скорости он даёт, и даёт ли вообще.

А у них камни коричневые на коричневой земле.
А почему так?
А потому что на них слабо увидишь дефекты изменения геометрии.

Вот на статуе из того скриншота - сразу видно. Поганится геометрия. Игрок это обязательно увидит.
Короче, очередное изобретение ЛОДов. Ждите теперь в их проектах скачущую геометрию как только вы шевельнёте камерой.

Ответить
3

А вот бы им взять и сравнить скорость

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

Видно что? На скрине Прокси  Меш — грубое представление модели которое игрок в игре не видит и которое необходимо для  работы системы освещения и рассчета коллизий.

Ответить
0

и делать это надо на релизной версии UE5

Ну это к ним вопрос. Они ж начали хвастать и показывать уже сейчас.

грубое представление модели которое игрок в игре не видит

Надо показать, как игрок увидит.
Это же центральная система всей этой штуки: как именно понижается детализация. Насколько будет ощутима потеря полигонов.
И показывать это надо не на коричневых склонах, которые можно вообще плоским мешем делать. А на вот подобной скульптуре, где каждое искажение будет заметно.

Я думаю что чуда не будет и лоды будут, как и прежде, ощутимо некрасивее оригинала.

Ответить
2

+ нанинитв - это а своей сути Динамические лоды - ближняя часть объекта будет более детализированной чем дальняя - раньше так тоже кстати делали - но только с ландшафтами. 

Ответить
0

Звучит неплохо но надо смотреть.
Не просто так этого не делали раньше.

Например, будет ли заметен шов внутри объекта если его части показывают разные лоды. Или например не будет ли затрат ресурсов больше, чем профита. Я там уже в тексте увидел рассчёт на 60 фпс, например, а также требование ссд. Классическим лодам ссд не требовался, почему-то. Ну как так?

Ответить
0

Шва не должно быть видно при ультра настройках ибо в таком случае - НАниты работают по принципу : 1 пиксель экрана=1полигон

Ответить
1

Наниты - это по сути следующая итерация автоматических лодов чье переключени может просиходить на лету, тем самым переключения лодов "по шелчку" не будет происходить

Ответить

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

1

Автор, у тебя один абзац дублирует перевод
 The second optimization that aggregates break is occlusion culling....

Ответить
1

Монументальный труд, спасибо

Ответить
0

simple geometry

Ответить
0

качество картинки улучшилось, но простота её создания нет, блэт

Ответить
Читать все 12 комментариев
null