Currently, you can do SubViewport/ColorRect, with the SubViewport.clear = Never (or Next Frame) and apply the shader to the ColorRect. To read the processed image, read the screen texture in the shader, or call sub_viewport.get_texture().get_image()on the next frame.
So you can only read it on the next frame, whether with the screen texture, or from ViewportTexture.
I’m basically asking, how to read the image in a single frame? or how to request my specific viewport to draw?
It’s not possible. Draw commands are gathered, and optimized and rendered at once. You need to wait at least to RenderingServer.frame_post_draw for the viewports to update.