ThomasPixel

Floodfilling Voronoi Noise Bugs

Apr 21st, 2023
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.24 KB | None | 0 0
  1.     /// <summary>
  2.     /// Generates a grayscale image from Voronoi noise, simulating district zones
  3.     /// </summary>
  4.     private void GenerateDistrctsMap()
  5.     {
  6.         // private texture2d
  7.         districtMap = new Texture2D(gridWidth, gridWidth);
  8.         Color[] pix = new Color[gridWidth * gridWidth];
  9.  
  10.         // private int
  11.         seed = UnityEngine.Random.Range(0, 1000);
  12.  
  13.         // From a custom Voronoi class
  14.         VoronoiNoise Voronoi = new VoronoiNoise(seed, frequency, amp);
  15.  
  16.         // Grid width atm is 60
  17.         float[,] arr = new float[gridWidth, gridWidth];
  18.  
  19.         //Sample the 2D noise and add it into a array.
  20.         for (int y = 0; y < gridWidth; y++)
  21.         {
  22.             for (int x = 0; x < gridWidth; x++)
  23.             {
  24.                 float fx = x / (gridWidth - 1.0f);
  25.                 float fy = y / (gridWidth - 1.0f);
  26.  
  27.                 arr[x, y] = Voronoi.Sample2D(fx, fy);
  28.             }
  29.         }
  30.  
  31.         for (int y = 0; y < gridWidth; y++)
  32.         {
  33.             for (int x = 0; x < gridWidth; x++)
  34.             {
  35.                 float n = arr[x, y];
  36.                 districtMap.SetPixel(x, y, new Color(n, n, n, 1));
  37.             }
  38.         }
  39.  
  40.         districtMap.Apply();
  41.  
  42.         // districtBorderMap is a RawImage UI element
  43.         Texture2D districtMapCopy = districtMap;
  44.         districtBorderMap.texture = districtMapCopy;
  45.     }
  46.  
  47.     /// <summary>
  48.     /// Floodfills district zones from districtMap, uses borderThreshold for checking greyscale values on Voronoi borders.
  49.     /// </summary>
  50.     private void FloodfillDistricts()
  51.     {
  52.         int width = districtMap.width;
  53.         int height = districtMap.height;
  54.  
  55.         Color[] colors = new Color[] { Color.yellow, Color.blue, Color.green };
  56.         List<Color> usedColors = new List<Color>();
  57.  
  58.         // Loop over each pixel in the districts map
  59.         for (int y = 0; y < height; y++)
  60.         {
  61.             for (int x = 0; x < width; x++)
  62.             {
  63.                 Color pixelColor = districtMap.GetPixel(x, y);
  64.  
  65.                 // If the pixel is white (above threshold) and hasn't been colored yet, floodfill it with a random color
  66.                 if (pixelColor.grayscale > borderThreshold && !usedColors.Contains(pixelColor))
  67.                 {
  68.                     Color fillColor = colors[Random.Range(0, colors.Length)];
  69.                     FloodfillBlob(x, y, pixelColor, fillColor, ref usedColors);
  70.                 }
  71.             }
  72.         }
  73.  
  74.         districtMap.Apply();
  75.         districtColorMap.texture = districtMap;
  76.     }
  77.  
  78.     /// <summary>
  79.     /// Performs a floodfill on the current Voronoi blob. Blob defined as a white-ish space surrounding by black-ish borders
  80.     /// </summary>
  81.     /// <param name="x"></param>
  82.     /// <param name="y"></param>
  83.     /// <param name="targetColor"></param>
  84.     /// <param name="fillColor"></param>
  85.     /// <param name="usedColors"></param>
  86.     private void FloodfillBlob(int x, int y, Color targetColor, Color fillColor, ref List<Color> usedColors)
  87.     {
  88.         int width = districtMap.width;
  89.         int height = districtMap.height;
  90.  
  91.         Queue<Vector2Int> pixelsToCheck = new Queue<Vector2Int>();
  92.         pixelsToCheck.Enqueue(new Vector2Int(x, y));
  93.  
  94.         while (pixelsToCheck.Count > 0)
  95.         {
  96.             Vector2Int pixel = pixelsToCheck.Dequeue();
  97.             int px = pixel.x;
  98.             int py = pixel.y;
  99.  
  100.             // Check if the pixel is within bounds and has the target color
  101.             if (px >= 0 && px < width && py >= 0 && py < height && districtMap.GetPixel(px, py) == targetColor)
  102.             {
  103.                 // Set the pixel to the fill color and add it to the list of used colors
  104.                 districtMap.SetPixel(px, py, fillColor);
  105.                 if (!usedColors.Contains(fillColor))
  106.                 {
  107.                     usedColors.Add(fillColor);
  108.                 }
  109.  
  110.                 // Add neighboring pixels to the queue to be checked
  111.                 pixelsToCheck.Enqueue(new Vector2Int(px - 1, py));
  112.                 pixelsToCheck.Enqueue(new Vector2Int(px + 1, py));
  113.                 pixelsToCheck.Enqueue(new Vector2Int(px, py - 1));
  114.                 pixelsToCheck.Enqueue(new Vector2Int(px, py + 1));
  115.             }
  116.         }
  117.     }
Advertisement
Add Comment
Please, Sign In to add comment