Skip to content

GLTF: Support MultiMesh objects using EXT_mesh_gpu_instancing#112866

Open
aaronfranke wants to merge 1 commit into
godotengine:masterfrom
aaronfranke:gltf-multi-mesh-gpu-inst
Open

GLTF: Support MultiMesh objects using EXT_mesh_gpu_instancing#112866
aaronfranke wants to merge 1 commit into
godotengine:masterfrom
aaronfranke:gltf-multi-mesh-gpu-inst

Conversation

@aaronfranke

@aaronfranke aaronfranke commented Nov 17, 2025

Copy link
Copy Markdown
Member

Fixes issue #109280, supersedes PR #107866.

Draft because this depends on PR #113202, PR #113206, PR #113245, and PR #113247.

This PR adds support for importing glTF EXT_mesh_gpu_instancing nodes as Godot MultiMesh nodes:

Screenshot 2025-11-16 at 1 30 54 PM

In master, this extension was not supported, which meant that such objects were not imported as multiple instances.

This PR also adds support for exporting MultiMesh nodes as glTF EXT_mesh_gpu_instancing, and configuring the export behavior. Users can choose to use the extension, use plain glTF nodes, or use both:

Screenshot 2025-11-16 at 12 42 04 PM

Note that the dropdown only appears when the scene contains at least one MultiMeshInstance3D node, so it won't clutter the export settings UI in most cases where the user does not have any such nodes in their scene.

The options have the following behavior:

  • Optional EXT_mesh_gpu_instancing: Convert MultiMesh nodes into the EXT_mesh_gpu_instancing extension. The extension is marked as not required, so implementations without support can still load the file, but they will see a single mesh instead of multiple instances of meshes.
  • Required EXT_mesh_gpu_instancing: Convert MultiMesh nodes into the EXT_mesh_gpu_instancing extension. The extension is marked as required, so implementations without support cannot load the file.
  • Multiple Nodes Only: Convert MultiMesh nodes into multiple glTF nodes. This is similar to the existing behavior in master, but there are multiple bugs with the current master, which have been fixed in this PR.
  • Multiple Nodes Fallback: Convert MultiMesh nodes into both the EXT_mesh_gpu_instancing extension and multiple nodes, allowing it to be imported as a MultiMesh when supported, or imported as nodes when not supported.

Here's what it looks like when loading a glTF exported with "Multiple Nodes Fallback" into Godot 4.5-stable:

Screenshot 2025-11-16 at 12 36 37 PM

This PR also makes several related changes:

  • Add a function to GLTFState to reserve a unique name (previously was private to GLTFDocument).
  • Fix a bug where MultiMesh's own transform was multiplied into each instance.
  • Fix a bug where 2D MultiMesh transforms were swapping the Y coordinate into Z.
  • Fix a bug where the material name was used as the surface name instead of the surface name.

Test files: ext_mesh_gpu_instancing.zip

@aaronfranke aaronfranke requested review from a team as code owners November 17, 2025 00:56
@aaronfranke aaronfranke added this to the 4.6 milestone Nov 17, 2025
@aaronfranke aaronfranke moved this to Ready for review in Asset Pipeline Issue Triage Nov 17, 2025
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from 5efa1a8 to 0e790eb Compare November 17, 2025 02:18
@Repiteo Repiteo changed the title GLTF: Support MultiMesh objects using EXT_mesh_gpu_instancing GLTF: Support MultiMesh objects using EXT_mesh_gpu_instancing Nov 17, 2025
Comment thread modules/gltf/extensions/gltf_document_extension_multi_mesh.h Outdated
Comment thread modules/gltf/extensions/gltf_document_extension_multi_mesh.h Outdated
Comment thread modules/gltf/doc_classes/GLTFDocumentExtension.xml Outdated
Comment thread modules/gltf/extensions/gltf_document_extension_multi_mesh.cpp Outdated
Comment thread modules/gltf/extensions/gltf_document_extension_multi_mesh.cpp Outdated
@fire

fire commented Nov 18, 2025

Copy link
Copy Markdown
Member

Adding multimesh support to godot engine gltf is a good idea. Need to pick a time to review. Other reviewers are welcome too.

@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from 082cc45 to 4287e0b Compare November 19, 2025 01:59
@Repiteo Repiteo modified the milestones: 4.6, 4.x Nov 19, 2025
Comment thread scene/resources/3d/importer_mesh.cpp
Comment thread scene/resources/3d/importer_mesh.h Outdated
@aaronfranke

aaronfranke commented Nov 27, 2025

Copy link
Copy Markdown
Member Author

