How to generate Perlin Noise in Java?

Stop messing around with this. Look at the wiki. This is filling an array with white noise then doing multiple passes of a bad box filter. This is insanely slow and very poor quality…you’re wasting your time. Use a real noise generation function from from the last 30 years.

Take a look at the simplex noise code I linked you to. With this code, it can generate a 512x512 in 79ms. It can also generate 10000x10000 (10 billion) points in 39.8s. With the code you have, generating a (smooth) 512x512 takes 5s. If you tried to generate 10000x10000, it would take almost 53 HOURS.

THanks, I didn’t notice the link to stackoverflow earlier. I just copy/pasted the code and it works perfectly. My head is going to break at the awesomeness of people who can create such maths. I want to able to do something like that too some day.

@trollwarrior1

Thanks for giving an explanation of the code. Earlier, I only read as far as seeing the array being filled with randoms, and things got “fuzzy” with the box filter step. I definitely have room to improve with my code reading skills.

I think it is neat that a decent noise/cloud can be generated this way. It does has the benefit of using very little code. But the inefficiency is pretty awful compared to other techniques that are readily available.

Math is awesome. Do stick with it in school! (I didn’t do so as much as I now wish I had.) I think that the path to being able to create maths comes not just from study, but from playing with it, exploring on the way, as you are already doing.

So I think I worked out the Perlin Noise algorithm at last (Check the modified original post. I put everything in there). Now what I need to do, is to make it kinda random.

Is there anyone who knows how to generate random numbers between -1 and 1 based on x,y and seed?

If you were to look at the local wiki page there are links to working implementations in java.

This is exactly the problem I encountered. Once upon a time I made a forum topic about that, too and Roquen helped me out. This is what came out of it in the end:


private static long hashWang(long key) {
    key = (~key) + (key << 21); // key = (key << 21) - key - 1;
    key = key ^ (key >>> 24);
    key = (key + (key << 3)) + (key << 8); // key * 265
    key = key ^ (key >>> 14);
    key = (key + (key << 2)) + (key << 4); // key * 21
    key = key ^ (key >>> 28);
    key = key + (key << 31);

    return key;
}

private FastRand getRand(int x, int y) {
    rand.setSeed(hashWang((x << 17) ^ y) + seed);
    return rand;
}

(look at it on github)

FastRand in the end uses simple xor logic for generating a random boolean:


public long randLong() {
    seed ^= (seed << 21);
    seed ^= (seed >>> 35);
    seed ^= (seed << 4);
    return seed;
}
public boolean randBool() {
    return randLong() > 0;
}

Though it might be sufficient to use the first bit (bit no. 0) of the hashWang result:


private static long hashWang(long key) {
    key = (~key) + (key << 21); // key = (key << 21) - key - 1;
    key = key ^ (key >>> 24);
    key = (key + (key << 3)) + (key << 8); // key * 265
    key = key ^ (key >>> 14);
    key = (key + (key << 2)) + (key << 4); // key * 21
    key = key ^ (key >>> 28);
    key = key + (key << 31);

    return key;
}

private boolean getRand(int x, int y) {
    return hashWang((x << 17) ^ y) + seed) & 1 == 0; // == 0 should be faster than == 1
}

Thanks for the code.
I implemented it. I might be doing something wrong, but the performance is 3-4 times worse than it was with just generating an array. My method has its limitations, but for small stuff it is pretty slick.