Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Использование ImmediateMesh
ImmediateMesh — удобный инструмент для создания динамической геометрии с использованием API в стиле OpenGL 1.x. Что делает его доступным в использовании и эффективным для сеток, которые необходимо обновлять в каждом кадре.
Генерация сложной геометрии (несколько тысяч вершин) с помощью этого инструмента неэффективна, даже если выполняется только один раз. Вместо этого он предназначен для создания простой геометрии, которая меняется каждый кадр.
Сначала вам нужно создать MeshInstance3D и добавить к нему ImmediateMesh в Инспекторе.
Затем добавьте скрипт в MeshInstance3D. Код для ImmediateMesh должен быть в функции _process(), если вы хотите, чтобы он обновлял каждый кадр, или в функции _ready(), если вы хотите создать сетку один раз и не обновлять ее. Если вы генерируете поверхность только один раз, ImmediateMesh так же эффективен, как и любой другой тип сетки, поскольку сгенерированная сетка кэшируется и используется повторно.
Чтобы начать создание геометрии, необходимо вызвать surface_begin(). surface_begin() принимает аргумент PrimitiveType. PrimitiveType указывает GPU, как расположить примитив на основе переданных вершин (будь то треугольники, линии, точки и т.д.). Полный список можно найти в документации класса Mesh.
После вызова surface_begin() можно начинать добавлять вершины. Вершины добавляются по одной. Сначала задаются атрибуты конкретной вершины, такие как нормали или UV-координаты, с помощью surface_set_****() (например, surface_set_normal()). Затем вызывается surface_add_vertex() для добавления вершины с этими атрибутами. Например:
# Add a vertex with normal and uv.
surface_set_normal(Vector3(0, 1, 0))
surface_set_uv(Vector2(1, 1))
surface_add_vertex(Vector3(0, 0, 1))
В вершину включаются только атрибуты, добавленные до вызова surface_add_vertex(). Если вы добавите атрибут дважды перед вызовом surface_add_vertex(), будет использован только второй вызов.
Наконец, после добавления всех вершин вызовите surface_end(), чтобы сигнализировать о завершении создания поверхности. Вы можете вызывать surface_begin() и surface_end() несколько раз для создания нескольких поверхностей для одной сетки.
Пример кода ниже рисует один треугольник в функции _ready().
extends MeshInstance3D
func _ready():
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
mesh.surface_add_vertex(Vector3(-1, -1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 1))
mesh.surface_add_vertex(Vector3(-1, 1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(1, 1))
mesh.surface_add_vertex(Vector3(1, 1, 0))
# End drawing.
mesh.surface_end()
ImmediateMesh также можно использовать между кадрами. Каждый раз, когда вы вызываете surface_begin() и surface_end(), вы добавляете новую поверхность в ImmediateMesh. Если вы хотите воссоздавать сетку с нуля в каждом кадре, вызовите clear_surfaces() перед вызовом surface_begin().
extends MeshInstance3D
func _process(delta):
# Clean up before drawing.
mesh.clear_surfaces()
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Draw mesh.
# End drawing.
mesh.surface_end()
Приведенный выше код будет динамически создавать и рисовать одну поверхность в каждом кадре.