I am editing some point cloud volume data in Unity, on the GPU.
My issue is that I have to edit my data in multiple passes (applying multiple different compute shaders to the same data). Is it possible to pass the output from one compute shader to another one? You know, stopping the current compute shader, starting another one, and pointing it to the same data in the GPU memory?
How would that be done? We have the `ComputeShader.Dispatch` to begin with (in unity), which starts one compute shader, and then what? Can I somehow just make multiple `ComputeShader` objects and then do `secondComputeShader.SetBuffer(--existingGPUBuffer--)` and then `.Dispatch()`?
(note: it wouldn't be necessary or optimal for me to run multiple compute shaders in the same frame, unless there's no other option)
I am using DX11, with HLSL. My data structure is in a `RWStructuredBuffer`, which according to MSDN, is synced across the entire GPU -- and indeed I can access this StructuredBuffer in my regular shader for display purposes.
Ideally I would be able to define a layering order "CS-A, CS-B, CS-**A**, CS-C"; if that is at all possible (but not all in the same frame).
Cheers!
[EDIT]
---
Alright, after Ben's comment, I'm posting what I'm doing right now:
public List computeShaderList;
ComputeBuffer particleBuffer;
struct Particle
{
public Vector3 position;
public Vector3 velocity;
};
ComputeShader currentComputeShader;
void Start ()
{
Particle[] particleArray = new Particle[particleCount];//remember to initialize for each Particle (position and velocity)
//create new compute buffer instance, and initialize it with your data.
particleBuffer = new ComputeBuffer(particleCount, 24); // 24 = "stride" = size allocated for each particle, probably in bytes, no idea what happens with this
particleBuffer.SetData(particleArray);
//so now we should have all our point data stored on the GPU, right?
foreach(ComputeShader cs in computeShaderList)
{
cs.SetBuffer(0, "particleBuffer", particleBuffer);
}
material.SetBuffer ("particleBuffer", particleBuffer);//this is for the regular shader
//and now we have told each of our (compute) shaders to reference that data we have stored on the GPU
}
void Update()
{
switch(currentState)// you don't need to run this each frame
{
case ComputeStates.CS_One:
currentComputeShader = computeShaderList[0];
break;
case ComputeStates.CS_Two:
currentComputeShader = computeShaderList[1];
break;
}
//currentComputeShader.SetFloat( ...set all your stuff
//Start the current compute shader to work this frame on your particles.
currentComputeShader.Dispatch(0, threadCount, 1, 1);
}
//note: you also need your OnRender with Graphics.DrawProcedural...
The Unity documentation on compute shaders is lacking, and the exposed ComputeShader object isn't very transparent. All I can say is that according to the Profiler, there seems to be no performance impact from having a bunch of different compute shaders, and choosing which one of them you want to dispatch at what time.
↧