Процедурная геометрия

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

Что такое геометрия?

Геометрия - это причудливый способ обозначения формы. В компьютерной графике геометрия обычно представлена массивом позиций, называемых "вершинами". В Godot геометрия представлена сетками (Meshes).

Что такое меш?

Многие вещи в Godot имеют название mesh: Mesh, ArrayMesh, MeshInstance, MultiMesh, и MultiMeshInstance. Хотя все они связаны между собой, их использование несколько отличается.

Meshes и ArrayMeshes - это ресурсы, которые рисуются с помощью узла MeshInstance. Такие ресурсы, как Meshes и ArrayMeshes, не могут быть добавлены в сцену напрямую. MeshInstance представляет один экземпляр сетки в вашей сцене. Вы можете повторно использовать одну сетку в нескольких MeshInstance, чтобы рисовать ее в разных частях сцены с разными материалами или преобразованиями (масштаб, поворот, положение и т.д.).

Если вы собираетесь рисовать один и тот же объект много раз, может быть полезно использовать MultiMesh с MultiMeshInstance. MultiMeshInstances очень дешево рисует сетки тысячи раз, используя преимущества аппаратного создания экземпляров. Недостатком использования MultiMeshInstance является то, что каждая из поверхностей вашей сетки ограничена одним материалом для всех экземпляров. Он использует массив экземпляров для хранения разных цветов и преобразований для каждого экземпляра, но все экземпляры каждой поверхности используют один и тот же материал.

Что такое Сетка

Сетка состоит из одной или нескольких поверхностей. Поверхность - это массив, состоящий из нескольких подмассивов, содержащих вершины, нормали, UV и т.д. Обычно процесс построения поверхностей и сеток скрыт от пользователя в VisualServer, но с помощью ArrayMeshes пользователь может построить сетку вручную, передав массив, содержащий информацию о поверхности.

Поверхности

Каждая поверхность имеет свой собственный материал. В качестве альтернативы, вы можете переопределить материал для всех поверхностей в Mesh при использовании MeshInstance с помощью свойства material_override.

Массив поверхности

Массив поверхности представляет собой массив длины ArrayMesh.ARRAY_MAX. Каждая позиция в массиве заполняется подмассивом, содержащим информацию о каждой вершине. Например, массив, расположенный по адресу ArrayMesh.ARRAY_NORMAL является PoolVector3Array нормалей вершин. Дополнительную информацию смотрите в Mesh.ArrayType.

Массив поверхности может быть индексированным или неиндексированным. Создать неиндексированный массив так же просто, как не назначать массив по индексу ArrayMesh.ARRAY_INDEX. Неиндексированный массив хранит уникальную информацию о вершине для каждого треугольника, что означает, что когда два треугольника имеют общую вершину, эта вершина дублируется в массиве. Индексированный массив поверхностей хранит информацию о вершинах только для каждой уникальной вершины, а затем также хранит массив индексов, которые указывают, как построить треугольники из массива вершин. В целом, использование индексированного массива быстрее, но это означает, что вам придётся обмениваться вершинными данными между треугольниками, что не всегда желательно (например, когда вам нужны нормали для каждой грани).

Инструменты

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

ArrayMеsh

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

Для получения дополнительной информации об ArrayMesh, пожалуйста, смотрите ArrayMesh tutorial.

Инструмент "Данные Меша"

MeshDataTool - это ресурс, преобразующий данные Mesh в массивы вершин, граней и ребер, которые могут быть изменены во время выполнения.

Более подробную информацию о MeshDataTool можно найти в MeshDataTool tutorial.

SurfaceTool (Инструмент поверхности)

Инструмент SurfaceTool позволяет создавать сетки, используя интерфейс OpenGL 1.x в стиле немедленного режима.

Для получения дополнительной информации о SurfaceTool, пожалуйста, обратитесь к SurfaceTool tutorial.

ImmediateGeometry ( Немедленная геометрия )

ImmediateGeometry - это узел, который использует интерфейс стиля немедленного режима (как SurfaceTool) для рисования объектов. Разница между ImmediateGeometry и SurfaceTool в том, что ImmediateGeometry - это узел, который может быть добавлен в дерево сцены и рисуется непосредственно из кода, а SurfaceTool генерирует Mesh, который должен быть добавлен в MeshInstance, чтобы его можно было увидеть.

ImmediateGeometry полезен для создания прототипов благодаря своему простому API, но он медленный, поскольку геометрия перестраивается каждый кадр. Он наиболее полезен для добавления простой геометрии для визуальной отладки (например, рисование линий для визуализации физических лучей и т.д.).

Более подробную информацию о ImmediateGeometry можно найти в ImmediateGeometry tutorial.

Какой из них мне следует использовать?

Какой подход вы используете, зависит от того, что вы пытаетесь сделать и какой вид процедуры вам удобен.

И SurfaceTool, и ArrayMesh отлично подходят для создания статической геометрии (сетки), которая не меняется со временем.

Использование ArrayMesh немного быстрее, чем использование SurfaceTool, но API немного сложнее. Кроме того, SurfaceTool имеет несколько методов качества жизни, таких как generate_normals() и index().

ImmediateGeometry регенерирует сетку каждый кадр, поэтому он работает намного медленнее, чем ArrayMesh или SurfaceTool. Однако, если вам нужно, чтобы геометрия менялась каждый кадр в любом случае, этот инструмент предоставляет гораздо более простой интерфейс, который может быть даже немного быстрее, чем генерация ArrayMesh каждый кадр.

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