I am doing a fluid simulation, and implementing such simulation with the CPU is very slow, especially when the simulation grid size gets bigger or is a 3d grid. So I used shaders to get the calculation done in parallel with the GPU, and here I got into a problem. One of the steps of a grid fluid simulation requires solving a linear equation, which I am achieving with the jacobi method. Implementing this method on the CPU is fairly simple, but with the GPU working in parallel, I have to keep two copies of the buffer holding the resulting data, and at each iteration flip between the two so one is being read from and the other stored into. This technique is called ping ponging, and the problem is that I couldn’t get my head around how to implement it as I am still new to shaders. Here is my current solution which I guess is clearly wrong. Any help how I can achieve the ping pong technique in here?
#pragma kernel Solve
RWStructuredBuffer<float3> Solution;
RWStructuredBuffer<float3> X;
StructuredBuffer<float3> X0;
float A;
float C;
int Iterations;
int N;
int index(int x, int y, int z) {
return (x) + (y) * (N);
}
[numthreads(8, 8, 1)]
void Solve(uint3 id : SV_DispatchThreadID) {
int z = id.z;
if (id.x >= N || id.y >= N || z >= N)
return;
float cRecip = 1.0f / C;
for (int iter = 0; iter < Iterations; ++iter) {
float3 q0C = X0[index(id.x, id.y, z)];
float3 qRight = float3(0, 0, 0);
float3 qLeft = float3(0, 0, 0);
float3 qTop = float3(0, 0, 0);
float3 qBottom = float3(0, 0, 0);
if (id.x + 1 < N)
qRight = X[index(id.x + 1, id.y, z)];
if (id.x > 0)
qLeft = X[index(id.x - 1, id.y, z)];
if (id.y + 1 < N)
qTop = X[index(id.x, id.y + 1, z)];
if (id.y > 0)
qBottom = X[index(id.x, id.y - 1, z)];
float3 newValue = (q0C + A * (qRight + qLeft + qTop + qBottom)) * cRecip;
Solution[index(id.x, id.y, z)] = newValue;
X[index(id.x, id.y, z)] = newValue;
}
}
I tried to switch between the data in the C# script (I am using Unity) but that led to a bottleneck because of dispatching the shader #iterations times.
Mohamad T Shehab is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.