x


Creating Perlin Noise

I've read articles and tutorials like this and this about perlin noise and found a way to do exactly what the pictures show.

Proof: alt text

I don't understand how I would add these together to get a nice outcome like this for example:

alt text or alt text

Could somebody help out on how to do such a thing? Here is my script:

function PerlinNoise(){
    var texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
    renderer.material.mainTexture = texture;
    for(x=0; x<width; x++){
        for(y=0; y<height; y++){
            if(Mathf.Round(Random.Range(0.0, 1.0)) == 0){
                color = Color.red;
            }
            else{
                color = Color.white;
            }
            texture.SetPixel(x, y, color);
        }
    }
    texture.Apply();
}

Thanks!

more ▼

asked Nov 23, 2011 at 08:45 PM

MrSplosion gravatar image

MrSplosion
192 119 104 110

That's not Perlin noise, that's just random. There's a Perlin noise function on the wiki which you can use. (Actually there's Mathf.PerlinNoise built into Unity, but it's undocumented.)

Nov 23, 2011 at 10:32 PM Eric5h5

I've seen a thread over the undocumented Mathf.PerlinNoise. From what I understand you give it a x and y value and it returns a decimal point. I'm not sure on how that's helpful at all in my situation. The way it's being used on the wiki is understandable though because you can use the float for the terrain height position.

So how would I use this function in my situation?

Nov 23, 2011 at 11:55 PM MrSplosion
(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

To create noise you need a float - it's not just a binary black or white, it's a smooth gradient.

As for how to do smooth color gradients, here's a snippet example:

//The two colors to generate noise between
var color1 = Color.white;
var color2 = Color.red;

var noise = .3; //You'd of course generate this from your perlin function
var perlinColor = new Color(color1.r * noise + color2.r * (1 - noise), color1.g * noise + color2.g * (1 - noise), color1.b * noise + color2.b * (1 - noise), color1.a * noise + color2.a * (1 - noise));

Sorry if that doesn't quite work - I'm a C# programmer guessing at JS.

The procedural examples have a Perlin noise example, available here:

http://unity3d.com/support/resources/example-projects/procedural-examples.html

more ▼

answered Nov 24, 2011 at 12:09 AM

Julien.Lynge gravatar image

Julien.Lynge
10.2k 87 85 123

I'm trying to make since of this. So is the perlinColor variable the color for the pixel? Like above would I iterate through each pixel in the texture and assign the perlinColor variable to it?

Also how do I generate the noise variable? Using the method like I explained when assigning each pixel the perlinColor variable the texture always looks like this: http://i.imgur.com/k42wB.png I'm making the noise variable a random decimal between 0 and 1 is this wrong?

Nov 24, 2011 at 12:47 AM MrSplosion

Correct, you would iterate through each pixel and assign the color to it. When you call your Perlin noise generator, it will return a float between 0 and 1 for each pixel. That float would then be the 'noise' variable. If you then wanted to create perlin noise between two colors (say red and white like your example), you'd set up color1 and color2 with these colors, and then apply 'perlinColor' to each pixel of your image, using the 'noise' generated for that pixel.

Nov 28, 2011 at 06:29 PM Julien.Lynge

Also, to answer your final question: you don't want to make the noise variable random for each pixel. Perlin noise is a controlled randomness, not pure randomness. Calling your perlin function will generate the appropriate level of randomness for you.

Nov 28, 2011 at 06:31 PM Julien.Lynge
(comments are locked)
10|3000 characters needed characters left

alt text

here is a img of unity perlin for reference. it's Mathf.PerlinNoise(x/10, 1.9); dots are x= 1,2,3 etc....

if you do perlin(x/10, 1.1) you'll get a curve like that, 1.1 is the random seed of the curve.

The above function will repeat every 200 or so kilometres, I just found out because I made my terrain with perlin(x/1.0 , 88.2) type of functions, and they all loop exactly the same after roughly 20,000 unity units, which is a surprise if you thought you were making an endless landscape!!! so if you do stuff like

perlin(x0.789 , 123)perlin(x*0.987 , 321), then it should repeat every 1 zillion kilometers because they are at different periods :)

NOTE: perlin noise isn't great for total randomisation. in fact it doesn't even go from 0 to 1 as the reference says! if you use it for random, the chances of having 1 and 0 are smaller than the chance of .5 and .8, it seems to be mostly distributed in the centre, probably like a Gaussian curve. To be more evenly distributed, it would have to be zig zag looking not rounded.

I just did a test to count the distribution... it turns out that for lower seeds for example under 20, none of the curve points are higher than 0.9

for 100000 perlin points:

seed=1.9, 
60 perlins> .85 
ZERO perlins>.9 (WEIRD!) 

 seed =43.543
843 perlinpts> .85
137 perlinpts> .9
2694 perlinpts< .15 
linear randomness would have given 15 000 above and below 8.5 and 1.5.

erm seed =4143.6543
663 perlinpts< 0.01, i.e 0.6 percent under 0.01

so! a WEIRD distribution. handy but weird.

the distribution is bottom heavy... esp. with higher seeds. and doesnt go over .9 with small seeds like 1.1

for some purposes you will want to amplify your perlin function and use Mathf.PingPong 0,1,to make it more evenly distributed, and add another perlin to it for granularity.

Also to note: 1.432=seed for perlin is not the same curve as 123.432, it's not modulo'd by 1.

to make more Granularity, to the perlin to make it possible to zoom in to more noise on smaller features... Unity perlin doesnt do that. you would have to add 2-3 perlin graphs together, 1 to make details on the 10/100th dimension, one on the 1/10, and one to make the large waves.

Random.seed = 1;
print (Random.value);
print (Random.value);

for (var p1:float = 0; p1 < 10000; p1 ++) {

var Perlin = Mathf.PerlinNoise(p1/100, 1.9);
Instantiate(digger, Vector3(p1-5000, Perlin*40, 0), rot3);
Debug.Log(     "Perlin  "   + Perlin );

}
pxdiv10.1.9.jpg (38.5 kB)
more ▼

answered Jan 19, 2013 at 10:15 AM

MountDoomTeam gravatar image

MountDoomTeam
1.2k 190 190 206

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3508
x53

asked: Nov 23, 2011 at 08:45 PM

Seen: 12674 times

Last Updated: Feb 03, 2013 at 09:17 PM