perlin noise mysterious constant

If you check the sources of the library libnoise, you can see the following code:


double noise::GradientNoise3D (double fx, double fy, double fz, int ix,
  int iy, int iz, int seed)
{
  // Randomly generate a gradient vector given the integer coordinates of the
  // input value.  This implementation generates a random number and uses it
  // as an index into a normalized-vector lookup table.
  int vectorIndex = (
      X_NOISE_GEN    * ix
    + Y_NOISE_GEN    * iy
    + Z_NOISE_GEN    * iz
    + SEED_NOISE_GEN * seed)
    & 0xffffffff;
  vectorIndex ^= (vectorIndex >> SHIFT_NOISE_GEN);
  vectorIndex &= 0xff;

  double xvGradient = g_randomVectors[(vectorIndex << 2)    ];
  double yvGradient = g_randomVectors[(vectorIndex << 2) + 1];
  double zvGradient = g_randomVectors[(vectorIndex << 2) + 2];

  // Set up us another vector equal to the distance between the two vectors
  // passed to this function.
  double xvPoint = (fx - (double)ix);
  double yvPoint = (fy - (double)iy);
  double zvPoint = (fz - (double)iz);

  // Now compute the dot product of the gradient vector with the distance
  // vector.  The resulting value is gradient noise.  Apply a scaling value
  // so that this noise value ranges from -1.0 to 1.0.
  return ((xvGradient * xvPoint)
    + (yvGradient * yvPoint)
    + (zvGradient * zvPoint)) * 2.12;
}

See the constant 2.12? Why the heck is it needed? It is even rational, no approximation of a real number.

If you think of it what guarantee do you have that the dot product dot(Q - P, G), where G is a unit gradient vector is going to be between -1 and 1?

EDIT:
I think he should be dividing by sqrt(2). The gradient vector can have any orientation and the P - Q vector can be parallel to it and be almost sqrt(2) size.

On the second thought, maybe he really shouldn’t be multiplying by anything at all.

I knew I was right, the multiplication constant was a bug it seems. I’ve made some clouds with my own implementation of the algorithm, so I am pretty sure nothing needs to be multiplied:

Maybe you could tell me what lerp I should use in my program, the more numerically unstable one:

a + t * (b - a)

or the more stable one:

a * (1 - t) + t * b

it seems to me I am getting better images with the more stable one.

Be aware that libnoise is GPL, so if you use the code or base your work on the code, you must release your code with your application.

No, I didn’t base my code on it, only on the article by Perlin. But I did look at it. The libnoise code has dimension-specific (2 and 3) code on it, while mine does not and it apparently has strange bugs too (that constant) :slight_smile:

Looks like this constant is 3*sqrt(2)/2, but what does that means?