Perlin noise that looks like this

Hey all,

I want to create Perlin noise that looks like this:

From what I can generate, that looks like this: (How do I shrink this on the forums?)

I’m unsure what settings I need to tweak. I’m using this :point: to generate my noise. Any help is greatly appreciated. :smiley:

Looks like the absolute value of 2 combined frequencies.

[offtopic]
Use
http://(Link)
to shrink images on the forums
[/offtopic]

So I should create two images with two different frequencies? Then add the values at the same points, Math.abs() them, then clamp them so they’re between 0 and 1?

Ta muchly

First answer seem to be that exact image.

Thanks @BurntPizza! Bear with me for being slow, but in the following code:

double turbulence(double x, double y, double z, double f) {
    double t = -.5;
    for ( ; f <= W/12 ; f *= 2) // W = Image width in pixels
        t += abs(noise(x,y,z,f) / f);
    return t;
}

I’m guessing f is frequency?

EDIT: gah, I’m starting to pull my hair out over this. Cannot seem to generate that type of noise no matter what I try :frowning:

Playing around with http://hexara.com/SimplexVisualizer.html I got the following, which seems pretty close.

http://www.java-gaming
.org/user-generated-content/members/27722/jgo-reply.jpg

Here is a screen shot of the settings I used:

Basically, what @LiquidNitrogen and @CptSpike is correct. The noise() function returns values between -1 and 1, and we want to scale the results to something like 0 to 255 for graphics output. The method of scaling used for your example includes an absolute value. This form of mapping was termed “Turbulent Noise” by Ken Perlin.

For example, (pseudo code)


for ( all y values)
  for ( all x values)
     noiseValue = noise(x * xScaling, y * yScaling);
     noiseValue = Abs(noiseValue) * 255;
     postValueToImagePixel(x, y, noiseValue);

A “Smooth Noise” mapping would be more like the following:


  noiseValue = ( (noiseValue + 1) / 2.0 ) * 255;

I don’t know about your particular noise() function, or why you are putting 4 parameters in it. With Gustavson’s Simplex Noise implementation, you only need the X & Y for 2D noise.

Your pattern might have a bit of “clamping” to it on the black end. That can be accomplished by something like the following:


    noiseValue = abs(noiseValue);  // applies 'turbulent noise' algo
    noiseValue = ( noiseValue * 1.2 ) - 0.2; // scale and shift
    noiseValue = max(0, noiseValue);  // "clamp" levels below 0 to 0

Another possibility is that the multiplication in the second step above is omitted, and the values simply shifted downward with the subtraction, then clamped. I say that because it seems to me the results don’t get as bright as I expect at the white end, so maybe the shift was uniform across the entire response range, rather than being “stretched” by the multiplication first.

There may be a second noise function being summed in, in which case the noiseValue starts out as the weighted sum of the two calls to the noise() function, before going through the various transforms to make the number an intelligible color value.

You can download the jar of Sivi from here:
http://www.java-gaming.org/user-generated-content/members/27722/sivi.jar
Or, check out the github open source here:

Just thought I’d add a note about “frequency”. It is probably the most confusing thing for people first trying to understand how to use the noise() function.

In the pseudocode in the previous example, I wrote the following:

 noiseValue = noise(x * xScaling, y * yScaling);

The “frequency” is referring to the amount of scaling used on your X & Y values before making the method call. One reason for the use of the term is that folks like to make the combination of noise() methods a fractal process, thus each “frequency” is set to be an octave (or doubling or halving) of another.

Thanks for the help @philfrei, I’d forgotten about the coordinate scaling business. I’m going to have a fresh start at this tomorrow, I’ll report back if I ever get it working properly :slight_smile:

EDIT: @philfrei, I borrowed your SimplexNoise class from the project you linked, and followed the code in your comment, but I’m just getting random noise, like this:

Full size image

To get an image like you want… you want to run the perlin routine at different levels and them merge the results.

Still no dice. Gah how can I be so bad at this, it’s only parameter twiddling.

You might be dividing the x and y by way too much, you want fairly low frequency noise to produce those loops

Actually, I’m guessing the opposite is the case, not dividing by enough.

To get lower frequencies, the rate at which one moves through the Perlin space has to be pretty small. Therefore the increments between one X and the next have to be very small. I’d try dividing X & Y by 64 or 32 to get something in the ballpark of what I displayed.

The “base” scaling factor in my app is 1/256 if I remember correctly, and the example I put up was 6 times that.

So try this:

 noiseValue = noise( (x * 6) / 256.0, (y * 6) / 256.0);  

Or put in a simpler expression like (x / 43.0, y / 43.0);, and be sure and make the division result in a double, don’t do integer division.
If you are using Gustavson’s SimplexNoise, that should get you pretty close.

Yesterday I thought I posted another round of playing with this–but I must have bungled it, as the post isn’t here. I couldn’t resist trying to reverse engineer your example.

Here is the screen shot:

I realize this is over-complicating things a bit, as you are still trying to get the basic function to produce the result on the top right. But I am confident you will get it when you try putting in a scaling factor like I described in the previous post.

In this example, the refinement is that a lower frequency is added (scaled to half of the main track), but I’m first clamping out all the negative values instead of folding them over back into the positives via the ABS function. So, overall, it is providing some nice shading with some “highlights” here and there where the white appears.

The equation for the left side (noiseValueA) in combination with the right side (noiseValueB) would be this:


    noiseValueA = Math.max(0, noise(x * 3 / 256.0, y * 3 / 256.0);
    
    noiseValueB = noise(x * 6 / 256.0, y * 6 / 256.0);
    noiseValueB = Math.abs(noiseValueB);

    noiseValue = (noiseValueA + 2 * noiseValueB) / 3; 

Then, transform noiseValue into a meaningful color value, and assign it to pixel (x, y).

Yeees! I was multiplying by a factor, instead of dividing, and it was much to small. Dividing my coordinates by 128 gives me this:

Thanks so much for your help everyone, was about ready to give up on this. Hopefully some tweaking will finally give me what I can use :slight_smile:

EDIT: Finally got to where I was trying to go. Big thanks to everybody for their help. Now I have terrain for my worms clone! Exmaple: