Voronoi Heightmap Generator

Posted By: oliver2s

Voronoi Heightmap Generator - 12/09/13 21:10

Script to create Voronoi Heightmaps. These are used to create realistic terrain erosion heightmaps (in combination with Perlin Noise or Diamond Square)

Code:
//Voronoi Heightmap Generator
//recommended default values:
// size_ 			= 512
// points_			= 32
var* voronoi_map_tmp_pixels=NULL;
var* voronoi_map_tmp_points=NULL;
///////////////////////////////
BMAP* voronoi_map(double size_,var points_)
{
	//create data
	voronoi_map_tmp_pixels=(var*)sys_malloc(sizeof(var) * size_*size_);
	voronoi_map_tmp_points=(var*)sys_malloc(sizeof(var) * points_*2);
	
	//create random points
	int i; for(i=0;i<points_;i++)
	{
		voronoi_map_tmp_points[i*2+0]=integer(random(size_));//px
		voronoi_map_tmp_points[i*2+1]=integer(random(size_));//py
	}
	
	//fill empty pixels
	var pmax=0;
	int py; for(py=0;py<size_;py++)
	{
		int px; for(px=0;px<size_;px++)
		{
			var fmax=999999;
			var closest_p=fmax;
			var second_closest_p=fmax;
			
			int i; for(i=0;i<points_;i++)
			{
				VECTOR vec_from_,vec_to_;
				vec_set(vec_from_,vector(px,py,0));
				vec_set(vec_to_,vector(voronoi_map_tmp_points[i*2+0],voronoi_map_tmp_points[i*2+1],0));
				var distance=vec_dist(vec_from_,vec_to_);
				
				if(distance<closest_p)
				{
					second_closest_p=closest_p;
					closest_p=distance;
				}
				else if(distance<second_closest_p)
				{
					second_closest_p=distance;
				}
			}
			
			var c1=1;
			var c2=-1;
			var d1=255-closest_p;
			var d2=255-second_closest_p;
			
			voronoi_map_tmp_pixels[px*size_+py]=c1*d1 + c2*d2;
			
			//find brightest pixel to prepare normalizing
			if(voronoi_map_tmp_pixels[px*size_+py]>pmax){pmax=voronoi_map_tmp_pixels[px*size_+py];}
		}
	}
	
	//normalize heightmap (range 0-255)
	if(pmax!=0)
	{
		var factor=255/pmax;
		int py; for(py=0;py<size_;py++)
		{
			int px; for(px=0;px<size_;px++)
			{
				voronoi_map_tmp_pixels[px*size_+py]*=factor;
				voronoi_map_tmp_pixels[px*size_+py]=clamp(integer(voronoi_map_tmp_pixels[px*size_+py]),0,255);
			}
		}
	}

	//create bmap
	BMAP* bmp_tmp=bmap_createblack(size_,size_,24);
	
	//fill bmap
	int py; for(py=0;py<size_;py++)
	{
		int px; for(px=0;px<size_;px++)
		{
			//get heightmap color
			var grey=voronoi_map_tmp_pixels[px*size_+py];
			
			VECTOR bmp_color_;
			bmp_color_.x=grey;
			bmp_color_.y=grey;
			bmp_color_.z=grey;
			
			//add to heightmap
			var format=bmap_lock(bmp_tmp,0);
			var pixel=pixel_for_vec(bmp_color_,100,format);
			pixel_to_bmap(bmp_tmp, px, py, pixel);
			bmap_unlock(bmp_tmp);
		}
	}
	
	//free pixels and bmaps
	sys_free(voronoi_map_tmp_pixels);
	sys_free(voronoi_map_tmp_points);
	
	return bmp_tmp;
}



Example:
Code:
void main()
{
	video_mode=9;
	
	wait(1);
	
	BMAP* bmp=voronoi_map(512,32);
	
	while(1)
	{
		DEBUG_BMAP(bmp,0,1);
		
		wait(1);
	}
}



Further reading:
http://oddlabs.com/download/terrain_generation.pdf

Posted By: sivan

Re: Voronoi Heightmap Generator - 12/09/13 22:09

many thanks! it seems to be best to start with the article.
Posted By: oliver2s

Re: Voronoi Heightmap Generator - 12/10/13 09:22

Yes, today I will try to go further with the article and erosion heightmaps.
Posted By: Helghast

Re: Voronoi Heightmap Generator - 12/20/13 07:54

This is funny, I actually had been working on exactly this over the last week too! (not in GS though).
I ended up creating fBM and layering that over the voronoi heightmaps (I used worley noise though instead) to get the erosion effect.
That link you posted looks way better though, will definitely attempt that next!

Link to fBM algorithm: http://code.google.com/p/fractalterraingeneration/wiki/Fractional_Brownian_Motion
Posted By: oliver2s

Re: Voronoi Heightmap Generator - 12/20/13 15:40

Never heard of fBM. Thanks for information and link.
Posted By: oliver2s

Re: Voronoi Heightmap Generator - 01/15/14 12:47

I've updated the code because of a bug: if there where too many height points, the chance that the script crashes was high, because of division by zero. Fixed it.
© 2024 lite-C Forums