Noise Problem

Hi everyone, I’m in the process of creating a really simple game like terraria, just for fun and as a challenge for myself. I’m currently in the process of making the terrain generator, and I kind of struggle with all these noise functions… I’ve looked over on the web and I found the j3d library for a perlin noise function. Here’s a simple test code I wrote :


PerlinNoiseGenerator p = new PerlinNoiseGenerator("My seed".hashCode());
		for (int i = 0; i < 30; i++) {
			System.out.println(p.noise1(i));
		}

The only thing that’s comming out of this is 0.0 and -0.0… “wat.”. Does anyone know why it’s doing this(/another good library or source code)? I had a library in C# when I was using XNA that was doing essentially the same thing… but it was working!

thanks for your time!

This is noise for java written by Perlin himself. It’s what I use:


// Copyright 2001 Ken Perlin
public final class Noise {

    public static int seed = 100;
    private static final int P = 8;
    private static final int B = 1 << P;
    private static final int M = B - 1;
    private static final int NP = 8;
    private static final int N = 1 << NP;
    //private static final int NM = N-1;
    private static int p[] = new int[B + B + 2];
    private static double g2[][] = new double[B + B + 2][2];
    private static double g1[] = new double[B + B + 2];
    //private static int start = 1;
    private static double[][] points = new double[32][3];

    static {
        init();
    }

    private static double lerp(double t, double a, double b) {
        return a + t * (b - a);
    }

    private static double s_curve(double t) {
        return t * t * (3 - t - t);
    }

    public static double noise(double x) {

        int bx0, bx1;
        double rx0, rx1, sx, t, u, v;
        t = x + N;
        bx0 = ((int) t) & M;
        bx1 = (bx0 + 1) & M;
        rx0 = t - (int) t;
        rx1 = rx0 - 1;

        sx = s_curve(rx0);
        u = rx0 * g1[p[bx0]];
        v = rx1 * g1[p[bx1]];

        return lerp(sx, u, v);
    }

    public static double noise(double x, double y) {

        int bx0, bx1, by0, by1, b00, b10, b01, b11;
        double rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v, q[];
        int i, j;

        t = x + N;
        bx0 = ((int) t) & M;
        bx1 = (bx0 + 1) & M;
        rx0 = t - (int) t;
        rx1 = rx0 - 1;

        t = y + N;
        by0 = ((int) t) & M;
        by1 = (by0 + 1) & M;
        ry0 = t - (int) t;
        ry1 = ry0 - 1;

        i = p[bx0];
        j = p[bx1];

        b00 = p[i + by0];
        b10 = p[j + by0];
        b01 = p[i + by1];
        b11 = p[j + by1];

        sx = s_curve(rx0);
        sy = s_curve(ry0);

        q = g2[b00];
        u = rx0 * q[0] + ry0 * q[1];
        q = g2[b10];
        v = rx1 * q[0] + ry0 * q[1];
        a = lerp(sx, u, v);

        q = g2[b01];
        u = rx0 * q[0] + ry1 * q[1];
        q = g2[b11];
        v = rx1 * q[0] + ry1 * q[1];
        b = lerp(sx, u, v);

        return lerp(sy, a, b);
    }

    static double noise(double x, double y, double z) {

        int bx, by, bz, b0, b1, b00, b10, b01, b11;
        double rx0, rx1, ry0, ry1, rz, sx, sy, sz, a, b, c, d, u, v, q[];

        bx = (int) Math.IEEEremainder(Math.floor(x), B);
        if (bx < 0) {
            bx += B;
        }
        rx0 = x - Math.floor(x);
        rx1 = rx0 - 1;

        by = (int) Math.IEEEremainder(Math.floor(y), B);
        if (by < 0) {
            by += B;
        }
        ry0 = y - Math.floor(y);
        ry1 = ry0 - 1;

        bz = (int) Math.IEEEremainder(Math.floor(z), B);
        if (bz < 0) {
            bz += B;
        }
        rz = z - Math.floor(z);

        if (bx < 0 || bx >= B + B + 2) {
            System.out.println(bx);
        }

        b0 = p[bx];

        bx++;

        b1 = p[bx];

        b00 = p[b0 + by];
        b10 = p[b1 + by];

        by++;

        b01 = p[b0 + by];
        b11 = p[b1 + by];

        sx = s_curve(rx0);
        sy = s_curve(ry0);
        sz = s_curve(rz);

        q = G(b00 + bz);
        u = rx0 * q[0] + ry0 * q[1] + rz * q[2];
        q = G(b10 + bz);
        v = rx1 * q[0] + ry0 * q[1] + rz * q[2];
        a = lerp(sx, u, v);
        q = G(b01 + bz);
        u = rx0 * q[0] + ry1 * q[1] + rz * q[2];
        q = G(b11 + bz);
        v = rx1 * q[0] + ry1 * q[1] + rz * q[2];
        b = lerp(sx, u, v);
        c = lerp(sy, a, b);
        bz++;
        rz--;
        q = G(b00 + bz);
        u = rx0 * q[0] + ry0 * q[1] + rz * q[2];
        q = G(b10 + bz);
        v = rx1 * q[0] + ry0 * q[1] + rz * q[2];
        a = lerp(sx, u, v);
        q = G(b01 + bz);
        u = rx0 * q[0] + ry1 * q[1] + rz * q[2];
        q = G(b11 + bz);
        v = rx1 * q[0] + ry1 * q[1] + rz * q[2];
        b = lerp(sx, u, v);
        d = lerp(sy, a, b);

        return lerp(sz, c, d);
    }

