-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bind mesh merging functionality in MeshInstance #57661
Conversation
The portal system introduced basic mesh merging functionality, this has wide ranging uses outside of the portal system. For this reason, this PR binds the mesh merging functionality. It also slightly modifies the calling from RoomManager to use a Vector of Node *, in order to allow binding of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed in PR review meeting today.
Exposing the existing feature for 3.x
seems fine, so this can be merged.
For 4.0, we'd like to have this properly integrated in the importer so that mesh merging can be done at import, also handling LOD, etc. properly.
Thanks! |
I noticed this PR is for 3.x branch - is there an equivalent for 4.0? |
See the above comment:
This will require an entirely separate implementation – also, the portals and rooms system isn't ported to 4.0 yet. Mesh merging relies on the portals and rooms system to an extent – at least internally. |
@akien-mga This seems like a pretty big deal that our team just discovered by pouring over PRs. We'll be implementing it soon and expect it will give us a huge performance boost on our development level. We were previously merging meshes manually in blender and it was quite time consuming. We looked at your latest news article and saw it's listed in the additions list, but it seems like this is a very important feature that should be highlighted in your news release. Thanks to everyone who made it possible. Looking forward to mesh merging in GD4. It's definitely desireable to have meshes able to be merged on import or at runtime. Runtime allows us to construct a house or village from components and keep them separate for development. |
Mesh merging is indeed hugely important, especially on GLES as drawcalls will often limit performance. Ideally it would be nice to expose this in an easier to use way (such as the UI, or automatic), but at least now it is available for power users. This is something we discussed recently on rocketchat, the potential for static flags (or groups) for meshes or similar to allow them to be merged after loading a level at runtime, both in terms of camera rendering (where materials must match) and in terms of shadow proxy meshes (where there is no requirement for matching materials, providing they are opaque and not moving). One even simpler option is to add a menu item whereby you can select a bunch of |
With "matching materials", do they have to be an identical 1:1 match? The documentation isn't clear on the specifics. If a wall has 2 materials, rock and wood, that should merge with a beam that only has wood. Really, even if you merge a single material wood beam and a rock, it should just create two material slots in the merged mesh. If you merge a set of houses, it should align all the glass, wood, thatch materials, and even though your window object is just a plane with one material, create additional slots for unique materials. |
It is very basic at the moment, primarily intended for merging bunch of similar (or identical) objects like trees, so the material matching requirements are very high. Merging can be made quite a bit more versatile though, by creating multiple materials, or even creating atlases. @fire has done quite a bit in this area I believe. PRs to improve the merging are welcome. Bear in mind that a single |
I'd expect that having a house like this w/ 6-7 materials, 786 objects, 1859 draw calls should get reduced down to around 6-7 draw calls based on the number of materials. And when we have 30 houses in our village, that magnifies the savings. However I tried some merging of simple objects via code and could not get it to work. The engine said they were mergable, and said the merge was successful, yet the resulting mesh is the same as the appended mesh, the source mesh is not included. Also the materials moved. They were attached to the mesh, after the merge they were put on the material override slots, which is not where they should be.
|
Oh yup sure. You would have to split by material first (using the addon), or improve the merging code. As I say it is currently bare minimum, and designed mainly with duplicate instances in mind (in order politically to get it merged, it is easier when things are simpler, rather than write something complex and not have it merged at all).
Does the model look different? The merging only attempts to make the result look the same, it does not warrant that the technical aspects will bear any relation to the input meshes (especially to make the code as simple as possible). It is possible that the materials could be set in a better way, I'm no expert in how materials are specified.
Please open an issue with MRP and I can investigate. 👍 |
The portal system introduced basic mesh merging functionality, this has wide ranging uses outside of the portal system.
For this reason, this PR binds the mesh merging functionality.
It also slightly modifies the calling from RoomManager to use a Vector of Node *, in order to allow binding of the function.
Introduction
Mesh merging is a very useful tool in the performance toolbox. Many games, especially outdoor games are bottlenecked by the number of MeshInstances, both in terms of draw calls in the renderer (especially with OpenGL), but also in terms of housekeeping scene tree side.
Merging meshes, either ahead of time (pre-baking and saving) or at runtime (usually at level startup) can offer significant performance improvements, particularly for things like vegetation and procedural modular block levels (such as minecraft type maps).
This is especially relevant when hardware instancing is not available, such as in GLES2, or where hardware instancing cannot be used, such as when a variety of different meshes must be drawn at once.
Note however that there is a trade off - merged meshes will be culled as a block, so depending on how you apply it you can lose culling accuracy. This will still be a net win in many situations though. And, unlike instancing, you also lose the ability to move the merged objects relative to each other, they can only be moved as a group.
Local or Global space
The merged vertices can either be defined in global (world) space, or in the local space of the destination
MeshInstance
(provided it is in the SceneTree, which is necessary in order to get its global_transform).In a static scene, global space may make sense, but when merging sub-parts of a movable object (say a spaceship), you may want the vertices specified relative to the object, so that when you move it the parts move in unison.
Local space is default. Note that local space will flag a warning if you merge before adding the MeshInstance to the SceneTree (because the local space is undefined), and will revert to global space.
Notes
get_global_transform()
. I'm not quite sure whether it would be better to checkis_inside_tree()
and silently allow this, we can always change this based on feedback though.Example script:
Example project
20,000 boxes, either drawn separately or merged:
MergingTest.zip
Separate 28 fps
Merged 664 fps (24 x faster)
Bugsquad edit: Related (but not closing) godotengine/godot-proposals#901.