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

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

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

Geometry is a fancy way of saying shape. In computer graphics, geometry is typically represented by an array of positions called "vertices". In Godot, geometry is represented by Meshes.

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

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

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

If you are going to draw the same object many times, it can be helpful to use a MultiMesh with a MultiMeshInstance. The MultiMeshInstance draws meshes thousands of times very cheaply. It takes advantage of hardware instancing in order to do so. The drawback with using a MultiMeshInstance is that you are limited to one material for all instances. It uses an instance array to store different colors and transformations for each instance, but all the instances use the same material.

What a Mesh is

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

Surfaces

Each surface has its own material. Alternatively, you can override the material for all surfaces in the Mesh when you use a MeshInstance using MeshInstance.override_material.

Surface array

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

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

Инструменты

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

ArrayMesh

The ArrayMesh resource extends Mesh to add a few different quality of life functions, and most importantly, the ability to construct a Mesh surface through scripting.

For more information about the ArrayMesh, please see the ArrayMesh tutorial.

MeshDataTool

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

For more information about the MeshDataTool, please see the MeshDataTool tutorial.

SurfaceTool

The SurfaceTool allows the creation of Meshes using an OpenGL 1.x immediate mode style interface.

For more information about the SurfaceTool, please see the SurfaceTool tutorial.

ImmediateGeometry

ImmediateGeometry is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The difference between ImmediateGeometry and the SurfaceTool is that ImmediateGeometry is a node itself that can be added to the scene tree and is drawn directly from the code. The SurfaceTool generates a Mesh that needs to be added a MeshInstance to be seen.

ImmediateGeometry is useful for prototyping because of the straightforward API, but it is slow because the geometry is rebuilt every frame. It is most useful for quickly adding simple geometry to debug visually (e.g. by drawing lines to visualize physics raycasts etc.).

For more information about ImmediateGeometry, please see the ImmediateGeometry tutorial.

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

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

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

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

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

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