Что такое уровни детализации (LOD) в играх и как с ними работать
Разбираем одну из самых популярных техник оптимизации 3D-графики.
Иллюстрация: Катя Павловская для Skillbox Media
Структура внутриигровых миров стала достаточно сложной и масштабной. И чтобы обеспечить плавный игровой процесс и снизить нагрузку на аппаратное обеспечение, разработчики ищут компромисс между привлекательной визуальной составляющей и производительностью. Поддерживать этот баланс помогают уровни детализации.
Что такое уровни детализации
Уровни детализации, или LOD, — это метод программирования 3D-графики, при котором детализация 3D-модели изменяется в зависимости от расстояния между героем (или внутриигровой камерой) и объектом. Иными словами, чем дальше от героя находится объект, тем проще его структура: количество полигонов уменьшается, а разрешение текстур становится ниже. Этот подход позволяет решить сразу несколько задач.
- Снижение нагрузки на видеокарту. Во время процесса рендеринга компьютерной графики задействован графический процессор. Когда уровень детализации снижается, процесс растеризации, в частности этап шейдеров вершин, происходит быстрее, что положительно влияет на итоговую производительность.
- Снижение нагрузки на центральный процессор. Чем проще геометрия в сцене — тем меньше дроуколлов, что также упрощает процесс рендеринга.
- Устранение визуальных дефектов. Края высокополигональных объектов с большого расстояния могут выглядеть слишком зазубренными. Это связано с тем, что они занимают очень мало экранного пространства и графический процессор не может корректно отобразить участок с высокой плотностью полигонов.
Уровни детализации в 3D-графике смотрятся довольно органично, ведь в реальной жизни человек тоже не может рассмотреть детали каждого объекта с большого расстояния. Например, издалека поле кажется нам плоским зелёным ковром. А если мы будем стоять рядом с ним, мы сможем рассмотреть все растения.
Сама концепция уровней детализации зародилась ещё в середине 1970-х годов прошлого века и впервые упомянута в работе Джеймса Кларка — будущего основателя Silicon Graphics. Кларк понимал, что объекты, занимающие на экране всего несколько точек, не требуют больших ресурсов при отрисовке. В его исследовании представлено несколько схем, где условно обозначена иерархия объектов по мере отдаления от камеры. К слову, в этой работе также упоминается и концепция отсечения геометрии за пределами зоны видимости камеры (Frustum Culling), которая наравне с Occlusion Culling в настоящее время считается одним из главных методов оптимизации 3D-графики.
Впервые уровни детализации начали применять в играх с открытыми пространствами, что характерно для авиасимуляторов (Flight Simulator 2). Поначалу их рисовали вручную художники. Но уже к началу 1990-х появились такие алгоритмы, как сокращение триангулярных мешей и упрощение моделей путём кластеризации вершин, которые автоматически уменьшали детализацию отдалённых объектов, сохраняя при этом их считываемость.
В настоящее время применение уровней детализации стало стандартом индустрии. Сейчас они встречаются практически в каждой игре и неигровом приложении с 3D-графикой, особенно если мир подразумевает наличие открытых пространств.
Как работают уровни детализации
Существует несколько подходов управления уровнями детализации.
Дискретные уровни детализации (DLOD). Для исходного объекта заранее создаётся несколько вариаций моделей с меньшим количеством полигонов. Когда герой или внутриигровая камера отдаляется от объекта, оригинальная модель заменяется на менее детализированный клон.
Порой в играх встречаются моменты, когда персонаж быстро подбегает к объекту, а тот на долю секунды остаётся размытым и низкополигональным. Разработчики стараются сводить такие нежелательные эффекты к минимуму, создавая плавные переходы из одного LOD в другой. Например, в Unity для этого можно использовать опцию Fade Mode. Что касается крупных объектов (дома и другие масштабные постройки), то единственный приемлемый вариант при этом подходе — подразделять их на несколько элементов.
Непрерывные уровни детализации (CLOD). Формируется структура данных, на основе которой уровни детализации объекта подстраиваются под конкретную ситуацию, а не подбираются из предварительно созданных вариантов, как в методе выше. Иными словами, детализация меняется локально. Например, часть объекта рядом с персонажем может быть высокой детализации, а другая часть — низкой.
Таким образом, при непрерывных уровнях детализации в объектах не будет избыточного количества полигонов, что способствует лучшей оптимизации ресурсов.
Иерархические уровни детализации (HLOD). При этом методе из нескольких вариаций меша создаётся простой промежуточный меш со сгенерированными текстурами в виде атласа. Данный вариант отображается на больших расстояниях от внутриигровой камеры. Когда дистанция сокращается, подгружается более детализированный объект. Такой подход значительно упрощает рендеринг, особенно в масштабных динамических сценах. Эти уровни детализации появились ещё в четвёртой итерации Unreal Engine (активируются в отдельном порядке), но сейчас можно добавить их и в Unity.
Как сделать уровни детализации
Процесс создания уровней детализации во многом зависит от выбранного движка, концепции и общей значимости ассета. В любом случае каждому LOD присваивается порядковый номер, начиная с нуля.
Например, оригинальной модели с самым высоким уровнем детализации (условно в несколько десятков тысяч полигонов и с текстурами разрешением в 4K) присваивается уровень LOD 0, менее детализированной — LOD 1 и так далее. Итоговый набор называют группой уровней детализации, или LOD Group. В движках можно создавать довольно большие группы, но, как правило, для игр вполне достаточно 3–4 вариаций LOD — 0, 1, 2 или 0, 1, 2, 3 соответственно.
Уровни детализации можно создать вручную или сгенерировать автоматически.
Ручной метод предполагает подготовку нескольких версий одной и той же 3D-модели с разными уровнями детализации в программе для 3D-моделирования. Сначала в редакторе дублируют исходный меш столько раз, сколько заявлено уровней детализации. Оригинальную модель оставляют как есть (она станет LOD 0), а вот в дубликатах количество полигонов сокращают в соответствии с их уровнем детализации (чем больше значение, тем меньше детализация). Главное — помнить, что полигонаж объектов LOD-группы должен понижаться равномерно. В противном случае в игре может возникнуть ситуация, когда при минимальном отдалении проработанный меш внезапно станет низкополигональным, что сразу заметит игрок. Универсальный вариант — сокращать полигонаж каждого следующего уровня детализации примерно в два раза.
Существует много способов получения низкополигональных вариантов моделей. Можно убирать лишние вершины и рёбра вручную в режиме редактирования (но следить за сохранением рёбер, относящихся к швам UV-островов), а можно воспользоваться специальными инструментами для оптимизации геометрии.
Например, в Blender для создания LOD чаще всего прибегают к модификатору «Упрощение» (Decimate). Он помогает сократить количество полигонов при минимальных искажениях структуры меша — правда, в некоторых случаях всё равно потребуется ручная коррекция для придания объекту более плавных очертаний, особенно если необходимо сделать уровни детализации для персонажа.
Во избежание появления различных дефектов в виде швов на текстурах после упрощения геометрии, при подготовке UV-развёртки стоит учитывать специфику MIP-мэппинга. Современные движки уменьшают разрешение текстур автоматически. Также во время упрощения геометрии возможны искажения структуры UV-островов, поэтому рекомендуется отслеживать состояние UV-развёртки на протяжении всего процесса.
Автоматическая настройка подразумевает генерацию LOD с помощью различных аддонов или плагинов для приложений и движков — например, Simplygon, InstaLOD, UnityMeshSimplifier, LODs Maker и других. Большинство из этих инструментов платные, но именно такой способ обычно выбирают студии, чтобы сэкономить время на стадии подготовки контента.
Некоторые специализированные приложения тоже поддерживают автоматическую генерацию уровней детализации. Например, в программе для создания деревьев и растений SpeedTree доступна автоматическая настройка LOD, которую можно подключить в параметре Dynamic LOD.
Другой пример: известный генератор моделей людей MetaHuman Creator от Epic Games не только поддерживает большое количество уровней детализации (от LOD 0 до LOD 7), но и обеспечивает синхронизацию компонентов модели.
Большинство готовых ассетов на маркетплейсах по умолчанию содержит уровни детализации (автор указывает их наличие в описании лота).
Настройка уровней детализации в игровых движках
Рассмотрим, как происходит настройка уровней детализации на примере известных игровых движков.
Unity
В Unity существует два способа создания уровней детализации для объекта. В первом случае необходимые уровни детализации объекта заранее подготавливают в стороннем приложении для 3D-моделирования, как описано выше. Если придерживаться определённых правил при экспорте и наименовании мешей, то при загрузке моделей в движок Unity автоматически распознает данные и настроит группы уровней детализации.
Другой способ — создать объект GameObject с компонентом LOD Group и настроить уровни детализации вручную.
Для Unity также существует множество платных плагинов, например Ultimate LOD System MT или Poly Few, которые позволяют сгенерировать уровни детализации в реальном времени.
Unreal Engine
И в четвёртой, и в пятой итерации Unreal Engine существует автоматическая система генерации LOD для статических мешей. Её можно настроить в редакторе статических мешей Static Mesh Editor, открыв на панели Details раздел LOD Settings. Далее — развернуть вкладку LOD Groups и выбрать желаемый шаблон уровня детализации. Например, HighDetail генерирует больше трёх уровней детализации, обеспечивая более плавный переход от высокой детализации до самой низкой. Шаблон SmallProp придерживается более стандартного подхода. Больше об автоматической системе генерации можно узнать из официальной документации.
Если у вас есть уже готовый набор уровней детализации, его также можно загрузить в движок и настроить в LOD Settings вручную. Как и в случае с Unity, необходимо учитывать несколько нюансов во время создания вариаций мешей и при импорте.
Unigine
Unigine поддерживает автоматическую генерацию уровней детализации. При настройке необходимо самостоятельно выбрать количество уровней, процент исходного количества полигонов от оригинального меша, а также расстояние. Также в движке можно объединить заранее подготовленные уровни детализации с помощью функции Combine by Postfixes при условии, что в стороннем ПО для 3D-моделирования названиям вариаций мешей присвоен соответствующий постфикс LOD.
Ручная настройка — ещё один способ создания уровней детализации в Unigine. Вариации меша создают в стороннем ПО, импортируют в движок с опцией Merge Static Meshes, а затем создают так называемые поверхности LOD для каждого элемента по отдельности.
Итог
Уровни детализации помогают поддерживать баланс между эффектной картинкой и оптимальной производительностью. И хотя в перспективе их могут заменить такие инновационные технологии, как Nanite, создание LOD всё ещё актуально в сфере разработки игр и проектов с 3D-графикой.
Если вы планируете развиваться в этом направлении, вам придётся освоить принципы работы с уровнями детализации. Даже если в будущем проекте не будет масштабного открытого мира, в котором одновременно отображаются сотни объектов, наличие LOD заметно улучшит производительность, а значит, поможет расширить аудиторию, которая сможет насладиться игрой даже на менее мощных системах.