- Home /
Diamond Square algorithm height problem
I'm currently trying to implement the Diamond Square algorithm in unity. When I generate a terrain I always end up to flat areas at max height like so :
Here is my code :
// Check if the point (x, y) exist
private bool isInRange(int x, int y)
{
if(x >= 0 && x < resolution && y >= 0 && y < resolution)
return true;
else
return false;
}
// Do the average of the square corners height
private float sqrAvr(int x, int y, int step)
{
float average = 0.0f;
float counter = 0.0f;
if(isInRange(x - step, y - step))
{
average += heightMap[x - step, y - step];
counter++;
}
if(isInRange(x - step, y + step))
{
average += heightMap[x - step, y + step];
counter++;
}
if(isInRange(x + step, y + step))
{
average += heightMap[x + step, y + step];
counter++;
}
if(isInRange(x + step, y - step))
{
average += heightMap[x + step, y - step];
counter++;
}
return average / counter;
}
// Do the average of the diamond corners height
private float diaAvr(int x, int y, int step)
{
float average = 0.0f;
float counter = 0.0f;
if(isInRange(x - step, y))
{
average += heightMap[x - step, y];
counter++;
}
if(isInRange(x + step, y))
{
average += heightMap[x + step, y];
counter++;
}
if(isInRange(x, y + step))
{
average += heightMap[x, y + step];
counter++;
}
if(isInRange(x, y - step))
{
average += heightMap[x, y - step];
counter++;
}
return average / counter;
}
private void generateTerrain()
{
// Corners initialisation
heightMap[0, 0] = Random.Range(0, maxHeight);
heightMap[0, resolution - 1] = Random.Range(0, maxHeight);
heightMap[resolution - 1, 0] = Random.Range(0, maxHeight);
heightMap[resolution - 1, resolution - 1] = Random.Range(0, maxHeight);
// Generation of the rest of the map
int step = resolution;
while(step > 1)
{
Debug.Log(step);
int halfStep = step / 2;
float scale = step * roughness;
// Square part
for(int x = halfStep ; x < resolution ; x += step)
for(int y = halfStep ; y < resolution ; y += step)
heightMap[x, y] = sqrAvr(x, y, halfStep) + Random.value * 2 * scale - scale;
// Diamond part
for(int x = 0 ; x < resolution ; x += halfStep)
for(int y = (x + halfStep) % step ; y < resolution ; y += step)
heightMap[x, y] = diaAvr(x, y, halfStep) + Random.value * 2 * scale - scale;
step /= 2;
}
}
public void Start()
{
terrain = Terrain.activeTerrain;
heightMap = new float[resolution, resolution];
generateTerrain();
terrain.terrainData.SetHeights(0, 0, heightMap);
}
Hope I can find an answer here. :)
I think your maxHeight should be equal to the terrain's max height. I'm not even sure how to work with terrains but hopefully sticking this line in the Start() function will get you somewhere:
maxHeight = Terrain.activeTerrain.terrainData.heightmapHeight;
Answer by Owen-Reynolds · Dec 29, 2014 at 05:59 PM
It does, as taxvi alludes to, look as if you're generating heights in a much greater range than the terrain can be. Like what we're seeing is a tiny slice of the real terrain.
A cheap way to test might be to scale and slide the final result, at line 113.5. heightMap[i,j]=heightMap[i,j]*scale+slide;
. Try with a very small terrain. Trail and error should find the range.
That, or just manually set heights 0-255 along the sides, and see what it makes (it you get a tiny slope up, then all flat, the range must be 0-1.)
Or maybe jack up the numbers on your Terrain object and see if it looks less slopey.
Yep, after some test I found that the height must be between 0 and 1. Now it's much better :
Thank you very much taxvi and Owen Reynolds ! :)
Hi Owen I'm facing similar issues as above. But I still can't get it to work and my code is an adaptation of above.
If the Answer here didn't help (the range is 0-1) then this seems like a new Q.
I think you should post it to the HelpRoom area. And put your code as text (formatted as code -- you'll see if it looks right.) That way someone could paste and test it if they wanted.
Hi Owen, I've just posted one. Here's the link http://answers.unity3d.com/questions/1236569/procedural-terrain-height-issue.html
Cheers
Your answer
