Не так давно мы изготовили систему создания лун. Наша цель заключалась в создании лун, похожих по размеру и составу на существующие в нашей Солнечной системе. Основной сложностью оказалось получение обширных поверхностей таких лун и их внутренностей, чтобы при этом они оставались интересными. Кроме того, нам нужно было, чтобы луны рендерились с чёткими деталями вне зависимости от расстояния до них.
Система предполагает, что луны имеют сферическую основу. К базовой сфере применяется создание геодезического меша, что гарантирует одинаковую площадь всех частей поверхности. Система применяет эту структуру только как вычислительную сетку для процедурной генерации, настоящая поверхность луны будет намного более гладкой, чем сетка генерации.
Геодезическая сфера
Чтобы получить небольшие неровные луны, базовые геометрические формы искажаются низкочастотным 3D-шумом.
Искажённая шумом геодезическая сфера
Начав с этой основы, система использует серию концентрических оболочек. Каждая ячейка определяет объёмные характеристики последующей концентрической оболочки. Самая внешняя оболочка задаёт свойства поверхности луны.
Концентрические оболочки
Каждая оболочка может быть искажена низкочастотным 3D-шумом, уникальным для этой оболочки. Если выбрать такую опцию генерации, то внутренняя оболочка сможет даже оказаться больше внешней.
Искажение оболочек
На показанных выше схемах расстояние между оболочками и величина искажения преувеличены, чтобы более наглядно показать процесс построения. На практике оболочки будут гораздо ближе друг к другу, и величина их искажения окажется пропорционально меньшей.
Ниже мы расскажем о том, как создаётся самая внешняя оболочка. Те же принципы применяются при создании внутренних оболочек, поэтому подробно их рассматривать мы не будем.
Для системы процедурных лун требуется компонент реального времени и офлайн-компонент. Компонент реального времени выполняется на компьютере игрока. Офлайн-компонент выполняется на компьютерах разработчиков игры. Офлайн-компонент генерации создаёт информацию, которую можно быстро дополнить компонентом реального времени.
Каждая вершина в сферической оболочке классифицируется как принадлежащая к одному отдельному биому. Биом — это набор свойств поверхности, в том числе: высота, распределение материалов, размещение экземпляров и окраска материалов.
Пример биома
Информация биома содержит насыщенные энтропией свойства, например, кратеры, сухие моря, поверхностные трещины, вызванные гравитационными приливами.
Большой кратер, записанный в информацию биома
В определении биома также содержатся правила размещения объектов, определяющие расположение, частоту и рандомизацию мелких частей — камней, булыжников, выступов и т.п.
Экземпляры камней на рельефе
Каждый биом создаётся из располагаемых плитками (тайлами) элементов, чтобы компонент реального времени мог применять одинаковую информацию на разных участках луны, а также на других лунах. Информация биомов должна генерироваться таким образом, чтобы были возможны быстрое искажение и перекомпоновка, благодаря чему можно снизить количество повторяющихся и предсказуемых паттернов окружения.
Система использует два типа тайлов биомов: переходные и изолированные.
Переходная информация биомов возникает в областях, где биом переходит в соседний биом. Изолированная информация биомов возникает в областях, где система гарантирует отсутствие соседних биомов.
Эти два отдельных режима необходимы, потому что некоторые элементы биомов, например, кратеры, могут размещаться только в областях, где биом не переходит в другой биом, потому что переходы между биомами могут влиять на профиль высоты и внешний вид элементов рельефа.
Ниже показан упрощённый пример луны, в которой используются три различных биома: полярный, тропический и экваториальный, окрашенные, соответственно, в красный, синий и зелёный цвета.
Луна с тремя биомами
Участки с изолированным биомом имеют однородную окраску, на участках с переходными биомами цвета смешиваются.
Система использует набор заранее вычисленных шумов для внесения вариативности в зоны переходов между биомами, создавая интересные, уникальные переходы от одного биома к другому.
Процедурный шум, применённый к переходам между биомами
На изображениях выше размер каждого участка биома преувеличен относительно размера луны, чтобы более наглядно показать технику создания биомов. Отдельный участок биома будет покрывать площадь примерно 10 на 10 км. Луна радиусом 1 500 км будет иметь площадь поверхности 30 000 000 км2. Для покрытия этой поверхности понадобилось бы почти 300 000 таких участков.
Разрешение сетки биомов для луны радиусом 1 500 км
Разрешение сетки биомов может привести к очень большому количеству участков биомов. Система не будет отслеживать каждый из них по отдельности, потому что размещение каждого участка может быть аналитически вычислено. А биом для большинства участков можно назначить из высокоуровневой карты биомов.
Высокоуровневые карты биомов определяют ключевые характеристики лун при взгляде с большого отдаления. Система использует эти карты для генерации дополнительных деталей в более близких видах, сохраняя однообразие определения луны при обзоре с разных расстояний.
Высокоуровневые карты биомов — это 2D-изображения которые можно при помощи 2D-параметризации разместить на поверхности луны. Каждая точка карты содержит числовой идентификатор биома, преобладающего в соответствующей локации поверхности или внутренней оболочки.
2D-карта биомов
На изображении выше показана карта с четырьмя различными типами биомов (синий, красный, жёлтый и белый). Изображение наложено на сферу при помощи 2D-параметризации. Одна из возможных параметризаций показана ниже:
2D-параметризация для карты идентификаторов биомов
Кроме карты идентификаторов биомов система позволяет использовать и другие карты, например, содержащие высоты и цвет поверхности.
Высота, оттенок и рендеринг луны на дальнем расстоянии
Один пиксель на каждом изображении может покрывать 4 км2, благодаря чему их создание малозатратно. Такие карты высот и оттенков могут генерироваться процедурно или рисоваться художниками. В проекте, в котором используется всего дюжина лун и где каждая луна должна иметь богатые и уникальные природные свойства, на этом этапе лучше всего применить труд художников.
На изображении ниже показан процесс генерации высоты поверхности оболочки и других свойств:
Три масштаба, использованные для построения луны
Луна будет состоять как минимум из одной сферической оболочки. Если оболочек несколько, то система экструдирует внутренние оболочки на основании их максимального радиуса и функции высоты оболочки, которая получается при выполнении процесса с разными масштабами, описанного выше.
Для каждой оболочки дизайнер лун создаёт высокоуровневую карту распределения биомов, определения биомов для встречающихся на этой карте биомов и определения встречающихся в этом биоме материалов.
Система считает «воздух» допустимым материалом, поэтому его можно использовать для создания полостей в любой оболочке.
Поперечное сечение рельефа луны, на котором видны различные оболочки
Отдельная оболочка также может быть объёмным объектом, глубина которого задаётся стеком материалов. Информация стека материалов хранится в биоме.
Стек материалов, составленный из шести материалов
Так как подземные материалы редко выходят на поверхность их можно описать с гораздо меньшим разрешением, чем материалы поверхности биомов, а использование локальных процедурных шумов останется для игрока незаметным.
Функциональности стека материалов может оказаться достаточно для расположения, потому что некоторые материалы в стеке могут быть довольно редкими. Дизайнер биомов может настраивать распространённость и паттерн появления любого материала в стеке.
Процедурная генерация выполняется шейдерами GPU и воксельными алгоритмами ЦП.
Шейдер вычисляет цвет фрагмента для каждого из трёх масштабов и смешивает эти сэмплы в зависимости от расстояния между камерой и фрагментом.
Все детали, которые слишком малы, чтобы регистрироваться в геометрии. но всё же влияющие на воспринимаемую сложность поверхностей, записываются в карты нормалей, генерируемые в реальном времени на основе процедурного определения материалов, биомов или высокоуровневых карт определения луны. Благодаря этому в сцене поддерживается низкое количество полигонов.
За это приходится расплачиваться тем, что пока луна видна в камере, биом и высокоуровневые карты определений должны храниться в GPU. Можно использовать выборочную загрузку только тех mip-текстур, которые необходимы для рендеринга текущего масштаба луны. Общее количество требуемой памяти GPU снижается до минимума благодаря потоковой загрузке и выгрузке из GPU при изменении позиции наблюдателя.
Когда из-за близости к камере отдельные элементы становятся достаточно большими, они начинают отображаться в выходных данных геометрии при помощи генерации вокселей в реальном времени. То же самое относится ко всем частям луны, терраформированным или вырытым игроками. Если изменения достаточно велики и их можно наблюдать с орбиты, адаптивный менеджер сцен Voxel Farm увеличивает уровень детализации (LOD) всех областей, изменение которых приложение сочтёт важным.