Optimizing the reaction-diffusion algorithm in Monogame C#

33 Views Asked by At

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.

0

There are 0 best solutions below