Work in progress

The content of this page was not yet updated for Godot 4.2 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

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

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

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

Мульти Meshes

MultiMesh - це єдиний примітив малювання, який може малювати до мільйонів об'єктів за один прохід. Він надзвичайно ефективний, оскільки використовує для цього апаратне забезпечення графічного процесора (у OpenGL ES 2.0 він менш ефективний, оскільки не має апаратної підтримки).

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

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

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

Another alternative is to use a GDExtension and C++, which should be extremely efficient (it's possible to set the entire state for all objects using linear memory via the RenderingServer.multimesh_set_buffer() function). This way, the array can be created with multiple threads, then set in one call, providing high cache efficiency.

Нарешті, не обов'язково, щоб усі екземпляри 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
    # 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)))