Implement a two-layered 2D shader that combines a 'morph' shader and a pixelation shader

Godot Version

Godot 4.4

tl;dr

I am trying to combine two 2D shaders into a two-layered shader. The first shader should generate an intermediate ‘buffer’ image, followed by a second pixelation shader that draws on the actual display.

Since there is no next_pass for 2d, I guess I need to implement a workaround using hint_screen_texture. However, I want the buffer image to have a consistent resolution (i.e. number of fragments) and the screen texture scale with window size. This changing resolution problem also applies to viewports.

Full description of what I am trying to do

For completeness sake, also this might be interesting for some of you.

I am trying to make a shader that generates a pixelized ‘morph’ between two source images
demo_p_full_size-export

I could not find any available shaders that achieve the morphing effect, searching for ‘morph’ on shader websites gives something very different. So I had to come up with my own algorithm.

The morphing works by defining a set of reference points on each source images, and generating a kernel-based projection that transforms one set of points into the other.

I then create the morph by linearly interpolating the projected images.
demo_full_size

The second shader is the pixelation shader, which pixelize the source, maps it to a color palatte, and generates dithering. To differenciate between a hard edge which I don’t want dithering that mess up the line and shading which dithering is for, multiple samples has to be taken for each fragment.
demo_dither

The pixelation shader generates a pixelized image, which may or may not need to be stretched into proper size.
demo_p

I need to have a two-layered shader with a buffer instead of hard coding the two into one shader because

  1. One functionality, one shader. I also need to pixelize other sprites without morphing so I want an independent pixelization shader.
  2. The morphing algorithm I made myself is not very efficient, and the pixelation shader requires multiple samples from the morph image. To reduce the calls to the morphing algorithm as much as possible, I want to save that result in a buffer.

I understand that post-processing pixelation shaders are common, however for the 2d pixel game look I am going for, the pixelation result has to be consistent regardless of the window size, especially when the window is small, leading to a badly compressed buffer.