Forum

Compute shader: Output mulitple textures

I have a question concerning compute shaders:
I want to output two textures from a compute shader. One to feed into the shader again with a framedelay and another one to render as the final output. Is it possible to output two textures from a compute shader in vvvv anyway (like in Unity for example) or do I need to add them to a TextureArray? And if so how do I add textures to a TextureArray in vvvv’s HLSL?

And a completely other question: How can I slow down a compute shader in vvvv? For example call it only every fifth frame?

Thanks a lot for your help!

Hi, first of, interesting question.

I did few tests, with RWTexture2D, and RWTexture2DArray
With RWTexture2D everything fine, but you can have only one texture.
With RWTexture2DArray it doesn’t seems to work for some reason

I think it would be more easy to do just:

struct MyOutput {
	float4 col1;
	float4 col2;
}; 

Then do regular Render Buffer
And then do buffer to texture in the pixelshader (tfx)

Anyways here you can have my tester to play around with…
MultiTexCS.zip (763.4 KB)

You have few options, one of witch to store that directly in the memory

Don’t think this possible, you can have frame time and calculate speed based on that…

Here, you can grab all the approaches i made:
MultiTexCSAll.zip (776.7 KB)

No clue why MRT and Array didn’t worked, maybe anyone else can take a look

hey @antokhio
Thanks a lot for your answer. Have you changed something on the BufferToTexture node in the struct approach? It seems like I miss this one if I try it out.

@maxs My bad sorry ;)
Edited wrong file )

MultiTexCSAll.zip (776.4 KB)

Thanks @antokhio works perfectly!

Just a view questions:
You said that I also could store one texture directly in memory, so that I could read from and write to it. How could this be done in a Compute Shader?

And what did you exactly mean with having a frame time and calculate speed based on that?
Are you talking about the global frame rate or specifically targeting the compute shader?

Sorry for the questions and thanks a lot for your help!

When you do RWBuffer you can not only write to it with a shader you can directly read from it.
Basically your Output[x] already accessible and you can call it as any other variable. Generally you would want to have also an reset witch would assign some initial value to the output…

More over you can build a chain of shaders each of them would read “Output” and add something to it… And then you can disable and enable them or control amount on effect…

About timing I can’t really add much, it’s not compute shader related if you can provide some timing for effect and evolve it based on that great, if not, then you have to find way how to do that… or hack a way around…

Thanks @antokhio that helped me a lot so far!

@antokhio sorry for bothering you once more if you’re still reading that thread. I have some troubles reproducing the whole thing with two 3D Textures. Should the struct approach work there as well?

Well that’s the approach is pretty much the same, however, it has few differences:

First function that converts 3D thread id to 1D buffer output:

uint idx = tid.x + tid.y * R.x;

Suspect should be something like this:

uint idx = tid.x + tid.y * R.x + tid.z * (R.y * R.x);

Then I’m not sure how you want to display that, and what you have as 3D Volume input, so you need to wrap up some functions according to your input…

To display as geometry, I made you quick example with instancing.
Shame couldn’t find any better 3d textures around…

MultiTexCS3D.zip (1015.7 KB)

Ah okay I understand that!Thanks for the good example. :) What I’m still not managing to do is to render the 1D Buffer output as two 3DTextures or Volumes.

So what I exactly want to do is:

  • Running a simualtion in a compute shader on a 3DTexture
  • Outputing two 3D Textures
  • Using one of the 3D Textures to put it into a framedelay(3DTexture) and feed it to the Compute Shader again
  • Using the other 3D Texture as the final Output. And turn it into an SDF and render it with Raymarching or use Marching Cubes to mesh it. But this part is already working. Just struggling to get the two 3DTextures out of the Compute Shader.

I’ll setup a little patch now to showcase my problem better if that helps.

Well if you strictly need 3d Texture on output i guess you can run one more compute to pack it back to 3d texture, just use RWTexture3D as output and there should be Render Volume or 3d…

I guess if you assemble example it would be more handy… )

Okay I’ll try that. I’m doing an example patch right now, and upload it if I can’t make it work now anyway. I’m just racking my brain at the moment on the line of code to pack back the 1D Buffer into the 3D Texture.

So the the way to get to 1D was:
uint idx = tid.x + tid.y * R.x + tid.z * (R.y * R.x);

But what’s the way back?

Yea, that why I did it with cross 3d and dynamic buffer so I could use just instance I’d for that…

I think we could use mod operation for that:
Like I%width, i%width*height and so on?
Gonna try in the morning…

Hi, so i manage to sort it for 4,4,4 but needs extra testing…

float3(idx % R.x, floor(idx / R.x) % R.y, floor(idx / (R.x * R.y)));

1Dto3D Test.zip (2.0 KB)

Thank you, that really helped me out a lot! Think I got it working now in an example patch. Just have an “implication of vector type” error in the 1D to 3D shader, but it seems to work though.
I’ll try to implement it in the shader I actually want to use now, but that should work now.

MultiTexCS3D.7z (70.1 KB)