1
\$\begingroup\$

In Perlin's implementation of his noise function, he uses an array to hash the input coordinates and later find the gradient vectors. But in Stefan Gustavson's implementation, a strange "permute" function is used:

vec4 permute(vec4 x)
{
  return mod289(((x*34.0)+1.0)*x);
}

vec4 mod289(vec4 x)
{
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

Then, it is used like this:

vec4 i = permute(permute(ix) + iy);

vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
vec4 gy = abs(gx) - 0.5 ;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;

I understand that the "*2.0 - 1.0" is for getting gx to the range -1 to +1, but I do not understand the rest of the hashing. How does this "permute" function work and why does it divided by 41.0?

Thanks.

\$\endgroup\$
2
\$\begingroup\$

That 41 is an arbitrary prime number value that happens to look good.

You want to values to be perceived as repeating as little as possible coming out of the hash function. One good way to do that is to use some prime numbers (or numbers with very few common denominators) as a scaling factor so they don't often reach a common multiple or denominator.

It's one of those things you tweak by trial-and-error.

41 is a prime number, 289 is 17*17.

The Least Common Multiple of both 41 and 17 is 697, 41 and 289 is 11849, which in theory one or the other (697 or 11849) would be how far coordinates have to go before the texture repeats.

In practice human perception might see a pattern emerge earlier and rounding errors may also play into this.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.