- Home /
How do i assign perlin noise
I am trying to make a procedural map using perlin noise. I have made a script that generates a plane mesh, and now i want to use mathf.perlinnoise to create hills. But i cannot figure out how to implement it.
My plane generation script was made with the help of quill18's tile map tutorial.
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class TileMap2 : MonoBehaviour {
public int size_x = 100;
public int size_z = 50;
public float tileSize = 1.0f;
// Use this for initialization
void Start () {
BuildMesh();
}
public void BuildMesh () {
int numTiles = size_x * size_z;
int numTris = numTiles * 2;
int vsize_x = size_x +1;
int vsize_z = size_z +1;
int numVerts = vsize_x * vsize_z;
float noise = 0.1f;
// generate the mesh data
Vector3[] vertices = new Vector3[numVerts];
Vector3[] normals = new Vector3[numVerts];
Vector2[] uv = new Vector2[numVerts];
int[] triangles = new int[ numTris * 3 ];
int x, z;
//my perlin noise nonsense..???
var noiseOffset = new Vector2(Random.Range(0f, 100f), Random.Range(0f, 100f));
for(z=0; z < size_z; z++) {
for(x=0; x < size_x; x++) {
var a = z * vsize_x + x + noiseOffset.x;
var b = z * vsize_x + x + noiseOffset.y;
noise = Mathf.PerlinNoise(a, b);
}
}
for(x=0; x < vsize_x; x++) {
for(z=0; z < vsize_z; z++) {
vertices[ z * vsize_x + x ] = new Vector3( x*tileSize, noise, z*tileSize );
normals[ z * vsize_x + x ] = Vector3.up;
uv[ z * vsize_x + x ] = new Vector2( (float)x / size_x, (float)z / size_z );
}
}
for(z=0; z < size_z; z++) {
for(x=0; x < size_x; x++) {
int squareIndex = z * size_x + x;
int triOffset = squareIndex * 6;
triangles[triOffset + 0] = z * vsize_x + x + 0;
triangles[triOffset + 2] = z * vsize_x + x + vsize_x + 1;
triangles[triOffset + 1] = z * vsize_x + x + vsize_x + 0;
triangles[triOffset + 3] = z * vsize_x + x + 0;
triangles[triOffset + 5] = z * vsize_x + x + 1;
triangles[triOffset + 4] = z * vsize_x + x + vsize_x + 1;
}
}
// create new mesh and populate with the data
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.uv = uv;
// assign our mesh to our filter/renderer
MeshFilter mesh_filter = GetComponent<MeshFilter>();
MeshRenderer mesh_renderer = GetComponent<MeshRenderer>();
MeshCollider mesh_collider = GetComponent<MeshCollider>();
mesh_filter.mesh = mesh;
mesh_collider.sharedMesh = mesh;
}
}
When i run the script now, it sets the entire plane at a random height. If i run the perlin noise stuff in the for loop making the mesh, it just becomes noise (or if i dont use random.range, nothing). I understand i have to change the y axis of Vertecies. But how do i implement the smooth perlin noise? I am still learning, especially c#..
you are looking for this kind of noise ?
(that was perlin noise applied to a plane)
Answer by maccabbe · Jun 15, 2015 at 03:19 PM
In lines 50-59 you are generating perlin noise for each point but only storing the last value. So when you assign the positions of the verticies in lines 63-70 you use the last generated height for all verticies. You would either have to store the generated heights or use each one immediately. i.e. replace lines 50-70 with
for(x=0; x < vsize_x; x++) {
for(z=0; z < vsize_z; z++) {
var a = z * vsize_x + x + noiseOffset.x;
var b = z * vsize_x + x + noiseOffset.y;
noise = Mathf.PerlinNoise(a, b);
vertices[ z * vsize_x + x ] = new Vector3( x*tileSize, noise, z*tileSize );
normals[ z * vsize_x + x ] = Vector3.up;
uv[ z * vsize_x + x ] = new Vector2( (float)x / size_x, (float)z / size_z );
}
}
Answer by -OTTO- · Jun 16, 2015 at 05:42 AM
Thank you.. after messing with it for a while i came up with this:
var noiseOffset = new Vector2(Random.Range(0f, 10f), Random.Range(0f, 10f));
for(x=0; x < vsize_x; x++) {
for(z=0; z < vsize_z; z++) {
var a = x + size_x * 2f + noiseOffset.x;
var b = z + size_x * 2f + noiseOffset.y;
float noise = Mathf.PerlinNoise(a / 10, b / 10);
vertices[ z * vsize_x + x ] = new Vector3( x*tileSize, noise * 10, z*tileSize );
normals[ z * vsize_x + x ] = Vector3.up;
uv[ z * vsize_x + x ] = new Vector2( (float)x / size_x, (float)z / size_z );
}
}
Any suggestions to how i can mix 2 or more x perlin noise to get a more natural terrain?