# Why does my Perlin Noise look "blocky"?

I tried to implement Perlin Noise by myself using just the theory (following flafla2.github.io/2014/08/09/perlinnoise.html). Unfortunately I was unable to achieve the look of the "original" Perlin Noise.

What's the reason the code below renders a blocky version of Perlin Noise?

What should I improve/change in the code so that it renders Perlin Noise without the artifacts?

I suspect there might be problem either in the way I interpolate or in the grads vector. The grads vector contains dot products of (random vector for lattice point) and (the size vector) – for all 4 nearby lattice points. (The random and size vectors are described in the very first link.)

GLSL Sandbox: http://glslsandbox.com/e#32663.0

float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }

vec2 hash(vec2 co) {
return fract (vec2(.5654654, -.65465) * dot (vec2(.654, 57.4), co));
}

float perlinNoise(vec2 uv) {
vec2 PT  = floor(uv);
vec2 pt  = fract(uv);
vec2 mmpt= smooth(pt);

dot(hash(PT + vec2(.0, 1.)), pt-vec2(.0, 1.)),   dot(hash(PT + vec2(1., 1.)), pt-vec2(1., 1.)),
dot(hash(PT + vec2(.0, .0)), pt-vec2(.0, .0)),   dot(hash(PT + vec2(1., .0)), pt-vec2(1., 0.))
);

}

float fbm(vec2 uv) {
float finalNoise = 0.;
finalNoise += .50000*perlinNoise(2.*uv);
finalNoise += .25000*perlinNoise(4.*uv);
finalNoise += .12500*perlinNoise(8.*uv);
finalNoise += .06250*perlinNoise(16.*uv);
finalNoise += .03125*perlinNoise(32.*uv);

return finalNoise;
}

void main() {
vec2 position = gl_FragCoord.xy / resolution.y;
gl_FragColor = vec4( vec3( fbm(3.*position) ), 1.0 );
}


The interpolation looks fine. The main problem here is that the hash function you're using isn't very good. If I look at just one octave, and visualize the hash result by outputting hash(PT).x, I get something like this:

This is supposed to be completely random per grid square, but you can see that it has a lot of diagonal line patterns in it (it almost looks like a checkerboard), so it's not a very random hash, and those patterns will show up in the noise produced by it.

The other problem is that your hash only returns gradient vectors in [0, 1], while they should be in [−1, 1] to get gradients in all directions. That part's easy to fix by remapping.

To fix those problems, I switched the code to use this hash function (which I learned from Mikkel Gjoel, and is probably due to a paper by W.J.J. Rey):

vec2 hash(vec2 co) {
float m = dot(co, vec2(12.9898, 78.233));
return fract(vec2(sin(m),cos(m))* 43758.5453) * 2. - 1.;
}


Note that due to the trig functions it's going to be a bit more expensive than your version. However, it considerably improves the appearance of the resulting noise:

• Thank you very much for your explanation. This is maybe off-topic, but I'll ask anyway; in some source codes that compute noise, people use vector vec3(1, 57, 113) to compute dot product with current coordinate (I suppose the aim is also to obtain a hash). Why this particular choice of constants (57 is approx. 1 radian in degrees, 133 = approx. 2*radian in degrees)? Is it because of periodicity in trig functions? I'm unable to google this. May 15 '16 at 18:55
• @sarasvati I'm not really sure, but a guess is that 57 and 113 are chosen because they're prime-ish numbers. (113 is prime; 57 isn't, but it's 3*19, so still kinda primey...if that's a thing.) Multiplying or modding by a prime-ish number tends to jumble up the bits, so it's not an uncommon ingredient in hashes. May 15 '16 at 19:15
• @cat I doubt GLSL has a PRNG, given that GLSL programs are deterministic. May 15 '16 at 22:20
• Looks like there are several potential new questions in this comment thread... May 16 '16 at 0:22
• I was having those artifacts and this rand() function fixed it. Problem is after I walked like 2km in my terrain, artifacts like the OPs started to show up again. It was using the hash function here: amindforeverprogramming.blogspot.com/2013/07/… that caused the artifacts to go away (Except at distances of 100km, bc of imprecision, but thats okay I just had to split into chunks and got that to work by hashing both values, which will let the perlin noise run nearly indefinitely). So, I'll leave this here to maybe help anyone who has the same issue. Oct 27 '19 at 20:01