0

I'm trying to find a faster implementation of a flood fill algorithm for a program I'm making using C# in Unity 2020.

This is my current method, which in my program takes about 400ms to run on a 1000 x 1000 map. Instead of a target colour to replace, I am using a height map (called noiseMap in this code snippet) and all values above a threshold should be considered inside the flooded area.

    public void Flood()
    {
        landMasses.Clear();
        globalSet.Clear();
        HashSet<Vector2Int> samples = new HashSet<Vector2Int>();

        for (int x = 0; x < mapGen.mapSize; x += mapGen.scanStride)
        {
            for (int y = 0; y < mapGen.mapSize; y += mapGen.scanStride)
            {
                samples.Add(new Vector2Int(x, y));
            }
        }

        float[,] noiseMap = mapGen.noiseMap;
        int mapSize = mapGen.mapSize;
        float threshold = mapGen.threshold;
        foreach (var sample in samples)
        {
            CalculateSets(sample, noiseMap, mapSize, threshold);
        }
    }



    public bool Inside(Vector2Int point)
    {
        return Inside(point.x, point.y);
    }

    public bool Inside(int x, int y)
    {
        if (x < mapGen.mapSize && x >= 0 && y < mapGen.mapSize && y >= 0)
        {
            return mapGen.noiseMap[x, y] > mapGen.threshold;
        }
        return false;
    }



    public void CalculateSets(Vector2Int sample, float[,] noiseMap, int mapSize, float threshold)
    {
        if (globalSet.Contains(sample) || noiseMap[sample.x, sample.y] < threshold)
        {
            return;
        }
        HashSet<Vector2Int> set = new HashSet<Vector2Int>();
        Queue<Vector2Int> queue = new Queue<Vector2Int>();
        queue.Enqueue(sample);
        while (queue.Count > 0)
        {
            Vector2Int n = queue.Dequeue();
            if (set.Contains(n))
            {
                continue;
            }

            if(Inside(n))
            {
                set.Add(n);
                globalSet.Add(n);
                queue.Enqueue(new Vector2Int(n.x, n.y - 1));
                queue.Enqueue(new Vector2Int(n.x, n.y + 1));
                queue.Enqueue(new Vector2Int(n.x - 1, n.y));
                queue.Enqueue(new Vector2Int(n.x + 1, n.y));
            }
        }
        landMasses.Add(landMasses.Count.ToString(), set);
    }

I've looked around at places like Wikipedia and other online forums for an implementation of the scan line flood fill, but every implementation I find has very little documentation to go along with it, or has no definitions of what their variable names represent. Regardless of this, I have tried to decipher these other implementations and have had 0 luck.

For example, on the Floodfill Wikipedia Page, there are a few different methods along with pseudocode to go along with it - but I cannot find definitions for what most of the variables mean in the later methods which are supposedly faster. Perhaps it's simple, but as someone overall new to computing algorithms I am struggling to figure it out.

So at the end of all this, I am essentially just looking for a faster way to implement something like a floodfill algorithm than what I currently have. It doesn't need to exactly fit into my program of course, even just a general C# implementation or more clarified pseudocode example with comments will be a great help.

Thank you for reading!!

Vallith
  • 1
  • 2
  • see `[Edit2]` in [Paint algorithm leaving white pixels at the edges when I color](https://stackoverflow.com/a/37810355/2521214) – Spektre Aug 04 '22 at 07:22
  • if your goal is find out "all" flooded area. you don't need use Floodfill algorithm , just foreach all point for once. – TimChang Aug 04 '22 at 08:03
  • Thanks @TimChang, I honestly don't know why I didn't think of this. I think I just assumed it would be slower than a floodfill - but you're entirely right. – Vallith Aug 05 '22 at 01:39
  • Maybe you just want show some effect , just for watch not a about logic , maybe just write it in fragment Shader code , GPU it's very quickly than CPU – TimChang Aug 05 '22 at 02:23

0 Answers0