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.

Оптимізація за допомогою MultiMeshes

Для великої кількості екземплярів (тисячі), які потрібно постійно обробляти (і при цьому зберігати певний рівень контролю), рекомендованою оптимізацією є using servers directly.

Коли кількість об'єктів сягає сотень тисяч або мільйонів, жоден з цих підходів вже не є ефективним. Проте, залежно від вимог, можлива ще одна оптимізація.

Мульти Meshes

MultiMesh — це єдиний примітив малювання, який може малювати до мільйонів об’єктів за один раз. Це надзвичайно ефективно, оскільки для цього використовується апаратне забезпечення GPU.

Єдиним недоліком є те, що немає можливості відбраковування окремих екземплярів, ні екранної, ні frustum. Це означає, що мільйони об'єктів будуть малюватися завжди або ніколи, залежно від видимості всього MultiMesh. Для них можна надати власне налаштування видимості, але це завжди буде видимість типу всі-або-нікого.

Якщо об'єкти досить прості (лише пара вершин), це не є великою проблемою, оскільки більшість сучасних графічних процесорів оптимізовано для цього випадку використання. Обхідним шляхом є створення декількох MultiMeshes для різних частин світу.

Також можна виконати певну логіку всередині шейдера вершин(за допомогою вбудованих констант INSTANCE_ID або INSTANCE_CUSTOM). Приклад анімації тисяч об'єктів у MultiMesh наведено у посібнику Animating thousands of fish. Інформацію шейдеру можна надавати за допомогою текстур (для цього ідеально підходять десяткові формати Image).

Іншою альтернативою є використання GDExtension і C++, що має бути надзвичайно ефективним (можна встановити повний стан для всіх об’єктів, використовуючи лінійну пам’ять, за допомогою функції RenderingServer.multimesh_set_buffer()). Таким чином, масив можна створити з кількома потоками, а потім встановити за один виклик, забезпечуючи високу ефективність кешу.

Нарешті, не обов'язково, щоб усі екземпляри MultiMesh були видимими. Кількість видимих екземплярів можна контролювати за допомогою властивості MultiMesh.visible_instance_count. Типовим робочим процесом є виділення максимальної кількості екземплярів, які будуть використовуватися, а потім зміна кількості видимих екземплярів залежно від того, скільки з них потрібно в даний момент.

Multimesh приклад

Ось приклад використання MultiMesh з коду. Мови, відмінні від GDScript, можуть бути ефективнішими для мільйонів об'єктів, але для кількох тисяч GDScript має бути чудовим.

extends MultiMeshInstance3D


func _ready():
    # Create the multimesh.
    multimesh = MultiMesh.new()
    # Set the format first.
    multimesh.transform_format = MultiMesh.TRANSFORM_3D
    # Set the mesh that will be duplicated.
    multimesh.mesh = BoxMesh.new()
    # Then resize (otherwise, changing the format is not allowed).
    multimesh.instance_count = 10000
    # Maybe not all of them should be visible at first.
    multimesh.visible_instance_count = 1000

    # Set the transform of the instances.
    for i in multimesh.visible_instance_count:
        multimesh.set_instance_transform(i, Transform3D(Basis(), Vector3(i * 20, 0, 0)))