Gamestudio Links
Zorro Links
Newest Posts
Trading Journey
by howardR. 04/28/24 09:55
basik85278
by basik85278. 04/28/24 08:56
Zorro Trader GPT
by TipmyPip. 04/27/24 13:50
Help with plotting multiple ZigZag
by M_D. 04/26/24 20:03
Data from CSV not parsed correctly
by jcl. 04/26/24 11:18
M1 Oversampling
by jcl. 04/26/24 11:12
Why Zorro supports up to 72 cores?
by jcl. 04/26/24 11:09
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (Quad, AndrewAMD), 722 guests, and 6 spiders.
Key: Admin, Global Mod, Mod
Newest Members
wandaluciaia, Mega_Rod, EternallyCurious, howardR, 11honza11
19049 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
Slope Blendmap Generator #434076
12/11/13 19:43
12/11/13 19:43
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
This code generates a blendmap out of a given heightmap. The angles which defines a slope (between 0-90 degrees) can be adjusted via function parameter.



Code:
BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_);

//Make Blendmap from Heightmap on slopes
///////////////////////////////
// bmap_hmap_			-> heightmap
// bmap_blendmap_		-> blendmap which will be painted or NULL for creating new blendmap
// color_			-> color which will be painted in blendmap on slopes
// gradientMin_			-> angle of slopes where painting should begin (range 0-90)
// gradientMax_			-> angle of slopes where painting should stop (range 0-90)
///////////////////////////////
BMAP* bmap_heightmap_to_blendmap_slopes(BMAP* bmap_hmap_,BMAP* bmap_blmap_,COLOR* color_,var gradientMin_,var gradientMax_)
{
	//clear up gradients
	var gradient_min_=gradientMin_;
	var gradient_max_=gradientMax_;
	if(gradient_max_<gradient_min_)
	{
		gradient_max_=gradientMin_;
		gradient_min_=gradientMax_;
	}
	gradient_min_=clamp(gradient_min_,0,90);
	gradient_max_=clamp(gradient_max_,0,90);
	if(gradient_min_==gradient_max_){ return NULL; }
	
	//store color
	COLOR c1_;
	c1_.red=color_.red;
	c1_.green=color_.green;
	c1_.blue=color_.blue;
	
	//get size
	var size_x_=bmap_width(bmap_hmap_);
	var size_y_=bmap_height(bmap_hmap_);
	
	//create tmp normalmap bmap
	BMAP* normalmap_=bmap_heightmap_to_normalmap(bmap_hmap_,NULL,1);
	
	//create temp bitmap for blendmap
	BMAP* blendmap_=bmap_createblack(size_x_,size_y_,24);

	//search slopes within the given range on normalmap
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			//get normalmap pixel
			COLOR c_;
			var format=bmap_lock(normalmap_,0);var alpha_;
			var pixel=pixel_for_bmap(normalmap_, px, py);
			pixel_to_vec(c_,alpha_,format,pixel);
			bmap_unlock(normalmap_);
			
			//convert normalmap pixel to normal vector
			VECTOR n;
			n.x = 2.0*(c_.red-128);
			n.y = 2.0*(c_.green-128);
			n.z = 2.0*(c_.blue-128);
			
			//normalize to 0-1
			vec_normalize(n,1);
			
			//get Euler angle
			var angle = 90-asinv(abs(n.z));
				
			//if angle is between given angles, paint blendmap
			if(angle>=gradient_min_ && angle<=gradient_max_)
			{
				//paint given color to blendmap
				var format=bmap_lock(blendmap_,0);
				var pixel=pixel_for_vec(c1_,100,format);
				pixel_to_bmap(blendmap_, px, py, pixel);
				bmap_unlock(blendmap_);
			}
		}
	}
	
	//remove tmp normalmap
	bmap_purge(normalmap_);
	bmap_remove(normalmap_);
	
	//return new created blendmap if no target bitmap was passed to function
	if(bmap_blmap_==NULL){return blendmap_;}
	else
	{
		//otherwise copy created blendmap to target bitmap
		bmap_blit(bmap_blmap_,blendmap_,NULL,vector(bmap_width(bmap_blmap_),bmap_height(bmap_blmap_),0));
		
		//delete temp bitmap
		bmap_purge(blendmap_);
		bmap_remove(blendmap_);
		
		//return
		return bmap_blmap_;
	}
}

