# Wonky perlin noise

I am quite new to the wondrous world of "Procedural Textures", and I am trying to create a double precission perlin noise algorithm.

I am almost done with it except for the fact that the coordinates seem to be off, any idea what I've done wrong? Here's the code:


public static class Noise {
static int[] p = new int[Convert.ToInt32(Math.Pow(2,16))];
public static vector2dDouble v1i;
public static vector2dDouble v2i;
public static vector2dDouble v3i;
public static vector2dDouble v4i;

public static double[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector3 offset) {
double[,] noiseMap = new double[mapWidth, mapHeight];

System.Random prng = new System.Random(seed);
Vector2[] octaveOffsets = new Vector2[octaves];
for (int i = 0; i < octaves; i++) {
float offsetX = prng.Next(-100000, 100000) + offset.x;
float offsetY = prng.Next(-100000, 100000) + offset.z;
octaveOffsets[i] = new Vector2(offsetX, offsetY);
}

if (scale <= 0) {
scale = 0.0001f;
}

float maxNoiseHeight = float.MinValue;
float minNoiseHeight = float.MaxValue;

float halfWidth = mapWidth / 2f;
float halfHeight = mapHeight / 2f;

for (int y = 0; y < mapHeight; y++) {
for (int x = 0; x < mapWidth; x++) {

float amplitude = 1;
float frequency = 1;
double noiseHeight = 0;

for (int i = 0; i < octaves; i++) {
double sampleX = (double)(x - halfWidth) / scale * frequency + octaveOffsets[i].x + 0.001;
double sampleY = (double)(y - halfHeight) / scale * frequency + octaveOffsets[i].y + 0.001;

double perlinValue = Noise2d(sampleX, sampleY);
noiseHeight += perlinValue * amplitude;
//Debug.Log(perlinValue);

amplitude *= persistance;
frequency *= lacunarity;
}

if (noiseHeight > maxNoiseHeight) {
maxNoiseHeight = (float)noiseHeight;
}
else if (noiseHeight < minNoiseHeight) {
minNoiseHeight = (float)noiseHeight;
}
noiseMap[x, y] = noiseHeight;
}
}

for (int y = 0; y < noiseMap.GetLength(1); y++) {
for (int x = 0; x < noiseMap.GetLength(0); x++) {
noiseMap[x, y] = (double)Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, (float)noiseMap[x, y]);
}
}

[![enter image description here][1]][1]
return noiseMap;
}

public static void init(int seed) {
}

public static int[] createGradients(int[] p, int seed) {
System.Random prng = new System.Random(seed);
for (int i = 0; i < p.GetLength(0) / 2; i++) {
p[i] = prng.Next(0, 256);
p[i + ((int)p.GetLength(0) / 2)] = p[i];
}

return p;
}

int hash = val & 3;
switch (hash) {
case 0:
return new vector2dDouble(1.0, 1.0);
case 1:
return new vector2dDouble(-1.0, 1.0);
case 2:
return new vector2dDouble(-1.0, -1.0);
case 3:
return new vector2dDouble(1.0, -1.0);
default: return new vector2dDouble(0, 0);
}
}

static double Noise2d(double x, double y) {

int ix = Convert.ToInt32(Math.Floor(x)) & (p.GetLength(0) / 2 - 1);
int iy = Convert.ToInt32(Math.Floor(y)) & (p.GetLength(0) / 2 - 1);

x -= Math.Floor(x);
y -= Math.Floor(y);

vector2dDouble v1 = new vector2dDouble(x - 1, y),
v2 = new vector2dDouble(x - 1, y - 1),
v3 = new vector2dDouble(x, y),
v4 = new vector2dDouble(x, y - 1);

int g1 = p[p[ix + 1] + iy + 1],
g2 = p[p[ix] + iy + 1],
g3 = p[p[ix + 1] + iy],
g4 = p[p[ix]  + iy];

return lerp(u, lerp(v, f2, f4), lerp(v ,f1, f3));
}

static double lerp(double t, double argc, double argv) { return argc + t * (argv - argc); }

static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }
}

[System.Serializable]
public struct vector2dDouble {
public double x, y;

public vector2dDouble(double argx, double argy) {
x = argx;
y = argy;
}

public double dot(vector2dDouble argc) {
argc.x *= x;
argc.y *= y;

return argc.x + argc.y;
}

public void print() {
Debug.Log(x + "," + y);
}
}


• It looks to me like your v and g variables don't agree with one another. g1 is the gradient for the corner (ix+1, iy+1), but you're dotting it with the vector from (ix + 1, iy) Feb 14, 2020 at 4:49
• @DMGregory I changed the vector variables a few times.. This is the closest I have gotten it: link Feb 14, 2020 at 5:08
• A good first question! Can’t believe my eyes Jul 13, 2020 at 6:47

Found The answer! My linear interpolation values were just flipped and when I flipped them back, instead of being inverted and creating layers, it was reverted to its normal state. Code Changed:


return lerp(u, lerp(v, f2, f4), lerp(v ,f1, f3));

// To:

return lerp(u, lerp(v, f4, f2), lerp(v ,f3, f1));

// Also my v and g vectors were unaligned