I've implemented the reaction-diffusion algorithm following Karl Sims' tutorial. It is working fine but I'm only getting 10 fps on a 600x600 grid which seems excessively low and makes it unusable for my application. How can I speed up my implementation or am I unintentionally misusing Monogames mechanisms?
This is my update-function, _a and _b are arrays containing the chemical concentrations.
public void Update()
{
for (int x = 1; x < N-1; x++)
{
for (int y = 1; y < M-1; y++)
{
float a = _a[Index(x, y)];
float b = _b[Index(x, y)];
_bufferA[Index(x, y)] = a + DT * (DA * laplacian(x, y, _a) - a * b * b + Feed * (1 - a));
_bufferB[Index(x, y)] = b + DT * (DB * laplacian(x, y, _b) + a * b * b - (Kill + Feed) * b);
}
}
// Update the grid to the new values.
(_a, _bufferA) = (_bufferA, _a);
(_b, _bufferB) = (_bufferB, _b);
}
// Convolution that calculates the difference between chemical concentrations of neighbouring cells.
private float laplacian(int x, int y, float[] arr)
{
float sum = 0;
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
switch (Math.Abs(i) + Math.Abs(j))
{
case 0: sum += -1 * arr[Index(x, y)]; break;
case 1: sum += 0.2f * arr[Index(x + i, y + j)]; break;
case 2: sum += 0.05f * arr[Index(x + i, y + j)]; break;
}
return sum;
}
And this is how I draw it, I just pass a Texture2D to my class, modify it in there and draw it in the Game.Draw() function.
public void Draw(Texture2D canvas)
{
Color[] data = new Color[Const.Width * Const.Height];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
data[i + j * N] = new Color((int)(255 * _a[Index(i, j)]), 0, (int)(255 * _b[Index(i, j)]));
}
}
canvas.SetData(data);
}
I would greatly appreciate any suggestions.