1
\$\begingroup\$

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

Noise

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) { 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); } } 
\$\endgroup\$
3
  • \$\begingroup\$ 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) \$\endgroup\$ Commented Feb 14, 2020 at 4:49
  • \$\begingroup\$ @DMGregory I changed the vector variables a few times.. This is the closest I have gotten it: link \$\endgroup\$ Commented Feb 14, 2020 at 5:08
  • \$\begingroup\$ A good first question! Can’t believe my eyes \$\endgroup\$ Commented Jul 13, 2020 at 6:47

1 Answer 1

1
\$\begingroup\$

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 
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.