I translated the improved 3D perlin noise from this webside from c# to c++. But the resulting values are strange.
First lets look at the code:
#include "PerlinNoise.h"
PerlinNoise::PerlinNoise(int repeat)
{
this->repeat = repeat;
for (int i = 0; i < 256; ++i)
{
permutation[i] = i;
}
for (int i = 0; i < 256; ++i)
{
int swapIndex = rand() % 256;
std::swap(permutation[i], permutation[swapIndex]);
}
for (int x = 0; x<512; x++) {
p[x] = permutation[x % 256];
}
}
int PerlinNoise::inc(int num)
{
num++;
if (repeat > 0) num %= repeat;
return num;
}
float PerlinNoise::noise(float x, float y, float z)
{
if (repeat > 0) { // If we have any repeat on, change the coordinates to their "local" repetitions
x = fmodf(x, repeat);
y = fmodf(y, repeat);
z = fmodf(z, repeat);
}
int xi = (int)x & 255; // Calculate the "unit cube" that the point asked will be located in
int yi = (int)y & 255; // The left bound is ( |_x_|,|_y_|,|_z_| ) and the right bound is that
int zi = (int)z & 255; // plus 1. Next we calculate the location (from 0.0 to 1.0) in that cube.
float xf = x - static_cast<int>(x); // We also fade the location to smooth the result.
float yf = y - static_cast<int>(y);
float zf = z - static_cast<int>(z);
float u = fade(xf);
float v = fade(yf);
float w = fade(zf);
int aaa, aba, aab, abb, baa, bba, bab, bbb;
aaa = p[p[p[xi] + yi] + zi];
aba = p[p[p[xi] + inc(yi)] + zi];
aab = p[p[p[xi] + yi] + inc(zi)];
abb = p[p[p[xi] + inc(yi)] + inc(zi)];
baa = p[p[p[inc(xi)] + yi] + zi];
bba = p[p[p[inc(xi)] + inc(yi)] + zi];
bab = p[p[p[inc(xi)] + yi] + inc(zi)];
bbb = p[p[p[inc(xi)] + inc(yi)] + inc(zi)];
float x1, x2, y1, y2;
x1 = lerp(grad(aaa, xf, yf, zf), // The gradient function calculates the dot product between a pseudorandom
grad(baa, xf - 1, yf, zf), // gradient vector and the vector from the input coordinate to the 8
u); // surrounding points in its unit cube.
x2 = lerp(grad(aba, xf, yf - 1, zf), // This is all then lerped together as a sort of weighted average based on the faded (u,v,w)
grad(bba, xf - 1, yf - 1, zf), // values we made earlier.
u);
y1 = lerp(x1, x2, v);
x1 = lerp(grad(aab, xf, yf, zf - 1),
grad(bab, xf - 1, yf, zf - 1),
u);
x2 = lerp(grad(abb, xf, yf - 1, zf - 1),
grad(bbb, xf - 1, yf - 1, zf - 1),
u);
y2 = lerp(x1, x2, v);
return (lerp(y1, y2, w) + 1) / 2; // For convenience we bound it to 0 - 1 (theoretical min/max before is -1 - 1)
}
float PerlinNoise::grad(int hash, float x, float y, float z)
{
int h = hash & 15; // Take the hashed value and take the first 4 bits of it (15 == 0b1111)
float u = h < 8 /* 0b1000 */ ? x : y; // If the most significant bit (MSB) of the hash is 0 then set u = x. Otherwise y.
float v; // In Ken Perlin's original implementation this was another conditional operator (?:). I
// expanded it for readability.
if (h < 4 /* 0b0100 */) // If the first and second significant bits are 0 set v = y
v = y;
else if (h == 12 /* 0b1100 */ || h == 14 /* 0b1110*/)// If the first and second significant bits are 1 set v = x
v = x;
else // If the first and second significant bits are not equal (0/1, 1/0) set v = z
v = z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); // Use the last 2 bits to decide if u and v are positive or negative. Then return their addition.
}
float PerlinNoise::fade(float t)
{
// Fade function as defined by Ken Perlin. This eases coordinate values
// so that they will "ease" towards integral values. This ends up smoothing
// the final output.
return t * t * t * (t * (t * 6 - 15) + 10); // 6t^5 - 15t^4 + 10t^3
}
float PerlinNoise::lerp(float a, float b, float x)
{
return a + x * (b - a);
}
void main()
{
PerlinNoise perlinNoise(-1);
std::vector<float> results;
for (int i = 0; i < 10000; ++i)
{
results.push_back(perlinNoise.noise(static_cast<float>(i) * 0.1f, 0.0f, 0.0f));
}
}
And of cause the output:
x = 0.1 value = 0.45428 x = 0.2 value = 0.42896 x = 0.3 value = 0.43154 x = 0.4 value = 0.45872
x = 0.5 value = 0.5 x = 0.6 value = 0.54128 x = 0.7 value = 0.56846 x = 0.8 value = 0.57104
x = 0.9 value = 0.54572 x = 1 value = 0.5 x = 1.1 value = 0.450428 x = 1.2 value = 0.405792
x = 1.3 value = 0.374462 x = 1.4 value = 0.363488 x = 1.5 value = 0.375 x = 1.6 value = 0.404768
x = 1.7 value = 0.442922 x = 1.8 value = 0.476832 x = 1.9 value = 0.496148 x = 2 value = 0.5
x = 2.1 value = 0.5 x = 2.2 value = 0.5 x = 2.3 value = 0.5 x = 2.4 value = 0.5
x = 2.5 value = 0.5 x = 2.6 value = 0.5 x = 2.7 value = 0.5 x = 2.8 value = 0.5
x = 2.9 value = 0.5 x = 3 value = 0.5 x = 3.1 value = 0.5 x = 3.2 value = 0.5
x = 3.3 value = 0.5 x = 3.4 value = 0.5 x = 3.5 value = 0.5 x = 3.6 value = 0.5
x = 3.7 value = 0.5 x = 3.8 value = 0.5 x = 3.9 value = 0.5 x = 4 value = 0.5
x = 4.1 value = 0.496148 x = 4.2 value = 0.476832 x = 4.3 value = 0.442922 x = 4.4 value = 0.404768
x = 4.5 value = 0.375 x = 4.6 value = 0.363488 x = 4.7 value = 0.374462 x = 4.8 value = 0.405792
x = 4.9 value = 0.450428 x = 5 value = 0.5 x = 5.1 value = 0.553424 x = 5.2 value = 0.617376
x = 5.3 value = 0.682616 x = 5.4 value = 0.731744 x = 5.5 value = 0.75 x = 5.6 value = 0.731744
x = 5.7 value = 0.682616 x = 5.8 value = 0.617376 x = 5.9 value = 0.553424 x = 6 value = 0.5
x = 6.1 value = 0.450428 x = 6.2 value = 0.405792 x = 6.3 value = 0.374462 x = 6.4 value = 0.363488
x = 6.5 value = 0.375 x = 6.6 value = 0.404768 x = 6.7 value = 0.442922 x = 6.8 value = 0.476832
x = 6.9 value = 0.496148 x = 7 value = 0.5 x = 7.1 value = 0.503852 x = 7.2 value = 0.523168
x = 7.3 value = 0.557078 x = 7.4 value = 0.595232 x = 7.5 value = 0.625 x = 7.6 value = 0.636512
x = 7.7 value = 0.625538 x = 7.8 value = 0.594208 x = 7.9 value = 0.549572 x = 8 value = 0.5
x = 8.1 value = 0.446576 x = 8.2 value = 0.382624 x = 8.3 value = 0.317384 x = 8.4 value = 0.268256
x = 8.5 value = 0.25 x = 8.6 value = 0.268256 x = 8.7 value = 0.317384 x = 8.8 value = 0.382624
x = 8.9 value = 0.446576 x = 9 value = 0.5 x = 9.1 value = 0.553424 x = 9.2 value = 0.617376
x = 9.3 value = 0.682616 x = 9.4 value = 0.731744 x = 9.5 value = 0.75 x = 9.6 value = 0.731744
x = 9.7 value = 0.682616 x = 9.8 value = 0.617376 x = 9.9 value = 0.553424 x = 10 value = 0.5
x = 10.1 value = 0.450428 x = 10.2 value = 0.405792 x = 10.3 value = 0.374462 x = 10.4 value = 0.363488
x = 10.5 value = 0.375 x = 10.6 value = 0.404768 x = 10.7 value = 0.442922 x = 10.8 value = 0.476832
x = 10.9 value = 0.496148 x = 11 value = 0.5 x = 11.1 value = 0.496148 x = 11.2 value = 0.476832
x = 11.3 value = 0.442922 x = 11.4 value = 0.404768 x = 11.5 value = 0.375 x = 11.6 value = 0.363488
x = 11.7 value = 0.374462 x = 11.8 value = 0.405792 x = 11.9 value = 0.450428 x = 12 value = 0.5
x = 12.1 value = 0.549572 x = 12.2 value = 0.594208 x = 12.3 value = 0.625538 x = 12.4 value = 0.636512
x = 12.5 value = 0.625 x = 12.6 value = 0.595232 x = 12.7 value = 0.557078 x = 12.8 value = 0.523168
x = 12.9 value = 0.503852 x = 13 value = 0.5 x = 13.1 value = 0.496148 x = 13.2 value = 0.476832
x = 13.3 value = 0.442922 x = 13.4 value = 0.404768 x = 13.5 value = 0.375 x = 13.6 value = 0.363488
x = 13.7 value = 0.374462 x = 13.8 value = 0.405792 x = 13.9 value = 0.450428 x = 14 value = 0.5
x = 14.1 value = 0.54572 x = 14.2 value = 0.57104 x = 14.3 value = 0.56846 x = 14.4 value = 0.54128
x = 14.5 value = 0.5 x = 14.6 value = 0.45872 x = 14.7 value = 0.43154 x = 14.8 value = 0.42896
x = 14.9 value = 0.45428 x = 15 value = 0.5 x = 15.1 value = 0.54572 x = 15.2 value = 0.57104
x = 15.3 value = 0.56846 x = 15.4 value = 0.54128 x = 15.5 value = 0.5 x = 15.6 value = 0.45872
x = 15.7 value = 0.43154 x = 15.8 value = 0.42896 x = 15.9 value = 0.45428 x = 16 value = 0.5
x = 16.1 value = 0.549572 x = 16.2 value = 0.594208 x = 16.3 value = 0.625538 x = 16.4 value = 0.636512
x = 16.5 value = 0.625 x = 16.6 value = 0.595232 x = 16.7 value = 0.557078 x = 16.8 value = 0.523168
x = 16.9 value = 0.503852 x = 17 value = 0.5 x = 17.1 value = 0.496148 x = 17.2 value = 0.476832
x = 17.3 value = 0.442922 x = 17.4 value = 0.404768 x = 17.5 value = 0.375 x = 17.6 value = 0.363488
x = 17.7 value = 0.374462 x = 17.8 value = 0.405792 x = 17.9 value = 0.450428 x = 18 value = 0.5
x = 18.1 value = 0.549572 x = 18.2 value = 0.594208 x = 18.3 value = 0.625538 x = 18.4 value = 0.636512
x = 18.5 value = 0.625 x = 18.6 value = 0.595232 x = 18.7 value = 0.557078 x = 18.8 value = 0.523168
x = 18.9 value = 0.503852 x = 19 value = 0.5 x = 19.1 value = 0.503852 x = 19.2 value = 0.523168
x = 19.3 value = 0.557078 x = 19.4 value = 0.595232 x = 19.5 value = 0.625 x = 19.6 value = 0.636512
x = 19.7 value = 0.625538 x = 19.8 value = 0.594208 x = 19.9 value = 0.549572 x = 20 value = 0.5
x = 20.1 value = 0.45428 x = 20.2 value = 0.42896 x = 20.3 value = 0.43154 x = 20.4 value = 0.45872
x = 20.5 value = 0.5 x = 20.6 value = 0.54128 x = 20.7 value = 0.56846 x = 20.8 value = 0.57104
x = 20.9 value = 0.54572 x = 21 value = 0.5 x = 21.1 value = 0.450428 x = 21.2 value = 0.405792
x = 21.3 value = 0.374462 x = 21.4 value = 0.363488 x = 21.5 value = 0.375 x = 21.6 value = 0.404768
x = 21.7 value = 0.442922 x = 21.8 value = 0.476832 x = 21.9 value = 0.496148 x = 22 value = 0.5
x = 22.1 value = 0.5 x = 22.2 value = 0.5 x = 22.3 value = 0.5 x = 22.4 value = 0.5
x = 22.5 value = 0.5 x = 22.6 value = 0.5 x = 22.7 value = 0.5 x = 22.8 value = 0.5
x = 22.9 value = 0.5 x = 23 value = 0.5 x = 23.1 value = 0.503852 x = 23.2 value = 0.523168
x = 23.3 value = 0.557078 x = 23.4 value = 0.595232 x = 23.5 value = 0.625 x = 23.6 value = 0.636512
x = 23.7 value = 0.625538 x = 23.8 value = 0.594208 x = 23.9 value = 0.549572 x = 24 value = 0.5
x = 24.1 value = 0.45428 x = 24.2 value = 0.42896 x = 24.3 value = 0.43154 x = 24.4 value = 0.45872
x = 24.5 value = 0.5 x = 24.6 value = 0.54128 x = 24.7 value = 0.56846 x = 24.8 value = 0.57104
x = 24.9 value = 0.54572 x = 25 value = 0.5 x = 25.1 value = 0.450428 x = 25.2 value = 0.405792
x = 25.3 value = 0.374462 x = 25.4 value = 0.363488 x = 25.5 value = 0.375 x = 25.6 value = 0.404768
x = 25.7 value = 0.442922 x = 25.8 value = 0.476832 x = 25.9 value = 0.496148 x = 26 value = 0.5
x = 26.1 value = 0.5 x = 26.2 value = 0.5 x = 26.3 value = 0.5 x = 26.4 value = 0.5
x = 26.5 value = 0.5 x = 26.6 value = 0.5 x = 26.7 value = 0.5 x = 26.8 value = 0.5
x = 26.9 value = 0.5 x = 27 value = 0.5 x = 27.1 value = 0.503852 x = 27.2 value = 0.523168
x = 27.3 value = 0.557078 x = 27.4 value = 0.595232 x = 27.5 value = 0.625 x = 27.6 value = 0.636512
x = 27.7 value = 0.625538 x = 27.8 value = 0.594208 x = 27.9 value = 0.549572 x = 28 value = 0.5
x = 28.1 value = 0.450428 x = 28.2 value = 0.405792 x = 28.3 value = 0.374462 x = 28.4 value = 0.363488
x = 28.5 value = 0.375 x = 28.6 value = 0.404768 x = 28.7 value = 0.442922 x = 28.8 value = 0.476832
x = 28.9 value = 0.496148 x = 29 value = 0.5 x = 29.1 value = 0.503852 x = 29.2 value = 0.523168
x = 29.3 value = 0.557078 x = 29.4 value = 0.595232 x = 29.5 value = 0.625 x = 29.6 value = 0.636512
x = 29.7 value = 0.625538 x = 29.8 value = 0.594208 x = 29.9 value = 0.549572 x = 30 value = 0.5
x = 30.1 value = 0.446576 x = 30.2 value = 0.382623 x = 30.3 value = 0.317383 x = 30.4 value = 0.268256
x = 30.5 value = 0.25 x = 30.6 value = 0.268256 x = 30.7 value = 0.317384 x = 30.8 value = 0.382625
x = 30.9 value = 0.446576 x = 31 value = 0.5 x = 31.1 value = 0.54572 x = 31.2 value = 0.57104
x = 31.3 value = 0.56846 x = 31.4 value = 0.54128 x = 31.5 value = 0.5 x = 31.6 value = 0.45872
x = 31.7 value = 0.43154 x = 31.8 value = 0.42896 x = 31.9 value = 0.45428 x = 32 value = 0.5
x = 32.1 value = 0.545721 x = 32.2 value = 0.57104 x = 32.3 value = 0.56846 x = 32.4 value = 0.541279
x = 32.5 value = 0.5 x = 32.6 value = 0.458719 x = 32.7 value = 0.43154 x = 32.8 value = 0.42896
x = 32.9 value = 0.45428 x = 33 value = 0.5 x = 33.1 value = 0.545721 x = 33.2 value = 0.57104
x = 33.3 value = 0.56846 x = 33.4 value = 0.541279 x = 33.5 value = 0.5 x = 33.6 value = 0.458719
x = 33.7 value = 0.43154 x = 33.8 value = 0.42896 x = 33.9 value = 0.45428 x = 34 value = 0.5
x = 34.1 value = 0.545721 x = 34.2 value = 0.57104 x = 34.3 value = 0.56846 x = 34.4 value = 0.541279
x = 34.5 value = 0.5 x = 34.6 value = 0.458719 x = 34.7 value = 0.43154 x = 34.8 value = 0.42896
x = 34.9 value = 0.45428 x = 35 value = 0.5 x = 35.1 value = 0.553425 x = 35.2 value = 0.617377
x = 35.3 value = 0.682616 x = 35.4 value = 0.731745 x = 35.5 value = 0.75 x = 35.6 value = 0.731743
x = 35.7 value = 0.682616 x = 35.8 value = 0.617377 x = 35.9 value = 0.553423 x = 36 value = 0.5
x = 36.1 value = 0.450427 x = 36.2 value = 0.405792 x = 36.3 value = 0.374462 x = 36.4 value = 0.363488
x = 36.5 value = 0.375 x = 36.6 value = 0.404769 x = 36.7 value = 0.442922 x = 36.8 value = 0.476832
x = 36.9 value = 0.496148 x = 37 value = 0.5 x = 37.1 value = 0.503852 x = 37.2 value = 0.523168
x = 37.3 value = 0.557078 x = 37.4 value = 0.595233 x = 37.5 value = 0.625 x = 37.6 value = 0.636512
x = 37.7 value = 0.625538 x = 37.8 value = 0.594208 x = 37.9 value = 0.549571 x = 38 value = 0.5
x = 38.1 value = 0.446575 x = 38.2 value = 0.382623 x = 38.3 value = 0.317384 x = 38.4 value = 0.268255
x = 38.5 value = 0.25 x = 38.6 value = 0.268257 x = 38.7 value = 0.317384 x = 38.8 value = 0.382623
x = 38.9 value = 0.446577 x = 39 value = 0.5 x = 39.1 value = 0.545721 x = 39.2 value = 0.57104
x = 39.3 value = 0.56846 x = 39.4 value = 0.541279 x = 39.5 value = 0.5 x = 39.6 value = 0.458719
x = 39.7 value = 0.43154 x = 39.8 value = 0.42896 x = 39.9 value = 0.45428 x = 40 value = 0.5
x = 40.1 value = 0.545721 x = 40.2 value = 0.57104 x = 40.3 value = 0.56846 x = 40.4 value = 0.541279
x = 40.5 value = 0.5 x = 40.6 value = 0.458719 x = 40.7 value = 0.43154 x = 40.8 value = 0.42896
x = 40.9 value = 0.45428 x = 41 value = 0.5 x = 41.1 value = 0.549573 x = 41.2 value = 0.594208
x = 41.3 value = 0.625538 x = 41.4 value = 0.636512 x = 41.5 value = 0.625 x = 41.6 value = 0.595231
x = 41.7 value = 0.557078 x = 41.8 value = 0.523168 x = 41.9 value = 0.503852 x = 42 value = 0.5
x = 42.1 value = 0.496148 x = 42.2 value = 0.476832 x = 42.3 value = 0.442922 x = 42.4 value = 0.404767
x = 42.5 value = 0.375 x = 42.6 value = 0.363488 x = 42.7 value = 0.374462 x = 42.8 value = 0.405792
x = 42.9 value = 0.450429 x = 43 value = 0.5 x = 43.1 value = 0.545721 x = 43.2 value = 0.57104
x = 43.3 value = 0.56846 x = 43.4 value = 0.541279 x = 43.5 value = 0.5 x = 43.6 value = 0.458719
x = 43.7 value = 0.43154 x = 43.8 value = 0.42896 x = 43.9 value = 0.45428 x = 44 value = 0.5
x = 44.1 value = 0.553425 x = 44.2 value = 0.617377 x = 44.3 value = 0.682616 x = 44.4 value = 0.731745
x = 44.5 value = 0.75 x = 44.6 value = 0.731743 x = 44.7 value = 0.682616 x = 44.8 value = 0.617377
x = 44.9 value = 0.553423 x = 45 value = 0.5 x = 45.1 value = 0.454279 x = 45.2 value = 0.42896
x = 45.3 value = 0.43154 x = 45.4 value = 0.458721 x = 45.5 value = 0.5 x = 45.6 value = 0.541281
x = 45.7 value = 0.56846 x = 45.8 value = 0.57104 x = 45.9 value = 0.54572 x = 46 value = 0.5
x = 46.1 value = 0.454279 x = 46.2 value = 0.42896 x = 46.3 value = 0.43154 x = 46.4 value = 0.458721
x = 46.5 value = 0.5 x = 46.6 value = 0.541281 x = 46.7 value = 0.56846 x = 46.8 value = 0.57104
x = 46.9 value = 0.54572 x = 47 value = 0.5 x = 47.1 value = 0.450427 x = 47.2 value = 0.405792
x = 47.3 value = 0.374462 x = 47.4 value = 0.363488 x = 47.5 value = 0.375 x = 47.6 value = 0.404769
x = 47.7 value = 0.442922 x = 47.8 value = 0.476832 x = 47.9 value = 0.496148 x = 48 value = 0.5
x = 48.1 value = 0.5 x = 48.2 value = 0.5 x = 48.3 value = 0.5 x = 48.4 value = 0.5
x = 48.5 value = 0.5 x = 48.6 value = 0.5 x = 48.7 value = 0.5 x = 48.8 value = 0.5
x = 48.9 value = 0.5 x = 49 value = 0.5 x = 49.1 value = 0.5 x = 49.2 value = 0.5
x = 49.3 value = 0.5 x = 49.4 value = 0.5 x = 49.5 value = 0.5 x = 49.6 value = 0.5
x = 49.7 value = 0.5 x = 49.8 value = 0.5 x = 49.9 value = 0.5 x = 50 value = 0.5
x = 50.1 value = 0.496148 x = 50.2 value = 0.476832 x = 50.3 value = 0.442922 x = 50.4 value = 0.404767
x = 50.5 value = 0.375 x = 50.6 value = 0.363488 x = 50.7 value = 0.374462 x = 50.8 value = 0.405792
x = 50.9 value = 0.450429 x = 51 value = 0.5 x = 51.1 value = 0.545721 x = 51.2 value = 0.57104
x = 51.3 value = 0.56846 x = 51.4 value = 0.541279 x = 51.5 value = 0.5 x = 51.6 value = 0.458719
x = 51.7 value = 0.43154 x = 51.8 value = 0.42896 x = 51.9 value = 0.45428 x = 52 value = 0.5
As you can see there are blocks of 0.5 values. How can I change the code, so that these 0.5 values turn into correct perlin noise value?