<p>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 <code>hash(PT).x</code>, I get something like this:</p>

<p><a href="https://i.sstatic.net/LcFJV.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/LcFJV.png" alt="bad hash function"></a></p>

<p>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.</p>

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

<p>To fix those problems, I switched the code to use this hash function (which I learned from Mikkel Gjoel, and <a href="https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner/">is probably due to a paper by W.J.J. Rey</a>):</p>

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

<p>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:</p>

<p><a href="https://i.sstatic.net/ND8Es.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ND8Es.png" alt="fbm noise with better hash function"></a></p>

CC BY-SA 3.0
2016-05-15T18:55:16.090Z
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.
sarasvati
CC BY-SA 3.0
2016-05-15T19:15:58.503Z
@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.
Nathan Reed
CC BY-SA 3.0
2016-05-15T20:41:06.323Z
What are the magic numbers?
cat
CC BY-SA 3.0
2016-05-15T21:04:08.753Z
@cat Not sure how Mikkel came up with them. They may just be random / arbitrarily chosen values.
Nathan Reed
CC BY-SA 3.0
2016-05-15T21:05:05.290Z
@NathanReed Doesn't GLSL have an RNG / PRNG? Why not use that or hardware entropy over hardcoded arbitrary constants?
cat
CC BY-SA 3.0
2016-05-15T21:10:23.537Z
@cat Well any PRNG or hash function has hardcoded constants in its implementation. And anyway a PRNG is not what you want for this application; you want a hash function. You could use a PRNG as a hash by re-seeding it every time, but a lot of PRNGs don't give good results when used that way; they're primarily designed to give good results in the sequence generated from one seed.
Nathan Reed
CC BY-SA 3.0
2016-05-15T22:20:40.880Z
@cat I doubt GLSL has a PRNG, given that GLSL programs are deterministic.
Criticize SE actions means ban
CC BY-SA 3.0
2016-05-15T22:32:31.670Z
@immibis Shows what I know, I thought GLSL was at least turing-complete.
cat
CC BY-SA 3.0
2016-05-16T00:22:52.760Z
Looks like there are several potential new questions in this comment thread...
trichoplax is on Codidact now
CC BY-SA 3.0
2016-05-16T01:28:36.453Z
@cat Being deterministic does not preclude being Turing-complete.
Criticize SE actions means ban
CC BY-SA 3.0
2016-05-16T01:33:17.547Z
@immibis I think I misinterpreted your comment as "it's decidable whether a given program will halt" not "deterministic side-effects", because I can read. I'll shut up now :P
cat
CC BY-SA 3.0
2016-05-17T09:11:15.923Z
The math speak here is: 57 and 113 are coprimes.  GCD(57,133)=1.  And 57 is square free.
MB Reynolds
CC BY-SA 4.0
2019-10-27T20:01:07.667Z
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: http://amindforeverprogramming.blogspot.com/2013/07/random-floats-in-glsl-330.html 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.
Nicholas Pipitone
CC BY-SA 3.0
2016-05-15T18:38:14.730Z
2016-05-16T21:52:56.627Z
2017-05-23T12:39:19.850Z
Nathan Reed
<p>I tried to implement Perlin Noise <em>by myself</em> 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.</p>

<p>What's the reason the code below renders a blocky version of Perlin Noise?</p>

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

<p>I suspect there might be problem either in the way I interpolate or in the <code>grads</code> vector. The <code>grads</code> 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.)</p>

<p>GLSL Sandbox: <a href="http://glslsandbox.com/e#32663.0" rel="noreferrer">http://glslsandbox.com/e#32663.0</a></p>

<p><a href="https://i.sstatic.net/okckE.png" rel="noreferrer"><img src="https://i.sstatic.net/okckE.png" alt="Artifacts in the noise"></a></p>

<pre><code>float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }
vec2 smooth(vec2 x) { return vec2(fade(x.x), fade(x.y)); }

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);

    vec4 grads = vec4(
        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.))
    );

    return 5.*mix (mix (grads.z, grads.w, mmpt.x), mix (grads.x, grads.y, mmpt.x), mmpt.y);
}

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 );
}
</code></pre>

<glsl><noise><artifacts>
Why does my Perlin Noise look "blocky"?
sarasvati
# Why does my Perlin Noise look "blocky"?

(Asked by: username_0 on 2016-05-15)

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>

[![Artifacts in the noise](https://i.sstatic.net/okckE.png)](https://i.sstatic.net/okckE.png)

```
float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }
vec2 smooth(vec2 x) { return vec2(fade(x.x), fade(x.y)); }

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);

    vec4 grads = vec4(
        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.))
    );

    return 5.*mix (mix (grads.z, grads.w, mmpt.x), mix (grads.x, grads.y, mmpt.x), mmpt.y);
}

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 );
}

```

**Tags:** glsl, noise, artifacts


---

## 1 answers

### Answer by username_1 on 2016-05-15. Score: 24 | Accepted answer

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:

[![bad hash function](https://i.sstatic.net/LcFJV.png)](https://i.sstatic.net/LcFJV.png)

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](https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner/)):

```
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:

[![fbm noise with better hash function](https://i.sstatic.net/ND8Es.png)](https://i.sstatic.net/ND8Es.png)

> **Comments:**
> **username_0**: 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.  
> **username_1**: @username_0 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.  
> **username_2**: What are the magic numbers?  
> **username_1**: @username_2 Not sure how Mikkel came up with them. They may just be random / arbitrarily chosen values.  
> **username_2**: @username_1 Doesn't GLSL have an RNG / PRNG? Why not use that or hardware entropy over hardcoded arbitrary constants?  
> **username_1**: @username_2 Well any PRNG or hash function has hardcoded constants in its implementation. And anyway a PRNG is not what you want for this application; you want a hash function. You could use a PRNG as a hash by re-seeding it every time, but a lot of PRNGs don't give good results when used that way; they're primarily designed to give good results in the sequence generated from one seed.  
> **username_3**: @username_2 I doubt GLSL has a PRNG, given that GLSL programs are deterministic.  
> **username_2**: @immibis Shows what I know, I thought GLSL was at least turing-complete.  
> **username_4**: Looks like there are several potential new questions in this comment thread...  
> **username_3**: @username_2 Being deterministic does not preclude being Turing-complete.  
> **username_2**: @immibis I think I misinterpreted your comment as "it's decidable whether a given program will halt" not "deterministic side-effects", because I can read. I'll shut up now :P  
> **username_5**: The math speak here is: 57 and 113 are coprimes.  GCD(57,133)=1.  And 57 is square free.  
> **username_6**: 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: http://amindforeverprogramming.blogspot.com/2013/07/random-floats-in-glsl-330.html 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.  

---

