Trying to "store" a perlin noise region and convert it to an island.

So in the picture you can see that I change the perlin noise to only generate values above 0.6f.
I want to store the data of one of those “regions” and later convert into a 3D island.

My problem lies in HOW I can store this region??

I have a recursive method that will find a pixel with value >= 0.6f.
Now that I’m “inside” the region, I do not know how to store this region data?

I’m thinking like going fully deep into the alice in wonderland rabbit hole and do a recursive function that explores all ends of the pixels >= 0.6 but idk if my willpower can take that powerlevel.

Halp.
Storing this region.

You do it by FloodFill algorithm.
You can do it directly on PerlinNoise texture, no need to do the divide pass.
You start with first pixel on an image. If it’s value is smaller than 0.6f you skip it and go to the next pixel.
If it’s greater than 0.6f you add this pixel to the list<(x,y,value)> of current region, set this pixel value to 0 and repeat the process for all neighbours (it may be recursive algorithm). When region is finished you create new list for new region ,check the next pixels for valid pixels and repeat the process.
Algorithm ends when you get to the final pixel.
You can store regions for example in ScriptableObject or as an image asset.

I have done a similar thing with classification of clouds in satellite images. And I used recursive floodfill back then. But today I would suggest you skip recursion and use an iterative aproach instead. As koirat already suggested, work on the noise texture/array directly but you need a data structure to store the “index” of your islands. This can be done in a separate int/byte array with the same dimension or (preferably?) with a custom struct which contains the index and the noise value. You then just have an array of that struct. Then you just iterate over all pixels. If a pixel fulfills your condition (fe > 0.6) you check all 8 surrounding pixels if they have been assigned a proper index already (fe -1 is uninitialized). If so you assign the same index to the pixel you are currently evaluating. If not you assign a new index (fe last index +1). When you do this you should have an array with the indices of the separate islands.

This can be optimized by just looking at pixels you have already visited (lie “behind” the one currently evaluated). So if you iterate from top left to bottom right just check the 3 above and the one before. This does not work with recursion since the order is not defined there.
Another optimization would be, to generate a custom data structure for every new “island” (index) which stores things like min / max x / y, number of pixels (size) etc. . So for every valid pixel you check in a list of this data structure where the index is used, if min/max values must be adjusted. Increment the size etc.
Another consideration may be, wether you want to allow islands crossing the border, since they appear "cut off. If not you can also check if a valid pixel is on the border and assign another “invalid” index to it (fe -99). Then you propagate this index to all pixels connected but you don’t create a data structure for that. This way you only have “valid” islands which are completely surrounded by sea.

Doing it this way you only need to iterate once over every pixel and still get what you need and the bounding box.

So I try to make this in untested pseudocode.

struct Pixel
{
 float noisevalue;
 int islandindex = -1;
}

class IslandManager
{
 array<Pixel>[,] pixels;   // fill the noise values accordingly

void Analyse()
{
 currentislandindex = -1;
 for(y)
 {
  for(x)
  {
    if(pixels[x,y].noisevalue > 0.6)
    {
     if(pixels[x-1,y-1].islandindex > -1)   // check for valid boundaries too! left out for simplicity
       pixels[x,y].islandindex = pixels[x-1,y-1].islandindex
     else if(pixels[x,y-1].islandindex > -1)
       pixels[x,y].islandindex = pixels[x,y-1].islandindex
     else if(pixels[x+1,y-1].islandindex > -1)
       pixels[x,y].islandindex = pixels[x+1,y-1].islandindex
     else if(pixels[x-1,y].islandindex > -1)
       pixels[x,y].islandindex = pixels[x-1,y].islandindex
     else // neighbouring pixels don#t belong to an island so create a new one
       pixels[x,y].islandindex = ++currentislandindex;

     // check additional properties here, fe min/max, fill a list with an additional structure for each island/new index
    }
  }
 }
}

}

I hope this makes some sense. It’s hard to explain for me (non native english speaker). If you have questions just ask.

Here’s the code of what I ended up doing. Thanks to the 2 replies! Gave me options to think about. Anywho’ I grabbed a random point inside a region. Then flood filled the hell outta it. With the data stored I could generate a texture of the island region.

THANKS AGAIN!

1 Like