# Terrain too rough

This topic is 4270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am currently working on a heightmap-generator. Since I would like to generate the heightmap for an island I searched for algorithms which would do this for me an found this one: http://www.robot-frog.com/3d/hills/island.html Since this algorithm always leaves me with the same circular shape and only one mountain, which is always in the center, I modified it so that half the time the hills would be subtracted. This makes the shape somewhat more interesting. But either way, the terrain is way too rough. It looks as if it was composed of circular slices stacked on top of another. I already tried a box filter to smoothe the terrain but it did not get better... Any ideas?

##### Share on other sites
Use a multi-fractal? I guess to make this produce an island you would need to add a multiplier based on distance from some center point.

##### Share on other sites
Given the fact that you already coded a box filter, you could just execute it multiple times! Or use a "better" smoothing algorithm, like a gaussian filter.

##### Share on other sites
What are you using to make the those renders?

##### Share on other sites
Actually I am already applying the box filter 20 times. Applying it about 500 times does somewhat soften the terrain but it still looks as if composed of slices (just with less features...).

I am rendering the terrain using Ogre3D so there should be nothing wrong with the renderer.

Will multifractal algorithms solve the circular shape problem? Islands that have a very straight coastline do not look too realistic :(

[Edited by - Hippokrates on March 27, 2006 12:08:35 PM]

##### Share on other sites
i implemented the robot frog algo and didnt have this issue at all. in fact, my issue was that there wasn't enough "roughness" to the algo. if you're ending with one mountain in the center every time then you havent properly implemented the method. or perhaps the metrics you are using to seed the algo are the source of your problem.

iirc, the algo randomly selects a point on your terrain and raises by variable X that point and does a radial fall off given a slope Y.

wish i had my home pc available i'd give you some screenshots of what is possible with it. smooth, rolling hills that look great and the ability to save it in a very small random seed to be generated later.

for smoother transitions increase your hill radius and store a list of your 10 or so highest points and auto reject them if they are within radius minus Y of the randomly chosen point.

##### Share on other sites
Quote:
 Original post by HippokratesIt looks as if it was composed of circular slices stacked on top of another.

Sounds like you are using int's instead of floats for the height values.

As for the rest, without an image it's hard to speculate what the problem is.

##### Share on other sites
I made a screenshot to illustrate my problem:

As for my implementation of the algorithm:
bool HeightmapGen::GenerateShape(double * heightmap, HeightmapParameters * params) {	int radius, centerX, centerY, distance;	int xMin, xMax, yMin, yMax, subtract = 1;	double theta;	for(int i = 0; i < params->details; i++) {		radius = params->hillMin + (rand() % (params->hillMax - params->hillMin));		theta = (rand() % (2 * Pi)) / 1000.0f;		distance = (radius / 2) + rand() % static_cast<int>(1 + (params->terrainSize / 2.0f) - radius);		centerX = (params->terrainSize / 2.0f) + cos(theta) * distance;		centerY = (params->terrainSize / 2.0f) + sin(theta) * distance;		xMin = centerX - radius - 1;		xMax = centerX + radius + 1;		yMin = centerY - radius - 1;		yMax = centerY + radius + 1;		if(xMin < 0) xMin = 0;		if(xMax >= params->terrainSize) xMax = params->terrainSize - 1;		if(yMin < 0) yMin = 0;		if(yMax >= params->terrainSize) yMax = params->terrainSize - 1;		if(rand() % 2 == 0) {			subtract = -1;		}else {			subtract = 1;		}		for(int j = xMin; j < xMax; j++) {			for(int k = yMin; k < yMax; k++) {				double squareDistance = (centerX - j) * (centerX - j) + (centerY - k) * (centerY - k);				double height = (radius * radius) - squareDistance;				if(height > 0.0f) {					heightmap[j + (k * params->terrainSize)] += height * subtract;					if(heightmap[j + (k * params->terrainSize)] < 0) heightmap[j + (k * params->terrainSize)] = 0;				}			}		}	}	return true;}

As I mentioned earlier, I modified the algorithm to subtract half of the hills in order to avoid a circular shape. The result isn't very pretty though ^^;

##### Share on other sites
Their algorithm doesnt look particularly good. (judging by their methods description, not the screenshot)
Have you considered using other approaches?

How about DiamondSquare, with some unitial 'seed' height values to keep it in a general island shape?

or perlin noise with a filter based on distance to center?

or either of the above techniques layered on top of what you have now to add details and hide problem areas?

##### Share on other sites
Sound like you're using bytes in the original height map generation. Bytes only have 256 different values, which easily leads to quantization in height. Try using floats instead. Or, if you're not using the full 0-255 range (or -128-127), scale your terrain such that the highest value you want is 255, and the lowest is 0, to minimize quantization.

Another thing you can do is to generate the heightfield at a much coarser interval, and generate a more tesselated mesh using some kind of interpolation. Cubic interpolation works pretty well for that cases, in my experience.

##### Share on other sites
Actually I am using doubles during heightmap generation. After the first step of heightmap generation, the array consists of values with no upper limit (since all hills are added on top of another). These values are then normalized to an intervall between 0 and 1. Finally, when saving the heightmap, the heightmap is scaled up by multiplying the values with 255.

##### Share on other sites
This is what I get using the Hill algorithm you mention above. I applied smoothing just once aftewards (based on a box filter from this gamedev article). It does occasionaly generate a large hill in the center, as you mention, but for the most part, it generates a good island scene. I use bytes for the height in the range 0 to 255.

##### Share on other sites
Quote:
 Original post by HippokratesActually I am using doubles during heightmap generation.

You're doing this:
int radius;double squareDistance = (centerX - j) * (centerX - j) + (centerY - k) * (centerY - k);double height = (radius * radius) - squareDistance;

The problem is you have declared radius as int. So your multiplications are giving you int's as well not doubles. This is giving you the quantized height values. Try:
double radius;double squareDistance = (double)(centerX - j) * (double)(centerX -j) + (double)(centerY - k) * (double)(centerY - k);double height = (radius * radius) - squareDistance;

##### Share on other sites
One other thing, why are you doing this:

theta = (rand() % (2 * Pi)) / 1000.0f;

The division by 1000 makes theta near 0. Therefore, centerX=mapcenter+distance, and centerY=mapcenter.

Which is probably making your island look like a long cammel hump instead of spreading the hills around the map.

##### Share on other sites
Changing the values into doubles did not work either :(
As for the "theta = (rand() % (2 * Pi)) / 1000.0f;": I divide the value by 1000 because Pi is defined as 3141 (since you cannot use modulo on floating point numbers)

##### Share on other sites
Can you provide an image with polygon lines visible aswell? That would be helpful in diagnosis. It looks to me like some of the terrain is "stepped". That might mean its a drawing problem not a generation problem. Also it could just be that 8 bits isn't accurate enough for how much terrain you are generating.

##### Share on other sites
I actually think the image is fine and to be expected. Could you post a wireframe screenshot maybe?

The image in the tutorial looks nicer, but you'll notice that it is far more dense than the lines drawn over it suggest. If they plotted that mountain only on the points where the lines intersect it would also look pretty rough.

##### Share on other sites
I made a shot of the terrain in wireframe mode. I hope it will prove helpful. And this time I also used the source code provided by the author to generate the terrain. Therefore my implementation of the algorithm should have been correct.

##### Share on other sites
Why is the mesh of the ground denser than the mesh of the 'mountain'?

##### Share on other sites
Actually I have no idea. I am rendering the terrain with Ogre's built-in terrain plugin, using standard parameters.
But I think the ground you are referring to, is actually behind the hill - so maybe it just looks more dense because it is farther away.

##### Share on other sites
Hmm, that could be I guess. But I still think the output seems about right. Could you maybe update the image to show a more zoomed out version?

##### Share on other sites
It *really* looks like a quantization artifact, like hplus explained. If the piece of code you posted is correct, then it could be a problem with Ogre's plugin (maybe it converts doubles to 8-bits integers ?), or maybe you have yourself a cast to 8-bits int somewhere when submitting your data to the Ogre API ?

Y.

##### Share on other sites
i don't have a solution to the problem but i wouldn't go as far as rick and say that it's alright. The terrain looks like a staircase. I also think that the problem is a result of inaccuracies of variables(like using ints) because every single vertex is lying on a 'step'.

regards,
m4gnus

##### Share on other sites
Well, Ogre is of course using 8-bit integers because I do not directly give the heightmap to Ogre - I save it as a 8-bit greyscale .png, first.
But heightmaps usually are 8-bit images, aren't they? So that should not be the problem...?

More zoomed-out version:

##### Share on other sites
Quote:
 Original post by HippokratesI divide the value by 1000 because Pi is defined as 3141 (since you cannot use modulo on floating point numbers)

Just for the record, you can do that with the fmod function.

##### Share on other sites

This topic is 4270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628696
• Total Posts
2984267

• 19
• 9
• 13
• 13
• 11