ViewportTexture Performance drops

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

I am creating a 3D game, and I am trying to add enemies to it. These enemies are added dinamically when my character gets close to them. I do it by using the “add_child” method within the main node.

It works perfectly fine, but when I add a 2D healthbar implemented with a progressive viewport texture, the performance to add (not to create) the enemies scenes drops a lot, and even make my screen freeze for even more than 1 second.

When I comment the code to add the 2D healthbar, the enemies scenes are added very smoothly.

Depending the area my character is, it maybe creates more than 10 enemies, which means more than 10 viewports for the healthbars.

I think I should use another way to do it. Do you guys have any tips, better way to do it? Or am I doing something very wrong?

You could avoid using viewports entirely to create health bars in 3D. For instance, you could use a MeshInstance + QuadMesh whose material has billboard enabled, then positing this MeshInstance to be parented to the enemy (but slightly above it). Then you can change the QuadMesh’s scale to adjust the “percentage” of the health bar.

Calinou | 2021-04-07 16:31

I am actually getting frustrated with this issue… what you said is true, I can use meshes to create the health bars… but what about 2D Labels ? I also need 2D effects in my game, which they will have to use viewports because this is the only way to do it. And if I create them on the fly I have a lot of stuttering.

I think this should be straitgh forward, and I would never think adding dinamically 10 to 20 text labels on the main scene would be so heavy.

zecaribeiro | 2021-04-07 17:07

:bust_in_silhouette: Reply From: Lopy

From what I understand, you create an independent 2D world, manage a Control inside it, then use an (implicit) Camera2D to render what it sees on a Spatial in your main scene. This does seem indeed very computationally expensive.

An easy improvement would be to try and reduce the quality of the Viewports, and make sure that they use a singular 2D world, where the various healthbars would be next to one another (even if no-one can see that).

The most efficient method however would probably to use a MeshInstance and change its texture depending on the remaining health. You might be able to do a 1*10 pixel Texture, and edit the pixels on the fly.

Thank you for the suggestion!

But the viewports dont have their own world. I use them as ViewportTexture for a Sprite3D node. I did what you said to reduce the quality of the viewports, and it got better, but far from the ideal. I still have lots of stuttering.

Maybe I understood it wrongly… do you have an example you can show me?

Doing it by using meshes is a lot more efficient, but the problem is that I need to also add 2d effects + 2d labels… And I cannot do it by using meshes.

zecaribeiro | 2021-04-07 17:11