Perlin noise glitch

1

I have an infinite map generator. It works well with positive coordinates. Positive coordinates generation 1

But on negative coordinates I have this trash: Negative coordinates broken generation 2

void generateChunk(int x0, int y0) {
    Chunk chunk = new Chunk(x0, y0);
    for(int yTile = 0; yTile < Chunk.CHUNK_SIZE; yTile++) {
        for(int xTile = 0; xTile < Chunk.CHUNK_SIZE; xTile++) {

            int pX = chunk.x0 + xTile;
            int pY = chunk.y0 + yTile;

            double perlinNoiseHeight = floorPerlinNoise.getHeight(pX, pY);;

            if(perlinNoiseHeight > BEACH_AREA) {
                chunk.setFloor(GrassTile.ID, xTile, yTile);
            } else if(perlinNoiseHeight > 0) {
                chunk.setFloor(SandTile.ID, xTile, yTile);
            } else {
                chunk.setFloor(WaterTile.ID, xTile, yTile);
            }
        }
    }
    saveChunk(chunk);
}

Perlin noise class:

package org.ixnomad.game.level.generation;

public class PerlinNoise {

    private double persistence, frequency, amplitude;
    private int octaves;
    private long seed;

    public PerlinNoise(double persistence, double frequency, double amplitude, int octaves, long seed) {
        this.persistence    = persistence;
        this.amplitude      = amplitude;
        this.frequency      = frequency;
        this.octaves        = octaves;
        this.seed           = seed;
    }

    public double getHeight(double x, double y) {
        return amplitude * total(x, y) + 0.4;
    }

    private double total(double i, double j) {
        double total = 0.0d;
        double _ampl = 1;
        double _freq = frequency;
        for(int k = 0; k < octaves; k++) {
            total += getValue(j * _freq + seed, i * _freq + seed) * _ampl;
            _ampl *= persistence;
            _freq *= 2;
        }
        return total;
    }

    private double getValue(double x, double y) {
        int xInt = (int) x;
        int yInt = (int) y;
        double xFrac = x - xInt;
        double yFrac = y - yInt;

        double n01 = noise(xInt-1, yInt-1);
        double n02 = noise(xInt+1, yInt-1);
        double n03 = noise(xInt-1, yInt+1);
        double n04 = noise(xInt+1, yInt+1);
        double n05 = noise(xInt-1, yInt  );
        double n06 = noise(xInt+1, yInt  );
        double n07 = noise(xInt  , yInt-1);
        double n08 = noise(xInt  , yInt+1);
        double n09 = noise(xInt  , yInt  );

        double n12 = noise(xInt+2, yInt-1);
        double n14 = noise(xInt+2, yInt+1);
        double n16 = noise(xInt+2, yInt  );

        double n23 = noise(xInt-1, yInt+2);
        double n24 = noise(xInt+1, yInt+2);
        double n28 = noise(xInt  , yInt+2);

        double n34 = noise(xInt+2, yInt+2);

        double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
        double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
        double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
        double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);

        double v1 = interpolate(x0y0, x1y0, xFrac);
        double v2 = interpolate(x0y1, x1y1, xFrac);
        return interpolate(v1, v2, yFrac);
    }

    private double interpolate(double x, double y, double frac) {
        double negFrac = 1.0 - frac;
        double negFraqSqr = negFrac * negFrac;
        double fac1 = 3.0 * negFraqSqr - 2.0 * negFraqSqr * negFrac;

        double fracSqr = frac * frac;
        double fac2 = 3.0 * fracSqr - 2.0 * fracSqr * frac;

        return x * fac1 + y * fac2;
    }

    private double noise(int x, int y) {
        int n = x + y * 57;
        n = (n << 13) ^ n;
        int t = (n * (n * n * 15713 + 789221) + 1376312589) & 0x7fffffff;
        return 1.0d - (double) (t * 0.931322574615478515625e-9);
    }

}

I have tried to solve this problem for a whole day, but I don't know, what I'm doing wrong. I thought that the problem is in bit shift (private double noise(double x, double y)), but the problem doesn't depend on it. I tried to use this Perlin's algoryth: https://mrl.nyu.edu/~perlin/noise/ But effect is the same.

java
game-engine
game-development
procedural-generation
asked on Stack Overflow Mar 10, 2020 by George Glebov • edited Mar 11, 2020 by Bashir

1 Answer

0

Good morning, I probably have sold the problem :D Jush should sleep and reload brains)

Just use the max value the integer can bring and move generate coordinates to half :D

int maxint = 0x07fffffff;
double perlinNoiseHeight = floorPerlinNoise.getHeight(pX + (maxint >> 1), pY + (maxint >> 1));

That is a simple solution, but it works) Negative coordinates

answered on Stack Overflow Mar 11, 2020 by George Glebov

User contributions licensed under CC BY-SA 3.0