2D Perlin Noise Algorithm not working correctly

So I’m trying to write my own perlin noise algorithm at the moment but I’ve been stuck with this one problem for a long time

Here is my result:

And here’s my code (sorry it’s a bit messy, I’m not using a proper vector class at the moment):



private float dot(float x0, float y0, float x1, float y1) {
	return (x0 * x1) + (y0 * y1);
}

public float sample(float x, float y) {
	int gx0 = (int) Math.floor(x);
	int gy0 = (int) Math.floor(y);
	int gx1 = gx0 + 1;
	int gy1 = gy0 + 1;
	
	float dx0 = x - gx0;
	float dy0 = y - gy0;
	
	float dx1 = x - gx1;
	float dy1 = y - gy1;
	
	float w0 = dot(dx0, dy0, getVX(gx0, gy0), getVY(gx0, gy0));
	float w1 = dot(dx0, dy1, getVX(gx0, gy1), getVY(gx0, gy1));
	float w2 = dot(dx1, dy1, getVX(gx1, gy1), getVY(gx1, gy1));
	float w3 = dot(dx1, dy0, getVX(gx1, gy0), getVY(gx1, gy0));
	
	float sx = weigh(dx0);
	float sy = weigh(dy0);
	
	float a = lerp(sy, w0, w1);
	float b = lerp(sy, w2, w3);
	float h = lerp(sx, a, b);
	
	return h;
}

private float weigh(float x) {
	return 3 * (x * x) - 2 * (x * x * x);
}

private float lerp(float w, float a, float b) {
      return a + w * (b - a);
}

The functions getVX and getVY get the respective x and y components of the vectors at the grid points. I’m pretty sure this isn’t an issue with random generation of the gradients on the grid points but I can post this code if it will help!

Thanks in advanced :D!

From a quick glance…the lerp order isn’t consistent.

EDIT: I suppose I should say more: a left egde bottom-to-top, b = right edge top-to-bottom. b = lerp(sy, w3, w2);

This solution fixed the obvious issue thanks!

However now I’m, not so much an issue, but something weird where the values don’t seem to cover the entire range between -1 and 1. Occasionally 1 in every about 36 attempts i will get one value bigger than 0.7 but other than that they are mostly between -0.5 and 0.5. This can be worked around it doesn’t cause any major issue, but all other tutorials and images I’ve seen have values ranging all the way from -1 to 1!

The ranges you’ll see depend on your choice of random vector generation. And actually going all the way to [-1,1] isn’t such a great idea as you’re likely to get values that go outside of range due to compounding of errors if you combine samples. You just want to know that the range actually is and deal with scaling outside of the core routine if you want to not hamper you’re speed.

output range in value-gradient noise is always depending on the gradient/random generator.

some of the “original” perlin code use output scales like 0.188, 0.507, 0.936, 0.87, (1,2,3,4D) to match renderman output ranges. but even then it’s not -1 to +1. dont worry about it.

run a million samples to fetch your implementations range and scale then.

ofc : -1 to +1 -> 0 to 1 : x *= 0.5; x += 0.5;
and : 0 to 1 -> -1 to 1 : x *= 2.0; x -= 1.0;

the only noise i saw which generates exact 0.0 to 1.0 values is the simple value-lattice-noise, not gradient. tho’ then it still depends on the random-generator but those are usually nicely in range.