(C++/Irrlicht Core) Terrain Generation Smoothed

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
DeusXL
Posts: 114
Joined: Sun Mar 14, 2004 9:37 am
Contact:

(C++/Irrlicht Core) Terrain Generation Smoothed

Post by DeusXL »

[I don't really know where to post it but there is code and perhaps you can add some too]

I was just playing a bit with heightmaps and I realized something :

Let's take a look at the example 12, Terrain Rendering.
When looking at the terrain, everything is smoothed and looks nice and if we look to the heightmap (see below), there are only 3 or 4 hills on the heightmap... It's a 256*256 very basic and very small heightmap which doesn't need to be scaled a lot :
Image

But what if we try to make a huge terrain with twenty hills or more and we try to use only a 256*256 bitmap :
Image
As you can see, the heightmap does not look very nice and it's normal because we have only very small hills and it looks a bit chaotic...

Now if we try to render our heightmap with Irrlicht, we shall need to scale it a lot more than the older one because each hill has to seem as big as in the first one.
But here's what happens (the texture is a false one, that's not what I'm talking about) :
Image
As you can see... It's quite ugly... Looks like our hills were turned into stairs and the expected effect is not that at all...

I thought that the problem was in the core, because Irrlicht loads a vertex buffer which has the same size as our heightmap (256*256 in both case) and then scales this buffer. Thus, a simple heightmap, not much scaled, is rendered perfectly but when you scale this heightmap, the distance between each vertex is scaled and then it's not well rendered.

I'm now wondering if anyone ever tried to solve this problem (I searched a bit on the forum and found nothing related) and if so, how he did.

I actually added a little code on Irrlicht's terrain generator to smooth the terrain loaded :

Code: Select all

		for(s32 i = 0; i < 5; i++)
		{
			for(int index = 2; index < (TerrainData.Size * TerrainData.Size - 2); index++)
			{
				pMeshBuffer->Vertices[index].Pos.Y = 
					(pMeshBuffer->Vertices[index - 2].Pos.Y + pMeshBuffer->Vertices[index - 1].Pos.Y +
					 pMeshBuffer->Vertices[index + 1].Pos.Y + pMeshBuffer->Vertices[index + 2].Pos.Y) / 4.0f;
			}
		}
		for(s32 i = 0; i < 5; i++)
		{
			for(int index = TerrainData.Size; index < (TerrainData.Size * (TerrainData.Size - 1)); index++)
			{
				pMeshBuffer->Vertices[index].Pos.Y = 
					(pMeshBuffer->Vertices[index - TerrainData.Size].Pos.Y +
					 pMeshBuffer->Vertices[index + TerrainData.Size].Pos.Y ) / 2.0f;
			}
		}
(in CTerrainSceneNode::loadHeightMap before "heightMap->drop();")

As you can see, it is really simple because it just changes each vertex's Y position according to the near vertices but the result surprised me :
Image
Thanks to that code, I can create quite big terrains on small heightmaps.
The terrain is foggy but it looks like this :
Image

I know such a code could not be used for every heightmap because it *normalizes* the height of our terrain and modifies it a lot but I was wondering if anyone had already worked on such a thing.
Irrlicht .NET complete and Cross Platform Wrapper
The kid on my avatar wrote:A painless lesson is one without any meaning
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

Thanks for that, I had the same problem.

One "solution" was to simply use jpegs instead of pngs. :roll:

For now I just 16 bit raw height maps, which works fine. :) I need the higher resolution for my game. ;)

Regards - Xaron
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Why does jpeg work and png not?! You could also use 24bit precision by exploiting all 3 color components.
The smoothing looks good, maybe it could use an option in the terrain generator to switch this on and off.
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

hybrid wrote:Why does jpeg work and png not?! You could also use 24bit precision by exploiting all 3 color components.
Yep, my fault, sorry. Of course that was the problem. ;)

Regards - Xaron
buhatkj
Posts: 444
Joined: Fri Dec 12, 2003 4:53 am
Contact:

Post by buhatkj »