    private static double[] G(int i) {
        return points[i % 32];
    }

    private static void init() {
        int i, j, k;
        double u, v, w, U, V, W, Hi, Lo;
        java.util.Random r = new java.util.Random(seed);
        for (i = 0; i < B; i++) {
            p[i] = i;
            g1[i] = 2 * r.nextDouble() - 1;

            do {
                u = 2 * r.nextDouble() - 1;
                v = 2 * r.nextDouble() - 1;
            } while (u * u + v * v > 1
                    || Math.abs(u) > 2.5 * Math.abs(v)
                    || Math.abs(v) > 2.5 * Math.abs(u)
                    || Math.abs(Math.abs(u) - Math.abs(v)) < .4);
            g2[i][0] = u;
            g2[i][1] = v;
            normalize2(g2[i]);

            do {
                u = 2 * r.nextDouble() - 1;
                v = 2 * r.nextDouble() - 1;
                w = 2 * r.nextDouble() - 1;
                U = Math.abs(u);
                V = Math.abs(v);
                W = Math.abs(w);
                Lo = Math.min(U, Math.min(V, W));
                Hi = Math.max(U, Math.max(V, W));
            } while (u * u + v * v + w * w > 1 || Hi > 4 * Lo
                    || Math.min(Math.abs(U - V), Math.min(Math.abs(U - W), Math.abs(V - W))) < .2);
        }

        while (--i > 0) {
            k = p[i];
            j = (int) (r.nextLong() & M);
            p[i] = p[j];
            p[j] = k;
        }
        for (i = 0; i < B + 2; i++) {
            p[B + i] = p[i];
            g1[B + i] = g1[i];
            for (j = 0; j < 2; j++) {
                g2[B + i][j] = g2[i][j];
            }
        }

        points[3][0] = points[3][1] = points[3][2] = Math.sqrt(1. / 3);
        double r2 = Math.sqrt(1. / 2);
        double s = Math.sqrt(2 + r2 + r2);

        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                points[i][j] = (i == j ? 1 + r2 + r2 : r2) / s;
            }
        }
        for (i = 0; i <= 1; i++) {
            for (j = 0; j <= 1; j++) {
                for (k = 0; k <= 1; k++) {
                    int n = i + j * 2 + k * 4;
                    if (n > 0) {
                        for (int m = 0; m < 4; m++) {
                            points[4 * n + m][0] = (i == 0 ? 1 : -1) * points[m][0];
                            points[4 * n + m][1] = (j == 0 ? 1 : -1) * points[m][1];
                            points[4 * n + m][2] = (k == 0 ? 1 : -1) * points[m][2];
                        }
                    }
                }
            }
        }
    }

    private static void normalize2(double v[]) {
        double s;
        s = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
        v[0] = v[0] / s;
        v[1] = v[1] / s;
    }
}


I’m gonna test it in a minute after my maths homework (lol kinda related except it’s probabilities(boring)) but thanks alot!

I just tried it, like that :



public static void main(String[] args) {
		Noise p = new Noise(45643);
		System.out.println("=====noise=====");
		for (int i = 0; i < 30; i++) {
			System.out.println(p.noise(i));
		}
		System.out.println("=====noise=====");
	}


It outputs 0.0 everywhere!!

Does anyone else know how to use this algorithm? I seem to misunderstand the concept of noise I think…

You need to use not integer coordinates something like (i/30) perlin noise is 0 at integer values:

wow this helps so much! I love this image, I saved it on my desktop :persecutioncomplex:

Local overview of noise kernels (of this type): http://www.java-gaming.org/topics/noise-bandpassed-white/27071/view.html

Note: integer coordinates being zero is only true for gradient noise.

@kaffiene: Perlin’s noise code pretty much always targets a direct hardware implementation. Much much faster and at the same time higher quality versions are available.