Dynamically compositing lots of textures via Subviewports, looking for optimization advice

Godot Version

4.5

Question

My game relies pretty heavily on generating custom items at runtime. I do it by compositing together textures via placing Sprites in Subviewports and applying shaders across multiple passes (color swaps, masking, etc.), with each item needing anywhere from 5-15 passes. It works perfectly, but every pass requires an await RenderingServer.frame_post_draw for the viewports to settle before I can “screenshot” the result so it can be used in the next pass.

My game neccessitates that at least ~50 of these items be generated at once, so this causes quite the bottleneck.

So far ive

  • minimized await frames as much as possible (theyre still necessary for viewports to render properly before their textures can be used as parameters in future shaders)
  • implemented 3 subviewports that allow me to ping-pong textures between them (allowing me to use viewport textures as parameters in certain shaders)

Each item takes ~100-200ms but theyre serial (because I dont want to use too many Subviewports) so it builds up fast. I know utilizing RenderingDevice could really help, but it would be a massive rewrite (shaders, helper funcs, management) to rewrite the whole process using it, and I don’t think I have the time for all of that. Caching some passes would be great, but every item is so different that it wouldnt help significantly.

I was wondering if anyone had any ideas on how I could further optimize this? Any help would be awesome! :slight_smile:

What are you doing in all those passes? I’m sure the whole thing can be visually (or conceptually) redesigned/simplified so it doesn’t require that many passes. Can you show some visual examples?

1 Like

Can you use an atlas?

Rendering slowdowns are often due to state changes, including switching textures or subviewports.

I think you could simply scroll the rendertarget region across a larger texture and therefore avoid all state changes.

Following up with what @normalized mentioned, is there a reason you can’t just layer Sprite2D nodes?

Some screen shots of what it looks like and the components you’re building from might help.