i had that same issue, i was trying to load some output from a terrain generator, and i got steps everywhere. i think this is definitely a valuable thing to add, perhaps you can make a patch for it, and maybe it can make it into the next release. many patches do :-)
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
burningreggae
Posts: 66
Joined: Wed Oct 04, 2006 2:07 pm

Post by burningreggae »

hey thats a real cute one!.
very nice!
i try to merge it with the existing source
burningreggae
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

Essentially what you have done is applied an averaging filter on your heightmap. This can be done in your image editing application (Gimp, PSP, Photoshop, etc) - and you can save on the processing.

The reason why your terrain is so lumpy from the original heightmap depends on the noise algorithm you used to create it.

I usually create a heightmap, say with Terragen, then whack it into my image editor and give it a Gaussian blur to get same effect.

Cheers,

Pinky
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
Elektordi
Posts: 4
Joined: Sun Oct 01, 2006 8:29 pm

Post by Elektordi »

I got same problems on my landscapes... Thanks for your code!
But, is there any way to put the code in my own source? Because I don't really want to deal with the engine source code...
DeusXL
Posts: 114
Joined: Sun Mar 14, 2004 9:37 am
Contact:

Post by DeusXL »

Elektordi wrote:I got same problems on my landscapes... Thanks for your code!
But, is there any way to put the code in my own source? Because I don't really want to deal with the engine source code...
You can still copy paste the code from Irrlicht's scene node, add the patch, and rename it...

@sgt_pinky : You're right but sometimes the problem is on the res of the heightmap... Here, 256*256 is too small for a huge terrain as rendered in Irrlicht... No software can create more pixel and a filter can't be applied on the heightmap... That's why it must be done on the terrain directly.
Irrlicht .NET complete and Cross Platform Wrapper
The kid on my avatar wrote:A painless lesson is one without any meaning
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

DeusXL wrote: @sgt_pinky : You're right but sometimes the problem is on the res of the heightmap... Here, 256*256 is too small for a huge terrain as rendered in Irrlicht... No software can create more pixel and a filter can't be applied on the heightmap... That's why it must be done on the terrain directly.
Ah, you're absolutely correct. I missed that point, sorry. Great suggestion!
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
pwierz
Posts: 59
Joined: Sun Aug 20, 2006 3:32 pm

Post by pwierz »

I made a small tweak to the code because the original code can cause some odd behavior at the edges of the heightmap which can be problematic if you're using tiled heightmaps. The problem with the original code is that it doesn't take into account "new lines" in the data. So it smooths the last vertex of one line with the first vertex of the next line. So this code will only smooth with adjacent vertices. I know there's a lot of if statements but I wanted to smooth the edges without potential seg faults.

Code: Select all

		for( s32 i=0; i < 5 ;i++)
		{
			for( s32 x=0; x < TerrainData.Size ; x++)
				for( s32 z=0; z < TerrainData.Size ; z++)
				{
					int counter=1;
					if( x>0 && z > 0){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x-1) + (z-1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( x>0 ){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x-1) + (z) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( x>0 && z < TerrainData.Size-1){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x-1) + (z+1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( x < TerrainData.Size-1 && z > 0){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x+1) + (z-1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( x < TerrainData.Size-1 ){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x+1) + (z) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( x < TerrainData.Size-1 && z < TerrainData.Size-1){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x+1) + (z+1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( z > 0 ){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x) + (z-1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					if( z < TerrainData.Size-1 ){
						pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y += pMeshBuffer->Vertices[(x) + (z+1) * TerrainData.Size].Pos.Y;
						counter++;
					}
					pMeshBuffer->Vertices[x + z * TerrainData.Size].Pos.Y /= (float)counter;
				}
		}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, you're right. I also spotted this bug when using a linear gradient as heightmap. It gives a perfect ramp with funny curves at the top and bottom. I did not have the time to find a proper solution. So thanks for making it much easier for me now :D
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

Hello I want to know how to add this code in Irrlicht, can somebody help me ?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Which one?
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

The one posted by DeusXL, to smooth terrain.
Post Reply