I am quite new to the wonderful world of "Procedural textures," and I am trying to create a double precision noise perlin algorithm.

I'm almost done, except for the fact that the coordinates seem to be off, any idea what I've done wrong? Here is 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) {
createGradients(p, 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;
}
static vector2dDouble generateGradient(int val) {
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);
double u = fade(x);
double v = fade(y);
double f1 = v1.dot(generateGradient(g1)),
f2 = v2.dot(generateGradient(g2)),
f3 = v3.dot(generateGradient(g3)),
f4 = v4.dot(generateGradient(g4));
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);
}
}
```