I split this into PR #113202, PR #113206, PR #113245, and PR #113247. These can be merged first, and then I can rebase and undraft this PR.

@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from b6325a3 to 3e4a2e1 Compare December 6, 2025 07:26
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch 2 times, most recently from 553d2f4 to 3a96db6 Compare January 10, 2026 19:07
@fire

fire commented Jan 10, 2026

Copy link
Copy Markdown
Member

Seems to be blocked on #113247

@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from 3a96db6 to 8003d6e Compare February 26, 2026 03:12
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from 8003d6e to 844d9b8 Compare March 5, 2026 07:37
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch 2 times, most recently from 1d213bc to ff90da3 Compare March 30, 2026 17:35
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from ff90da3 to 874259f Compare April 14, 2026 06:50
@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from 874259f to f2eb613 Compare April 17, 2026 16:44
@aaronfranke aaronfranke moved this from Work in progress to Ready for review in Asset Pipeline Issue Triage Apr 17, 2026
@aaronfranke aaronfranke marked this pull request as ready for review April 17, 2026 16:47
@mikest

mikest commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

I gave this branch a go on top of master and it works as advertised. 1440 draw calls down to 1 😎

image

@fire fire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be ready to go. Some good user testing too!

Does multimesh instancing in gltf support skinned meshes? How does this handle it?

@aaronfranke

Copy link
Copy Markdown
Member Author

@fire No, skinned meshes are out of the scope which MultiMesh and EXT_mesh_gpu_instancing are meant to cover.

@aaronfranke aaronfranke modified the milestones: 4.x, 4.8 Apr 27, 2026

@fire fire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea. Requires QA. #112866 (comment) may be sufficient qa.

Did not test.

@mikest

mikest commented May 4, 2026

Copy link
Copy Markdown
Contributor

Tested against master from 15min ago. Still working well.

@Ansraer

Ansraer commented May 6, 2026

Copy link
Copy Markdown
Contributor

Hmm, I wonder if it might make more sense to instead import a single mesh resource during import and have multiple MeshInstances that all reference that single mesh resource.
IIRC we automatically batch MeshInstances that share a material and mesh together before they are rendered, so the gpu cost should be almost identical unless the instace count is very high.
With MI we would also get more accurate culling (since MMI are culled based on a combined AABB), which could be important for GPU perf if the meshes are on the heavy side.

I am not convinced that this will necessarily result in better performance. I don't think we support combining multiple MultiMeshInstance, so each of them would end up as an individual draw call. So depending on the scene this might end up resulting in a performance regression compared to using duplicates as we currently do.

e.g.: I have a table asset, which has 4 identical legs and one tabletop. I want to render 200 tables.

Without using any kind of instance import this would result in us rendering each of the table legs once and then the table top, each with 200 instances. So rendering my entire scene would happen with just 5 draw calls.

However, if MultiMeshes are used instead (as implemented by this PR) we could now render a single table using one MeshInstance (top) and one MMI (the four legs). Since MMI can't automatically be combined rendering out entire scene would now take 201 draw calls. (200 * MMI + 1 mesh instance for the batched table tops).

If we instead could use MeshInstances for the leg instances and have all of them reference the same Mesh object we should be able to automatrically combine them when rendering, so the entire scene could be rendered with just two draw calls (one for all the legs, the other for the top).

@mikest

mikest commented May 7, 2026

Copy link
Copy Markdown
Contributor

so the gpu cost should be almost identical unless the instace count is very high.

I have instance counts that can reach tens of thousands (feathers, roof tiling, stone walls, etc). While the server can coalesce the meshes, the MeshInstance3D overhead from that is not negligible even when coalesced.

There is a separate issue with the blender importer not reusing mesh instances (outside of geometry nodes) that should also be fixed at some point, but that seems like a separate issue.

Regardless, the current geometry node behavior is very taxing on performance.

@aaronfranke aaronfranke force-pushed the gltf-multi-mesh-gpu-inst branch from f2eb613 to 3107eb7 Compare May 7, 2026 09:37
@aaronfranke

Copy link
Copy Markdown
Member Author

@Ansraer This PR does not automatically combine anything into MultiMesh / MultiMeshInstance3D. It only generates MultiMeshInstance3D where EXT_mesh_gpu_instancing data exists in the glTF file. And that data only exists when the file author explicitly chose to use this technique when making the file.

@mikest mikest left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have done the following testing:

  • Blender 4.5 & 5.1 imported files
  • Imported GN nodes with instance counts >10,000

No issues discovered yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

6 participants