Best way to set up an input and output texture for CompositorEffect?

Godot Version

4.6

Question

I’ve been learning to use compositor and I have been wondering what the best way would be to have a separate texture for input and output. I’ll start by clarifying why this is necessary.

Consider the case of a simple chromatic aberration shader: You want to read the r, g, and b values from the input texture at different offsets and store them in the final result. A naive port of a .gdshader for this might sample the color texture, and then write back into it. This can cause the threads on the GPU to race causing them to read data that has already been overwritten by another thread. So, we need another texture.

Simple enough, we can create a new texture with RenderSceneBuffersRD.create_texture(). The part I’m not so sure about is copying step. We either need to use this new texture as the output and then copy the final result back into the color texture, or copy the color texture into our new texture and use it as the input.

My first thought was to use RenderingDevice.texture_copy(), but the color buffer doesn’t have the CAN_COPY_FROM or CAN_COPY_TO usage bits set so that simply doesn’t work. The only other way I can think of would be to dispatch a separate compute shader that does nothing but copy the texture over. That seems seems like it might be bad, but maybe it’s just the only way.

I’m also curious about if there’s any particular reason why the color texture doesn’t have the copy usage bits set, and if there’s no good reason maybe I’ll make a feature request / PR to set them.

Render into subviewport, read that texture and write to main screen.