Multiple Viewports have a one-frame delay on render

Godot Version

v3.5.1

Question

Hello,
I’m trying to create a reflection setup for a top-down 2D game. For each reflection, I have a ViewportContainer with a Viewport child. I go through my list of characters and objects to reflect, duplicate any sprite children on them, add the new sprites as children of the reflection Viewport, and then update the positions, visibility, frame, etc. of the duplicated sprites at each processing step. I’m using this method over a BackBufferCopy or a shader because I want to manipulate the reflected sprite’s frame and region rect to differ from the original, like if you’re facing a mirror on a wall, the reflected sprite is modified to show your character’s face frames instead of his back frames.

This works perfectly fine for the first reflection viewport in the scene tree, but for any others, I’ve noticed a one-frame delay (you can see the reflected sprite visually lagging behind at the position where you were last frame). The first reflection node in my map’s node tree is always showing up-to-date frame information - reordering the nodes in the tree changes which reflection behaves properly. Only the other reflections have the delay.

I’ve found somewhat of a workaround for this by redrawing my reflection viewports calling VisualServer.force_draw(false) (I set my main viewports’ render_target_update_mode to UPDATE_DISABLED and the reflection viewports to UPDATE_ONCE, then call the force_draw, then set the main viewports back to UPDATE_ALWAYS). This causes the positions to display correctly, but then I run into an issue when I switch sprite visibility. When a character flips visibility between two sprites (such as setting the walking sprite’s visibility to false and the running sprite’s visibility to true), the newly visible reflected sprite doesn’t actually show up (I’ve verified in the debugger that the visible property is set to true) while the previously visible sprite is hidden. This causes the reflection to have a one-frame flashing effect where both sprites disappear completely when you swap their visibility.

Does anyone have any insight on what’s causing either of these things and how to get around them (other than updating to 4.x)? My fallback is to ditch the viewports and just stick the reflected sprites into a control with clip content enabled, but I won’t be able to apply shaders to the full reflection in that case - just to the individual reflected sprites.

For the sake of anyone that happens to stumble into this, the best workaround I’ve found for this was just adding a one-frame delay onto any sprites that I set visible to false for within the extra reflection viewports. It’s not perfect, but it’s a small enough delay that the human eye doesn’t notice it when running the game at higher framerates since it gets rid of the “flickering” effect.