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

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

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

Геометрия - это причудливый способ обозначения формы. В компьютерной графике геометрия обычно представлена массивом позиций, называемых "вершинами". В Godot геометрия представлена сетками (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. MultiMeshInstances draw meshes thousands of times very cheaply by taking advantage of hardware instancing. The drawback with using a MultiMeshInstance is that each of your mesh's surfaces 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 of each surface use the same material.

What a Mesh is

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

Поверхности

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

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

The surface array is an array of length ArrayMesh.ARRAY_MAX. Each position in the array is filled with a sub-array containing per-vertex information. For example, the array located at ArrayMesh.ARRAY_NORMAL is a PoolVector3Array of vertex normals. See Mesh.ArrayType for more information.

The surface array can be indexed or non-indexed. Creating a non-indexed array is as easy as not assigning an array at the index ArrayMesh.ARRAY_INDEX. A non-indexed array stores unique vertex information for every triangle, meaning that when two triangles share a vertex, the vertex is duplicated in the array. An indexed surface array only stores vertex information for each unique vertex and then also stores an array of indices which maps out how to construct the triangles from the vertex array. In general, using an indexed array is faster, but it means you have to share vertex data between triangles, which is not always desired (e.g. when you want per-face normals).

Инструменты

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

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

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, while the SurfaceTool generates a Mesh that needs to be added to a MeshInstance to be seen.

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

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

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

Which approach you use depends on what you are trying to do and what kind of procedure you are comfortable with.

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

Using an ArrayMesh is slightly faster than using a SurfaceTool, but the API is a little more challenging. Additionally, SurfaceTool has a few quality of life methods such as generate_normals() and index().

ImmediateGeometry regenerates the mesh every frame, so it is much slower than ArrayMesh or SurfaceTool. However, if you need the geometry to change every frame anyway, it provides a much easier interface that may even be a little faster than generating an ArrayMesh every frame.

The MeshDataTool is not fast, but it gives you access to all kinds of properties of the mesh that you don't get with the others (edges, faces, etc.). It is incredibly useful when you need that sort of data to transform the mesh, but it is not a good idea to use it if that extra information is not needed. The MeshDataTool is best used if you are going to be using an algorithm that requires access to the face or edge array.