0
\$\begingroup\$

I'm trying to use 1D Perlin Noise to generate "random" terrain for a side-view scrolling game (Think Terraria). I've gotten it mostly working, however strange things start to happen when generating terrain for negative x values. This is a sample of the terrain: enter image description here

As you can see, the left side, where the x values are negative, is generated in a much more jagged and sharp way than the positive side. I would much prefer it to be more smooth like the positive side. This is the noise generator I am using:

private long seed;

public PerlinNoise(long seed) {
    this.seed = seed;
}

public int getNoise(int x, int range) {
    int selectionSize = 16  * 16;
    float noise = 0;

    range /= 2;
    while (selectionSize > 0) {

        int selectionIndex = x / selectionSize;

        float distanceToIndex = (x % selectionSize) / (float) (selectionSize);

        float leftRandom = random(selectionIndex, range);
        float rightRandom = random(selectionIndex + 1, range);

        noise += (1 - distanceToIndex) * leftRandom + distanceToIndex * rightRandom;

        selectionSize /= 2;
        range /= 2;

        range = Math.max(1, range);
    }

    return Math.round(noise * (noise < 0 ? -1 : 1));
}

private int random(int x, int range) {
    return (int) ((x + seed) ^ 10) % range;
}
\$\endgroup\$
  • 2
    \$\begingroup\$ Where did you take this noise function? This doesn't look like Perlin noise. \$\endgroup\$ – user6245072 May 23 '16 at 5:24
  • \$\begingroup\$ It is code taken from this video: youtu.be/Exuz4OWP7t8 I am not using unity, but I thought I could use it anyways. Should I use something else? \$\endgroup\$ – Panda May 23 '16 at 18:00
2
\$\begingroup\$

My bet is on integer division. Integer division doesn't always round down, it always cuts off the decimal part, so for negative values it is rounding up.

The reason this looks jagged is because the values you are feeding in jump up every time you cross an integer border in the negative x region.

Also with negative numbers the % operator isn't guaranteed to yield a positive result.

I bet that if you replace the first division and modulus operation with their floating point variants and then floor instead of just letting the integer division handle it, it will turn out normal.

\$\endgroup\$
0
\$\begingroup\$

That probably is a variant of a value noise implementation (which is slightly lower in quality than pure Perlin noise).

You can find the original Perlin noise implementation (written by Perlin himself) here (it's already in Java so you don't even have to translate it)

The array p is just a specific mix of 0-255 values, you can generate a new noise every time by varing the order of the values in this array (with a code like int p[256]; for (int n = 0, n < 256, n++) {int t = random(0, 255); while(p[t]) {t = random(0, 255);} p[t] = n;})

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.