Gamestudio Links
Zorro Links
Newest Posts
Trading Journey
by howardR. 04/24/24 20:04
M1 Oversampling
by Petra. 04/24/24 10:34
Zorro FIX plugin - Experimental
by flink. 04/21/24 07:12
Data from CSV not parsed correctly
by EternallyCurious. 04/20/24 21:39
Scripts not found
by juergen_wue. 04/20/24 18:51
zorro 64bit command line support
by 7th_zorro. 04/20/24 10:06
StartWeek not working as it should
by jcl. 04/20/24 08:38
folder management functions
by VoroneTZ. 04/17/24 06:52
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (Ayumi, AndrewAMD), 770 guests, and 4 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Mega_Rod, EternallyCurious, howardR, 11honza11, ccorrea
19048 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Thermal Erosion Heightmap Filter #434011
12/10/13 18:47
12/10/13 18:47
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
This code simulates thermal erosion on a greyscaled heightmap. Algorithm is taken from this paper: http://oddlabs.com/download/terrain_generation.pdf



Code:
//Heightmap Normalizing (range 0-255)
void bmap_normalize(BMAP* bmap_)
{
	var size_x_=bmap_width(bmap_);
	var size_y_=bmap_height(bmap_);
	
	var pmax=0;
	
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			COLOR color_;
			var format=bmap_lock(bmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_, px, py);
			pixel_to_vec(color_,alpha_,format,pixel);
			bmap_unlock(bmap_);
			
			//find brightest pixel to prepare normalizing
			if(color_.red>pmax){pmax=color_.red;}
		}
	}

	//normalize heightmap (range 0-255)
	var factor=255/pmax;
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			COLOR color_;
			var format=bmap_lock(bmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_, px, py);
			pixel_to_vec(color_,alpha_,format,pixel);
			bmap_unlock(bmap_);
			
			color_.red*=factor;
			color_.green*=factor;
			color_.blue*=factor;
			
			color_.red=clamp(integer(color_.red),0,255);
			color_.green=clamp(integer(color_.green),0,255);
			color_.blue=clamp(integer(color_.blue),0,255);
			
			var format=bmap_lock(bmap_,0);
			var pixel=pixel_for_vec(color_,100,format);
			pixel_to_bmap(bmap_, px, py, pixel);
			bmap_unlock(bmap_);
		}
	}
}

//Thermal Erosion Filter
//recommended default values:
//iterations_ 		= 50
//threshold_		= 3
//coefficient_		= 0.5
var* thermal_erosion_tmp=NULL;
///////////////////////////////
void bmap_thermal_erosion_filter(BMAP* bmap_,var iterations_,var threshold_,var coefficient_)
{
	//normalize heightmap
	bmap_normalize(bmap_);
	
	//get size
	double size_x_=bmap_width(bmap_);
	double size_y_=bmap_height(bmap_);
	
	//create data
	thermal_erosion_tmp=(var*)sys_malloc(sizeof(var) * size_x_*size_y_);
	
	//fill data with pixel color
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			COLOR color_;
			var format=bmap_lock(bmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_, px, py);
			pixel_to_vec(color_,alpha_,format,pixel);
			bmap_unlock(bmap_);
			
			thermal_erosion_tmp[px*size_x_+py]=color_.red;
		}
	}
	
	int i; for(i=0;i<iterations_;i++)
	{
		int py; for(py=0;py<size_y_;py++)
		{
			int px; for(px=0;px<size_x_;px++)
			{
				var h_=thermal_erosion_tmp[px*size_x_+py];
				
				var d[4]; COLOR color_tmp_; var h[4];
				
				h[0]=thermal_erosion_tmp[clamp(px-1,0,size_x_-1)*size_x_+clamp(py,0,size_y_-1)];
				d[0]=h_-h[0];

				h[1]=thermal_erosion_tmp[clamp(px,0,size_x_-1)*size_x_+clamp(py-1,0,size_y_-1)];
				d[1]=h_-h[1];

				h[2]=thermal_erosion_tmp[clamp(px+1,0,size_x_-1)*size_x_+clamp(py,0,size_y_-1)];
				d[2]=h_-h[2];

				h[3]=thermal_erosion_tmp[clamp(px,0,size_x_-1)*size_x_+clamp(py+1,0,size_y_-1)];
				d[3]=h_-h[3];

				var dtotal=0,dmax=-9999;
				int j; for(j=0;j<4;j++)
				{
					if(d[j]>threshold_)
					{
						dtotal=dtotal+d[j];
						if(d[j]>dmax)
						{
							dmax=d[j];
						}
					}
				}
				
				int j; for(j=0;j<4;j++)
				{
					if(dtotal!=0)
					{
						h[j]=h[j] + coefficient_*(dmax - threshold_) * (d[j]/dtotal);
					}
				}
				
				thermal_erosion_tmp[clamp(px-1,0,size_x_-1)*size_x_+clamp(py,0,size_y_-1)]=h[0];
				thermal_erosion_tmp[clamp(px,0,size_x_-1)*size_x_+clamp(py-1,0,size_y_-1)]=h[1];
				thermal_erosion_tmp[clamp(px+1,0,size_x_-1)*size_x_+clamp(py,0,size_y_-1)]=h[2];
				thermal_erosion_tmp[clamp(px,0,size_x_-1)*size_x_+clamp(py+1,0,size_y_-1)]=h[3];
			}
		}
	}
	
	//fill pixels with array data
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			//set colors
			COLOR bmp_color_;
			bmp_color_.red=thermal_erosion_tmp[px*size_x_+py];
			bmp_color_.green=thermal_erosion_tmp[px*size_x_+py];
			bmp_color_.blue=thermal_erosion_tmp[px*size_x_+py];
			
			//add to heightmap
			var format=bmap_lock(bmap_,0);
			var pixel=pixel_for_vec(bmp_color_,100,format);
			pixel_to_bmap(bmap_, px, py, pixel);
			bmap_unlock(bmap_);
		}
	}
	
	//free data
	sys_free(thermal_erosion_tmp);
}


