public float[,] ErodeTerrain(float[,] heightMap, int seed)
    {
        rng = new System.Random(seed);

        erosionInfo = InitializeErosionInfo();

        erosionBrush    = InitializeErosionBrush(heightMap);
        depositionBrush = InitializeDepositionBrush(heightMap);

        for (int i = 0; i < settings.iterations; i++)
        {
            Droplet droplet = new Droplet(heightMap, erosionInfo, erosionBrush, depositionBrush);
            droplet.Update();
        }

        return(heightMap);
    }
        public Droplet(float[,] map, ErosionInfo info, ErosionBrush eBrush, DepositionBrush dBrush)
        {
            heightMap       = map;
            erosionInfo     = info;
            erosionBrush    = eBrush;
            depositionBrush = dBrush;

            mapWidth  = heightMap.GetLength(0);
            mapHeight = heightMap.GetLength(1);

            position = new Vector2(
                erosionInfo.rng.Next(0, mapWidth - 1),
                erosionInfo.rng.Next(0, mapHeight - 1)
                );

            direction = new Vector2(0f, 0f).normalized;
        }
    ErosionBrush InitializeErosionBrush(float[,] heightMap)
    {
        int width  = heightMap.GetLength(0);
        int height = heightMap.GetLength(1);

        ErosionBrush erosionBrush = new ErosionBrush(width, height);

        Vector2 position = new Vector2();
        Vector2 v        = new Vector2();

        float[] xOffsets = new float[(int)settings.erosionRadius * (int)settings.erosionRadius * 4];
        float[] yOffsets = new float[(int)settings.erosionRadius * (int)settings.erosionRadius * 4];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (x < 0 || x >= width || y < 0 || y >= height)
                {
                    continue;
                }

                int index = 0;

                position.x = x;
                position.y = y;

                float weightSum   = 0f;
                int   numVertices = 0;
                for (int i = -(int)settings.erosionRadius; i <= settings.erosionRadius; i++)
                {
                    int xCoord = x + i;
                    for (int j = -(int)settings.erosionRadius; j <= settings.erosionRadius; j++)
                    {
                        int yCoord = y + j;

                        v.x = xCoord;
                        v.y = yCoord;

                        if (xCoord < 0 || xCoord >= width || yCoord < 0 || yCoord >= height)
                        {
                            continue;
                        }

                        if ((v - position).magnitude <= settings.erosionRadius)
                        {
                            weightSum += Mathf.Max(0f, settings.erosionRadius - (v - position).magnitude);
                            numVertices++;

                            xOffsets[index] = i;
                            yOffsets[index] = j;

                            index++;
                        }
                    }
                }

                erosionBrush.erosionBrushWeights[y * width + x]  = new float[numVertices];
                erosionBrush.erosionBrushVertices[y * width + x] = new float[numVertices];

                for (int n = 0; n < numVertices; n++)
                {
                    v.x = x + xOffsets[n];
                    v.y = y + yOffsets[n];

                    float weight = Mathf.Max(0, settings.erosionRadius - (v - position).magnitude) / weightSum;
                    erosionBrush.erosionBrushVertices[y * width + x][n] = v.y * width + v.x;
                    erosionBrush.erosionBrushWeights[y * width + x][n]  = weight;
                }
            }
        }

        return(erosionBrush);
    }