Big spike in idle time on adding instanced node to scene tree for first time.

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

When I preload and instance a packed .tscn, the first time I add it to the scene tree causes a large and noticeable frame lag that isn’t there when adding subsequent instances. This persists even if all instances of it in the scene tree are freed and only the initial reference to it remains.

Since it happens the first time the scene needs to be rendered I assume that godot is waiting until then to load some resources from the scene file, but if this happens when I’m trying to instance it I can’t use background loading to prepare it in advance. How do I make adding the first instance of the node to the scene tree as seamless as adding following ones?

Here’s a project file I made showing the problem I’m having: Data package from March 20th. - FileTransfer.io

You can see the big spike in frame time, on the first instance of the cubes being added, but nothing for the following ones.

The tscn in question is made from a .glb exported from blender

:bust_in_silhouette: Reply From: MrEliptik

What you’re experiencing is Godot compiling the shaders for your materials. This is a known issue, due to the way things are handled in OpenGL. Unfortunately there’s no perfect answer (see relevant discussion here: https://github.com/godotengine/godot/issues/13954).

The trick is to render all your materials on an invisible mesh (invisible to the player but visible to the camera, otherwise the shaders don’t get compiled).

Here’s a video showing you how: https://www.youtube.com/watch?v=Cg4ZT6X0ghs

Thanks for the help. That really is kind of a pain but at least I can get things going now. Hopefully 4.0 will get pre-caching figured out in a good way so we won’t have to do workarounds like this.

benis | 2021-03-21 11:58

Actually, I’ve got a followup question: The github issue mentioned that different threads can’t share cached shaders, so does this mean that they also can’t be shared across scenes instanced in different viewports (since I guess each viewport has its own rendering thread). I tried a solution similar to the video but with the change that the materials were being drawn to a viewport inside a viewportcontainer, but still had the stutter when adding the scene that used them to a different viewport (even when they were clearly already visible on screen).

So I wanted to clarify if they have to be cached for each viewport individually and you can’t use that kind of trickery to get around it: You’ve got to put them in the actual viewport you want them rendered on in the end, right?

benis | 2021-03-21 12:21

Unfortunately, I don’t have an answer for that, it’s beyond my scope.

MrEliptik | 2021-03-21 18:34