Control visibility of large groups of MultimeshInstance3D managed with RenderingServer

Godot Version

4.6.2

Context

I’m working on this and right now most of the game is managed in the Scene Tree but I’m hitting memory and performance limits because of the large number of MultiMeshInstance3D.

I’m in the process of tackling the performances issue that currently negatively impact the frame rates.

The current development branch of my game replace the Scene Tree management with the lower level approach offered by RenderingServer. A positive observable effect is that stuttering is less noticeable during environment preloading/refreshing and frame rate is more stable while exploring the environment.

Issue

I have many rooms made of many MultimeshInstance3D modules managed with RenderingServer.

For a given active room (the one where the player is) all neighbors (up to a limited range) are preloaded.

The issue here is these preloaded rooms are always visible. Because they are not inside the scene tree there is no easy way to toggle visibility upon already existing rules designed to work with the scene tree logic.

Question

Is it possible to control visibility of large group of MultimeshInstance3D with one CPU call ?

I assume that sort of thing would involve some custom shader, custom vertex data, and some uniform variables but I don’t know how to do this with the Godot workflow.

Also ideally i would like to enable or disable visibility at the geometry level, if that make sense, not in the fragment stage. In other words, ideally, vertices should not be processed at all if the condition is not met (a visibility uniform set to true for example).

Any hints, tips, useful resources or related documentations page would be great.

:nerd_face:

Why aren’t they part of the scene tree? Just adding them and setting them not visible seems like the easiest solution.

By this you probably mean frustum culling. Culling happens via bounding boxes. The engine has no way of calculating this in a straightfoward way for multi instances but you can supply it your own estimate via RenderingServer::instance_set_custom_aabb()

2 Likes

@dragonforge-dev Because creating and adding a lot of instances was causing a lot of stuttering during gameplay, which is precisely what I try to avoid. I tried an approach based on a limited amount of deferred call per frame but this wasn’t doing great. I also tried a mixed approach with multi-threading and deferred call. None was really efficient. Maybe I messed up things, but since I’m working on this specific issue since months I do hope I didn’t implement all of the previous attempt the wrong way.

@normalized Indeed this could help a lot. I will give a try. Thank you.

1 Like

When it comes to adding instances to a multimesh, it doesn’t really make much difference if you’re doing it to a node or via the server.

Avoid buffer resizes. Keep the total number of instances constant. You can also keep the number of visible instances constant by null-scaling the ones you’re currently not using.

1 Like