+3 votes

You can control the transform of an individual instance of a multimesh through MultiMeshInstance.MultiMesh.set_instance_transform ( int instance, Transform transform ).

You can control how many of the instances are visible through MultiMeshInstance.Multimesh.visible_instance_count = < parameter >.

But how do you control which of the instances are visible and invisible?

I have cells that are born, and some eventually die. Since particular cells will die, it's not precise enough to tune down the visible_instance_count (since I'm assuming that the highest indices will be cut off). So how can I make a MultiMesh instance, representing a dead cell, invisible?

in Engine by (138 points)

1 Answer

+1 vote

One thing you can do is scale the particular instance transform to zero.
I do something like this for a custom multimesh I use.

var ZERO_TRANSFORM = Transform.IDENTITY.scaled(Vector3.ZERO)
....
func _hide_all():
for i in multimesh.instance_count:
    multimesh.set_instance_transform(i, ZERO_TRANSFORM)

The previous code effectively "hides" every instance of the multimesh and stops them from being rendered altogether, so there's no performance loss.

You can even set the color of a particular instance which has a transparent material in order to fade them out. Do keep in mind however that transparent instances are still being processed by the renderer.

You can see it all in action here

by (58 points)

Hi!!!, I read your comment and tried implementing it by my self, but, some how, I still get the same fps drop as if all instances where being rendered. Could you give some more advice on how did you implemented your grass system? I am trying to create a grass field too

Here's the code

I use an area to determine when the player enters the multimesh and another one to determine the player position and render distance.

The most important bit is to be aware of how much time per frame you spend iterating over the instances, especially if you have a lot of them. To avoid iterating over the whole list in a single frame I split the iteration into batches and process them over multiple frames.

You can ignore the following part, as it is quite convoluted and the performance gains are not that huge.

Another optimization I use is to have a dynamic amount of meshes being available to be shown. As mentioned before, the biggest cost lays in iterating over all of the meshes, but if you only have a set amount of meshes you can show, then you can potentially break the iteration once you're showing all the instances you have available.

This is handled by the dynamic pool, which grows or shrinks trying to fit the amount of meshes in the display area.

Keep in mind that there might be better options for creating grass. This is mostly to increase performance of wide area multimeshes by limiting the render distance, since Godot doesn't have occlusion culling.

Thanks!!!!! I am going to test it right now.!!!!!!
This is what I am working on https://twitter.com/OzzRC0/status/1314978039856533509?s=09

Glad to have been of help, looks great!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.