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.

Використання 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(), ви додаєте нову поверхню до ImediateMesh. Якщо ви хочете відтворити сітку з нуля для кожного кадру, викличте 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()

Наведений вище код динамічно створюватиме та малюватиме одну поверхню для кожного кадру.