Hello there!
I’ve been dabbling in procedural world generation for a little while now, and I’ve gotten a decent understanding of some parts. I can create height maps, temperature and moisture maps.
It seems usually people generate biomes based on various factors, eg. temperature and moisture maps.
Now what I want to do is to generate a heightmap, then add biomes, and then modify each biome based on whatever parameters I come up with.
So… to the point - I was looking into the Voronoi diagram and implemented that. My problem is, I have a hard time understanding how I implement this for an infinite world. For a heightmap, I can simply offset it by whatever distance on the x/y axis, and all is good (And deterministic based on seed, which is important)
What I’ve gathered so far during my research is this:
When generating the Voronoi diagram for a chunk, you take the eight adjacent chunks into account. Now as I’m writing this, my understanding seems to become a bit better, but I’m still not entirely sure exactly how to do this. I guess this means, assuming chunk 1 - 9 where 5 is the center chunk; if I generate my Voronoi diagram for chunk 5, then if I do the same approach for, say chunk 4 (Left of 5), then it will seamlessly fit together with chunk 5? Is this assumption correct?
Assuming I’m correct in my sudden mid-text epiphany; I’m not really sure how to take the adjacent chunks into account when generating the Voronoi.
My current implementation looks like this:
public static Color[] GenerateVoronoidDiagram(int width, int height, int numberOfRegions)
{
var centroids = new Vector2Int[numberOfRegions];
var regions = new Color[numberOfRegions];
for (int i = 0; i < numberOfRegions; i++)
{
centroids *= new Vector2Int(_rand.Next(0, width), _rand.Next(0, height));*
regions = new Color((float)_rand.NextDouble(), (float)_rand.NextDouble(), (float)_rand.NextDouble());
}
var colorDiagram = new Color[width * height];
for (int y = 0; y < width; y++)
{
for (int x = 0; x < height; x++)
{
colorDiagram[y * height + x] = regions[GetClosestCentroidIndex(new Vector2Int(x, y), centroids)];
}
}
return colorDiagram;
}
private static int GetClosestCentroidIndex(Vector2Int pixelPos, Vector2Int[] centroids)
{
var smallestDstSqr = float.MaxValue;
var index = 0;
for (int i = 0; i < centroids.Length; i++)
{
var distanceSqr = (pixelPos - centroids*).sqrMagnitude;*
if (distanceSqr < smallestDstSqr)
{
smallestDstSqr = distanceSqr;
index = i;
}
}
return index;
}
What I’m struggling with is how do I take the other chunks into account?
Simply multiplying width and height with 3 (3*3=9 chunks) and multiplying numberOfRegions with 9, will just result in the exact same generation, no matter where I generate it.
Initially I thought I could simply offset the centroids by width and height multiplied by the chunks x and y coordinate respectively, but that did not give me the desired result.
Sorry for the wall of text, but wanted to include as much of the info I gathered as possible, and to clarify what I do not understand. - Any help is greatly appreciated ![]()