Re: Thermal Erosion Heightmap Filter [Re: oliver2s] #434013
12/10/13 19:29
12/10/13 19:29
Joined: Mar 2011
Posts: 3,150
Budapest
sivan Offline
Expert
sivan  Offline
Expert

Joined: Mar 2011
Posts: 3,150
Budapest
crazy development speed. what's next? grin tongue


Free world editor for 3D Gamestudio: MapBuilder Editor
Re: Thermal Erosion Heightmap Filter [Re: sivan] #434014
12/10/13 19:33
12/10/13 19:33
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Next thing in the paper is Hydraulic Erosion.

Re: Thermal Erosion Heightmap Filter [Re: oliver2s] #434031
12/11/13 07:20
12/11/13 07:20
Joined: Jan 2006
Posts: 968
EpsiloN Offline
User
EpsiloN  Offline
User

Joined: Jan 2006
Posts: 968
I dont understand what this all is... laugh

The codes generate a heightmap for you, and then smooth/randomize and change it so that it looks more like a natural terrain? Or you have to supply it with a heightmap, and it'll clean it?


Extensive Multiplayer tutorial:
http://mesetts.com/index.php?page=201
Re: Thermal Erosion Heightmap Filter [Re: EpsiloN] #434034
12/11/13 08:36
12/11/13 08:36
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
For the code in this thread you need an existing heightmap. Then the code simulates thermal erosion on this heightmap. Thermal erosion simulates material braking loose and sliding down slopes to pile up at the bottom.

Re: Thermal Erosion Heightmap Filter [Re: oliver2s] #434035
12/11/13 08:51
12/11/13 08:51
Joined: Jan 2006
Posts: 968
EpsiloN Offline
User
EpsiloN  Offline
User

Joined: Jan 2006
Posts: 968
But , all the methods can be combined into one, right? With a generator for heightmap?


Extensive Multiplayer tutorial:
http://mesetts.com/index.php?page=201
Re: Thermal Erosion Heightmap Filter [Re: EpsiloN] #434037
12/11/13 08:57
12/11/13 08:57
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Yes, right. First you generate two heightmaps, one with Perlin Noise algorithm, one with Voronoi algorithm. Then you lerp both togehter with 2/3 Perlin Noise and 1/3 Voronoi. After that you're running 3 different filters/algorithms over the heightmap in following order: perturbation filter, thermal erosion, hydraulic erosion.

Re: Thermal Erosion Heightmap Filter [Re: oliver2s] #434038
12/11/13 09:05
12/11/13 09:05
Joined: Jan 2006
Posts: 968
EpsiloN Offline
User
EpsiloN  Offline
User

Joined: Jan 2006
Posts: 968
Then, this is amazing laugh

Final question tongue
How do you lerp them together? You read the color codes and get a value between both heightmaps?


Extensive Multiplayer tutorial:
http://mesetts.com/index.php?page=201
Re: Thermal Erosion Heightmap Filter [Re: EpsiloN] #434040
12/11/13 09:16
12/11/13 09:16
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Originally Posted By: EpsiloN
How do you lerp them together? You read the color codes and get a value between both heightmaps?


Yes, read color of both pixels and lerp with 0.333 and 0.666:

Code:
finalColor.red = perlinNoiseColor.red*0.666 + voronoiColor.red*0.333;
finalColor.green = perlinNoiseColor.green*0.666 + voronoiColor.green*0.333;
finalColor.blue = perlinNoiseColor.blue*0.666 + voronoiColor.blue*0.333;



Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1