Slow GUI rendering

Hi. I use AdvancedDynamicTexture.CreateFullscreenUI() to draw the entire GUI in the game. The clouds above the houses are also drawn on this texture and attached to the houses via linkWithMesh. The problem starts at the moment of camera movement because the clouds need to be redrawn, but this redrawing takes a huge frame time → as a result, the fps drops.

Game link: https://lands-staging.faraway.com/Hriz256#LZW3UQ
Here is an example:


Maybe there are ways to optimize this?

2 Likes

Have you tried using control.useBitmapCache = true on the clouds to see if that will help?

Yes, I tried it. No effect

While @carolhmj is having a look, let me tell you the game is way too pretty !!!

Maybe for some of those effects a webgl rendering would help ?

Thank you:)

What effects are you talking about?

I believe he’s talking about the clouds which (in my opinion) shouldn’t be part of the ADT. There’s a good reason why the ADT does not refresh at the same rate as scene objects and fx. I agree with @sebavan that these fx should not be part of the ADT layer. And then, I also agree that this scene looks just very pretty :heart_eyes:

If doing this is not part of the ADT layer, how then?
dynamic texture + instanced plane + billboard mode?

Depends on how often it appears and there are a number of options as per the animation and frequency.
But yes, either basically on a plane in which case likely parented to the cam and/or resized with canvas. Else as a pp fx on full-screen (likely from NME or shader). Something around that (again, my opinion only). We’ll see what @carolhmj has to say about it… Meanwhile, have a great day :sunglasses:

I think it would be important to mention that there are clouds width text, so it is important for me to be able to render them dynamically

Снимок экрана 2023-03-16 в 13.23.17
Снимок экрана 2023-03-16 в 13.23.45

Sorry I’m not sure to understand this part. I don’t see any clouds in your hotspots (from the site or the screenshots above). Do you mean you want to make sure that the GUI can still be viewed when there are clouds. I guess this request is implicit and shouldn’t be a problem. Something I missed?

By clouds I mean pop-up bubbles (I have attached screenshots of them). They are part of the ADT layer now

OMG. :shushing_face: So it’s a language issue (english is also not my language). The clouds I can see on the screen opening above the scene are not those who you were talking about. Your issue is with your hotspots ‘pop-up bubbles’ that are slowing down your scene, is it?

Yes. They are part of the ADT layer and it takes a long time to redraw them

Ok, now I get it. You can forget about the above (my apologies). :pleading_face: :pray:
So let’s start new: All these hotspots/bubbles/clouds, they are all in a single FS ADT texture, is it? You didn’t use ADT for mesh (in texture mode)? And you render/update the entire ADT on each call of these hotspots/bubbles, is that what it is? And when you say they are drawn on this texture, do you mean in real time? They are created and disposed each time you click on an interactive object? And then, you can actually not interact with these bubbles, can you? In case, you could use a dynamicTexture for this part…

Edit: So I just went back to your perf screenshot and I guess this is clearer now. I suppose your issue is for mobile or just from the numbers. Because to be honest, on desktop, I didn’t notice this performance drop and it doesn’t affect my user xp. But then, I don’t seem to be able to move the cam while the bubble is open, so I suppose I cannot really reproduce as per your initial post.

Yes, that’s right.

No, I haven’t tried that. Does that make sense? There could be dozens or hundreds of hotstops

They have to redraw themselves every time the camera moves

I create them once, if it is a hotspot with a timer it updates its time text every second

const hotspot = new Container();
ADT.addControl(hotspot);
hotspot.linkWithMesh(attachmentNode);

I believe not. Not in this case and not until we get this cloning of ADT feature I’m still waiting on :grin:

For the rest, I will leave @carolhmj (my GUI mentor :woman_teacher:) reply :grin: I don’t feel like taking a chance giving the wrong answer here :grinning: I guess you provided enough information for that to happen. Shouldn’t be all too long… :hourglass_flowing_sand:

2 Likes

Hello! Wasn’t able to check this earlier, sorry! First thing, I’ll add to Seb and say that the game is looking very very nice already!

I’ve started investigating your example and will report back!

1 Like

I’ve tried doing some captures in your scene using CPU slowdown so the problem gets more visible. What looks like to be using the most time is drawImage, like in these two frame examples:


I imagine you’re using some high resolution images for your game, and certain graphic processors (maybe machines with integrated graphics?) struggle to draw them. Keep in mind that when using a GUI image, it is drawn on a 2D canvas context first and then passed as a texture to the 3D main context. And the 3D frame has to wait for the 2D GUI layer to be drawn, which slows everything down. You can see on the captures that _renderForCamera has to wait for _checkUpdate to finish everything before it can end.

One possible solution would be to lower this resolution. It could be something adaptive, where you detect the agent and adjust the images resolution accordingly. Another option would be to move those elements that rerender many times to use billboarded meshes instead of linked GUI. I put together an example here, the two methods aren’t looking exactly the same, but it can be further refined and adjusted: Simple GUI in fullscreen mode | Babylon.js Playground (babylonjs.com). The idea here is, well, since the CPU is struggling to draw these high res images in a 2D canvas context, bypass it entirely and render on 3D context as a texture.

There are other further explorations that could be ventured, like maybe rendering the GUI only every X frames, but I think these first two solutions are simpler.

In addition to pictures, hotspots also show timers (text), so I need DynamicTexture as a minimum. Would it be beneficial if I have to create 100 hotspots (100 dynamic textures)?