Shaders stop on web when new scene is loaded

Godot Version

v4.4.1.stable.official [49a5bc7b6]

Question

I’m working on a simple 2D game using fragment shaders on animated sprites. It works fine when run for Desktop (MacOS), but when I export for web and run on Safari or Chrome on an iPad or in Safari on desktop (launched via Godot), the shaders stop working after loading the scene a couple times (either loading a new level or reloading the current level). They work as expected for the first couple times a scene is loaded. This happens in both Compatibility and Mobile rendering modes.

The shaders are the same, all the sprites are the same (new instances). The game still plays as expected, it’s just that the shader effects are no longer applied to the sprites. There are no console errors that I can see. I’m not sure how to even start troubleshooting!

Any advice / insight?

Thanks,
Douglas

Sounds like a memory leak. Hit F12 in your browser and watch what your browser is doing. You can also monitor your system resources and see if RAM usage for your browser tab keeps increasing. Then go back into the editor, play the game and open the Remote tab. As you play, see what items are getting added and not deleted.

It’s possible your shaders are being sacrificed first to the memory gods. It’s also possible that something is causing them to just stop working, i.e. they’re no longer getting the input they need to function.

1 Like

Thank you! I’ll start with the memory leak clue. That sounds very likely as I do create and destroy a lot of scenes.

1 Like

You were correct, there was a memory leak! I wasn’t able to find it via the remote/editor, since it was orphan nodes, and those don’t appear in the tree. But once I realized there was definitely a leak and it wasn’t appearing in the tree, I started using print_orphan_nodes() and was able to track down the problem. I was removing my scene from the tree, but not actually calling queue_free() on it. Obvious error in retrospect!

UNFORTUNATELY now that I don’t have a memory leaks (that I can find after extensive monitoring of objects and memory) the shaders are still crashing on web! So it seems like I found a bug, but it wasn’t actually the bug affecting my shaders.

One new clue is that after letting the game run for a few minutes the objects with shaders attached all turn red. Which seems to imply that they’re not crashed but that some memory is being corrupted or a variable is doing something I don’t understand. Any additional hints on how to troubleshoot shaders welcome!

1 Like

If it were me, I would remove all the shaders but one, and see what happens. That’ll tell you if it’s load or something else.

Then if it’s not load, try to simplify your shader to something really basic, like pulling the texture from the screen and upping the blue channel. Then see if it continues to fail. If it does, then it seems solidly a bug. Otherwise, it’s likely something in your shader code.

It was my shader code, although I don’t completely understand the problem. I think was over-using instance uniforms, although I thought I was keeping to the < 16 per shader guideline. The problem was cycling in and out as I added and removed objects using the shader, so something was going on with the accumulated number of instance uniforms. It also seems that one shader using instance uniforms can affect the total for other un-related shaders.

So, it’s still mysterious to me. The takeaway is that when I simplified my use of instance uniforms (max of one per shader now), the problem went away. I hope that helps someone in the future! Use as few instance uniforms as possible.

I should mention again that this problem only appeared on web exports, not on desktop. I don’t know if that’s due to there being more memory generally available on desktop, or to something about the renderers. It happened with both Compatibility and Mobile renderers.

1 Like