- Home /
How can I make my algorithm make cloudy heightmaps?
My game relies heavily on my terrain generation algorithm. The only problem is, is that my terrain is jagged. Suddenly, a mountain starts. And then it is perfectly flat. I want flat ground, but INTERESTING flat ground. and my mountain aren't mountainous. The heightmap is below.
Seriously blocky. My algorithm is this. (Yes, I've seen a thread with an algorithm JUST like this one. I did not steal. Hand on heart.)
function Start () {
var res = 513;
var tData = GetComponent(Terrain).terrainData;
tData.heightmapResolution = res;
var heights = new float[res, res];
for (var i = 0; i < res*res; i++) heights[i%res, i/res] = Random.Range(.51, .519);
tData.SetHeights (0, 0, heights);
var flat = new float[50, 50];
for (i = 0; i < 50*50; i++) flat[i%50, i/50] = .5;
for (i = 0; i < 75; i++) {
tData.SetHeights (Random.Range(0, res-50), Random.Range(0, res-50), flat);
}
}
Yes, this is my first game. Any support would be delightful. Thanks, -YoshiMad08
I kind of see what you want, but a picture would be very helpful. The first thing that comes to $$anonymous$$d is to use an image to create the map, but that may not work if you want to dynamically generate these maps during the game. As a point of comparison, how does this image compare to what you want?
Hmm... Well, I think I can whip up a photo in a second, and if that picture had a tad more... turbulence(?), it would be more suitable. I don't want it generated in-game, we aren't talking $$anonymous$$inecraft here. :) I just want randomly generated terrain at runtime.
Ah, I think I know what I need. Heightmap interpolation. Anyone know how to do that in CODE please? Javascript is prefered. Thanks :)
Answer by AlucardJay · Apr 05, 2013 at 04:07 PM
The reason you have jaggies is because you are using such a large range for each sample. Perlin Noise interpolates.
http://docs.unity3d.com/Documentation/ScriptReference/Mathf.PerlinNoise.html
Here is a script that takes two samples of perlin, then combines them.
This modifies terrain, so be sure to use a New Terrain. I won't be held responsible for lost terrain.
Step 1 : Backup your terrain ! Right click it, and hit Export Package...
Create a new scene, create a New Terrain, attach this script to the terrain or an empty gameObject.
Hit play, then Left-Mouse-Click to add noise to the terrain.
Modify the values of one of the octaves, then click LMB.
Then start playing around with the offsets and click LMB.
// April 6th 2013
// TwoSamplePerlinTerrain.js by Jay Kay (Alucard Jay)
#pragma strict
public var terrain : Terrain;
private var terrainData : TerrainData;
private var heightmapWidth : int;
private var heightmapHeight : int;
public var sampleOneOctave : float = 2.0;
public var sampleTwoOctave : float = 5.0;
public var sampleOneOffset : Vector2 = Vector2.zero;
public var sampleTwoOffset : Vector2 = Vector2.zero;
function Start()
{
if ( !terrain )
{
terrain = Terrain.activeTerrain;
}
terrainData = terrain.terrainData;
heightmapWidth = terrain.terrainData.heightmapWidth;
heightmapHeight = terrain.terrainData.heightmapHeight;
}
function Update()
{
if ( Input.GetMouseButtonDown(0) )
{
GeneratePerlinTerrain();
}
}
function GeneratePerlinTerrain()
{
var heightmapData : float[,] = terrainData.GetHeights( 0, 0, heightmapWidth, heightmapHeight );
for ( var y : int = 0; y < heightmapHeight; y ++ )
{
for ( var x : int = 0; x < heightmapWidth; x ++ )
{
var perlinSampleOne : Vector2 = new Vector2( ( ( sampleOneOctave / parseFloat( heightmapWidth ) ) * parseFloat( x ) ) + sampleOneOffset.x, ( ( sampleOneOctave / parseFloat( heightmapHeight ) ) * parseFloat( y ) ) + sampleOneOffset.y );
var perlinHeightOne : float = Mathf.PerlinNoise( perlinSampleOne.x, perlinSampleOne.y );
var perlinSampleTwo : Vector2 = new Vector2( ( ( sampleTwoOctave / parseFloat( heightmapWidth ) ) * parseFloat( x ) ) + sampleTwoOffset.x, ( ( sampleTwoOctave / parseFloat( heightmapHeight ) ) * parseFloat( y ) ) + sampleTwoOffset.y );
var perlinHeightTwo : float = Mathf.PerlinNoise( perlinSampleTwo.x, perlinSampleTwo.y );
heightmapData[y,x] = ( perlinHeightOne + perlinHeightTwo ) * 0.5;
}
}
terrainData.SetHeights( 0, 0, heightmapData );
}
There are more examples out there. Some good suggestions on the answer to this question : http://answers.unity3d.com/questions/340971/is-it-possible-to-do-this-for-a-random-terrain-app.html
Also there is a script in the Unity Wiki.
Answer by janzdott · Apr 05, 2013 at 04:43 PM
I agree with alucardj. You should use perlin noise. It works very well for terrain generation. I don't like Mathf.PerlinNoise. it never worked for me. I wrote a perlin noise algorithm that I can send you if you'd like. It works very well
Thanks to all who have answered/commented on this question! About the perlin noise... yes please. :3 You have all helped me a lot - thanks. :D
SUCCESS! alucardj thanks so freakin' much! I now have a pretty smooth terrain generator, and I'm making a main menu where you can change the Perlin Octaves, but i'll just call it Seeds 1/2. :D Thanks so much everyone :D
Your answer
Follow this Question
Related Questions
Terrain and procedural rivers 2 Answers
Map Generator script ? 1 Answer
Block Terrain Generator 5 Answers
Diamond Square algorithm height problem -1 Answers
How would I go about blending Noise? 1 Answer