BMAP* bmap_heightmap_to_normalmap(BMAP* bmap_hmap_,BMAP* bmap_nmap_,var factor_)
{		
	//get size
	var size_x_=bmap_width(bmap_hmap_);
	var size_y_=bmap_height(bmap_hmap_);
	
	BMAP* normalmap_=bmap_createblack(size_x_,size_y_,24);
	
	int py; for(py=0;py<size_y_;py++)
	{
		int px; for(px=0;px<size_x_;px++)
		{
			//get height of 3 neighbor pixels
			COLOR color_;
			var c1,c2,c3;
			var format=bmap_lock(bmap_hmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
			bmap_unlock(bmap_hmap_);

			//build temporary points that makes a triangle
			VECTOR v1,v2,p1,p2,p3;
			p1.x=0;p1.y=0;p1.z=c1*factor_;
			p2.x=32;p2.y=0;p2.z=c2*factor_;
			p3.x=0;p3.y=32;p3.z=c3*factor_;
			
			//get first vector for cross product (p2-p1)
			v1.x=p2.x-p1.x;
			v1.y=p2.y-p1.y;
			v1.z=p2.z-p1.z;
			
			//get second vector for cross product (p3-p1)
			v2.x=p3.x-p1.x;
			v2.y=p3.y-p1.y;
			v2.z=p3.z-p1.z;
			
			//calculate cross product of v1 and v2
			VECTOR n;
			vec_cross(n,v1,v2);
			
			//normalize to color range 0-255
			vec_normalize(n,255);
			
			//convert vector into normalmap color
			n.x=n.x/2 + 128;
			n.y=n.y/2 + 128;
			n.z=n.z/2 + 128;
			
			//copy color
			COLOR color1_;
			color1_.red=n.x;
			color1_.green=n.y;
			color1_.blue=n.z;
			
			//get height of another 3 neighbor pixels
			COLOR color_;
			var c1,c2,c3;
			var format=bmap_lock(bmap_hmap_,0);var alpha_;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c1=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px-1,0,size_x_), clamp(py+1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c2=color_.red;
			var pixel=pixel_for_bmap(bmap_hmap_, clamp(px+1,0,size_x_), clamp(py-1,0,size_y_));
			pixel_to_vec(color_,alpha_,format,pixel); c3=color_.red;
			bmap_unlock(bmap_hmap_);

			//build temporary points that makes a triangle
			VECTOR v1,v2,p1,p2,p3;
			p1.x=32;p1.y=32;p1.z=c1*factor_;
			p2.x=0;p2.y=32;p2.z=c2*factor_;
			p3.x=32;p3.y=0;p3.z=c3*factor_;
			
			//get first vector for cross product (p2-p1)
			v1.x=p2.x-p1.x;
			v1.y=p2.y-p1.y;
			v1.z=p2.z-p1.z;
			
			//get second vector for cross product (p3-p1)
			v2.x=p3.x-p1.x;
			v2.y=p3.y-p1.y;
			v2.z=p3.z-p1.z;
			
			//calculate cross product of v1 and v2
			VECTOR n;
			vec_cross(n,v1,v2);
			
			//normalize to color range 0-255
			vec_normalize(n,255);
			
			//convert vector into normalmap color
			n.x=n.x/2 + 128;
			n.y=n.y/2 + 128;
			n.z=n.z/2 + 128;
			
			//copy color
			COLOR color2_;
			color2_.red=n.x;
			color2_.green=n.y;
			color2_.blue=n.z;
			
			COLOR color_;
			color_.red=(color1_.red+color2_.red)/2;
			color_.green=(color1_.green+color2_.green)/2;
			color_.blue=(color1_.blue+color2_.blue)/2;
			
			//add to pixels
			var format=bmap_lock(normalmap_,0);
			var pixel=pixel_for_vec(color_,100,format);
			pixel_to_bmap(normalmap_, px, py, pixel);
			bmap_unlock(normalmap_);
		}
	}
	
	//return new created Normalmap if no target bitmap was passed to function
	if(bmap_nmap_==NULL){return normalmap_;}
	else
	{
		//otherwise copy created Normalmap to target bitmap
		bmap_blit(bmap_nmap_,normalmap_,NULL,vector(bmap_width(bmap_nmap_),bmap_height(bmap_nmap_),0));
		
		//delete temp bitmap
		bmap_purge(normalmap_);
		bmap_remove(normalmap_);
		
		//return
		return bmap_nmap_;
	}
}



All scripts to make a terrain like in the screenshot above:

1. Combine a Perlin Noise Heightmap of 2/3 with a Voronoi Heightmap of 1/3
2. Use the Perturbation Filter over the combined heightmap.
3. Run the Hydralic Erosion Script over the heightmap.
4. Blur it a litte bit (had no script yet for this, made this in Photoshop)

Re: Slope Blendmap Generator [Re: oliver2s] #434093
12/12/13 11:25
12/12/13 11:25
Joined: Dec 2003
Posts: 1,225
germany
gri Offline
Serious User
gri  Offline
Serious User

Joined: Dec 2003
Posts: 1,225
germany
nice work.


"Make a great game or kill it early" (Bruce Shelley, Ensemble Studios)
Re: Slope Blendmap Generator [Re: gri] #434102
12/12/13 14:49
12/12/13 14:49
Joined: Mar 2006
Posts: 1,993
Karlsruhe
PadMalcom Offline
Serious User
PadMalcom  Offline
Serious User

Joined: Mar 2006
Posts: 1,993
Karlsruhe
Awesome! Those heightmaps are the most useful because you can even place buildings on the flat areas.

Re: Slope Blendmap Generator [Re: PadMalcom] #434105
12/12/13 15:12
12/12/13 15:12
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Yes, I'm happy I found that paper where those heightmap algorithm was featured. But I had to blur the final heightmap result, because the cliffs were too sharp.

Re: Slope Blendmap Generator [Re: oliver2s] #434106
12/12/13 17:36
12/12/13 17:36
Joined: Nov 2011
Posts: 274
de
lemming Offline
Member
lemming  Offline
Member

Joined: Nov 2011
Posts: 274
de
Thank you for your contributions! The are awesome and very very useful!

Re: Slope Blendmap Generator [Re: lemming] #434108
12/12/13 19:16
12/12/13 19:16
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
I really like the mesh of the terrain from the screenshot (in terms of usability for video games)!
However, I think the terrain really needs triplanar texture mapping, the stretched texture on the slopes if not up to date.

Btw. just saw the following part of your code:

Code:
VECTOR n;
n.x = 2.0*(c_.red-128);
n.y = 2.0*(c_.green-128);
n.z = 2.0*(c_.blue-128);

//normalize to 0-1
vec_normalize(n,1);

//get Euler angle
ANGLE rotation;
vec_rotate(n,vector(0,-90,0));
vec_to_angle(rotation,n);

//if angle is between given angles, paint blendmap
if(abs(rotation.tilt)>gradient_min_ && abs(rotation.tilt)<gradient_max_)


Basically you are only interested in the z-component of the normal vector, aren't you? If it's 1 your rotation.tilt is 0, near 1 the slope is near 90° in incline. Thus you should be able to skip the whole (vec_to_)angle stuff and work with the normal vector directly.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: Slope Blendmap Generator [Re: Superku] #434109
12/12/13 19:55
12/12/13 19:55
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: Superku
However, I think the terrain really needs triplanar texture mapping, the stretched texture on the slopes if not up to date.

Yes you are right. This is one thing I should work on. Never read about theory behind it, but I'm sure a google search give me dozen of papers about this.

Originally Posted By: Superku
Basically you are only interested in the z-component of the normal vector, aren't you? If it's 1 your rotation.tilt is 0, near 1 the slope is near 90° in incline. Thus you should be able to skip the whole (vec_to_)angle stuff and work with the normal vector directly.

I really suck at vector mathematics. but I think vec_to_angle is neccesary, because you need the exact euler angle. The normal vector gives you only the direction.

Re: Slope Blendmap Generator [Re: oliver2s] #434112
12/12/13 20:55
12/12/13 20:55
Joined: Feb 2010
Posts: 886
Random Offline
User
Random  Offline
User

Joined: Feb 2010
Posts: 886
What did you use to create your terrain?



Re: Slope Blendmap Generator [Re: Random] #434113
12/12/13 21:29
12/12/13 21:29
Joined: Jan 2006
Posts: 968
EpsiloN Offline
User
EpsiloN  Offline
User

Joined: Jan 2006
Posts: 968
I think he's using his generators from the start of this series of posts... laugh

Isnt this awesome? Now we get a random map generator!


Extensive Multiplayer tutorial:
http://mesetts.com/index.php?page=201
Re: Slope Blendmap Generator [Re: EpsiloN] #434114
12/13/13 04:14
12/13/13 04:14
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Just thought about it and tested it, you can replace the vec_to_angle code with rotation_tilt = -asinv(n.z); which gives you the very same angle as with your current code but more elegant and much faster.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Page 1 of 2 1 2

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