Compute shaders - hot to get data back

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Andrea

Hello, i’m trying to run a “pixel-per-pixel” simulation, and obviously doing it through shader would help a lot.
I cant find a decent source of documentation on the topic, especially on how to get data back after a computing step, but i’ve read that the best solution is to use a Viewport texture, so I did it.
However now i’m stuck, i cant find a way to “feed” the newly generated viewport texture to the shader in order to compute the next temporal step of the simulation.

I got 2 sprites, one for Quantity, the other for NextQuantity, NextQty has the shader that performs the calculation. What i’m triying to achieve is:

take the texture of Qty and give it to NextQty=> the shader pass is applied => take the texture of NextQty (with the applied shader) and give it to Qty=>repeat.

I’ve tried different configuration but up to now nothing seems to work, any hints from you guys?


EDIT:
I think i almost solved it, as i said i created the 2 sprites: Qty in the root viewport, and NextQty in a secondary Viewport (from where i take the ViewportTexture). The shader material is applied to NextQty to compute each simulation step based on its current texture.
In process i run the below code: first i get_data_from_shader to take the ViewportTexture (original NextQty texture+applied shader) and convert into a single Image variable. Then I pass_data_to_shader to take said image and use it for the texture of the NextQty, so that it can be used by the shader to compute the next step.

var tex=ImageTexture.new()
var img=Image.new()
var count=0
var value=2

func _process(delta):
  count+=1
  if count==value:
	  get_data_from_shader()
	  pass_data_to_shader()
	  count=0

func get_data_from_shader():
	img = $Viewport.get_texture().get_data()
	img.lock()
	img.flip_y()

func pass_data_to_shader():
	tex.create_from_image(img,3)
	$Qty.texture=tex    #only for visualizing the result
	$Viewport/NextQty.texture=tex

it works but it’s not optimal: as you can see i had to implement a counter to skip same frames.
I’m not sure why, but it seems like it is not possibile to change a texture of an object inside a viewport each frame, it requires at least 1 idle frame otherwise the Sprite texture get deleted (i checked in remote, NextQty has no texture if value==1)

My solution is kinda messy, and i can see my self making a lot of mistakes with it.
Secondly, it is effectively halving the computing power of the engine.
If you guys know how to apply the change on one single frame it would be great