How to make a particular instance of a multimesh invisible or visible?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By toblin

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?

:bust_in_silhouette: Reply From: btuso

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

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

OzzRC | 2020-10-25 20:12

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.

btuso | 2020-10-25 22:18

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

OzzRC | 2020-10-26 01:01

Glad to have been of help, looks great!

btuso | 2020-10-26 01:54