Skip to content

Instantly share code, notes, and snippets.

@Kraballa
Created November 9, 2022 15:24
Show Gist options
  • Save Kraballa/acd813ca19db4a9f6379a6106d126228 to your computer and use it in GitHub Desktop.
Save Kraballa/acd813ca19db4a9f6379a6106d126228 to your computer and use it in GitHub Desktop.
Simplex Noise generator
/// <summary>
/// from http://stephencarmody.wikispaces.com/Simplex+Noise
///
/// blind conversion to C#... let's see what blows up.
///
/// NOT THREADSAFE
/// </summary>
public class SimplexNoise
{
private const float onethird = 0.333333333f;
private const float onesixth = 0.166666667f;
private static int[] T = { 0x15, 0x38, 0x32, 0x2c, 0x0d, 0x13, 0x07, 0x2a };
private float u, v, w, s;
private int i, j, k;
private int[] A = { 0, 0, 0 };
public SimplexNoise()
{
}
public static float[,] Noise(int width, int height, float x, float y, float z, bool normalize = false)
{
SimplexNoise noise = new SimplexNoise();
Random rand = new Random();
float[,] map = new float[width, height];
float zOffset = rand.Next() * 0.001f;
float min = 100;
float max = -100;
//sampling the noise
for (int xx = 0; xx < width; xx++)
{
for (int yy = 0; yy < height; yy++)
{
map[xx, yy] = noise.Noise(xx * x, yy * y, z);
if (map[xx, yy] > max)
max = map[xx, yy];
if (map[xx, yy] < min)
min = map[xx, yy];
}
}
if (normalize)
{
//normalizing
for (int xx = 0; xx < width; xx++)
{
for (int yy = 0; yy < height; yy++)
{
map[xx, yy] = (map[xx, yy] - min) / (max - min);
}
}
}
return map;
}
public float Noise(float x, float y, float z)
{
// Skew input space to relative coordinate in simplex cell
s = (x + y + z) * onethird;
i = fastfloor(x + s);
j = fastfloor(y + s);
k = fastfloor(z + s);
// Unskew cell origin back to (x, y , z) space
s = (i + j + k) * onesixth;
u = x - i + s;
v = y - j + s;
w = z - k + s;
A[0] = 0;
A[1] = 0;
A[2] = 0;
// For 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we're in
int hi = u >= w ? (u >= v ? 0 : 1) : (v >= w ? 1 : 2);
int lo = u < w ? (u < v ? 0 : 1) : (v < w ? 1 : 2);
return K(hi) + K(3 - hi - lo) + K(lo) + K(0);
}
private int fastfloor(float n)
{
return n > 0 ? (int)n : (int)n - 1;
}
private float K(int a)
{
s = (A[0] + A[1] + A[2]) * onesixth;
float x = u - A[0] + s;
float y = v - A[1] + s;
float z = w - A[2] + s;
float t = 0.6f - x * x - y * y - z * z;
int h = shuffle(i + A[0], j + A[1], k + A[2]);
A[a]++;
if (t < 0) return 0;
int b5 = h >> 5 & 1;
int b4 = h >> 4 & 1;
int b3 = h >> 3 & 1;
int b2 = h >> 2 & 1;
int b = h & 3;
float p = b == 1 ? x : b == 2 ? y : z;
float q = b == 1 ? y : b == 2 ? z : x;
float r = b == 1 ? z : b == 2 ? x : y;
p = b5 == b3 ? -p : p;
q = b5 == b4 ? -q : q;
r = b5 != (b4 ^ b3) ? -r : r;
t *= t;
return 8 * t * t * (p + (b == 0 ? q + r : b2 == 0 ? q : r));
}
private int shuffle(int i, int j, int k)
{
return b(i, j, k, 0) + b(j, k, i, 1) + b(k, i, j, 2) + b(i, j, k, 3) +
b(j, k, i, 4) + b(k, i, j, 5) + b(i, j, k, 6) + b(j, k, i, 7);
}
private int b(int i, int j, int k, int B)
{
return T[b(i, B) << 2 | b(j, B) << 1 | b(k, B)];
}
private int b(int N, int B)
{
return N >> B & 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment