Last active
August 30, 2021 07:16
-
-
Save rorydriscoll/be1375a63999a272524a to your computer and use it in GitHub Desktop.
2D Perlin noise with derivatives
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static const int permutations[256] = | |
{ | |
249, 69, 172, 0, 116, 3, 219, 221, | |
224, 5, 6, 145, 128, 131, 97, 108, | |
133, 14, 165, 45, 166, 127, 114, 111, | |
119, 20, 34, 4, 103, 67, 48, 158, | |
85, 143, 181, 238, 217, 173, 78, 139, | |
179, 77, 191, 89, 251, 150, 183, 8, | |
168, 225, 23, 65, 55, 247, 136, 104, | |
117, 193, 174, 106, 122, 199, 243, 211, | |
57, 162, 189, 125, 146, 7, 21, 169, | |
194, 98, 95, 233, 244, 175, 62, 137, | |
232, 86, 148, 113, 52, 252, 88, 30, | |
185, 216, 132, 248, 215, 51, 178, 239, | |
76, 242, 27, 192, 29, 195, 188, 206, | |
40, 94, 250, 75, 210, 203, 214, 152, | |
120, 81, 25, 198, 254, 245, 255, 90, | |
80, 213, 66, 82, 124, 43, 83, 102, | |
161, 170, 53, 246, 118, 91, 18, 36, | |
107, 134, 110, 163, 73, 33, 167, 138, | |
87, 58, 31, 123, 140, 182, 71, 141, | |
231, 74, 184, 92, 19, 115, 63, 135, | |
218, 17, 241, 24, 207, 79, 13, 177, | |
186, 155, 93, 153, 42, 39, 99, 144, | |
222, 190, 64, 47, 157, 142, 187, 101, | |
56, 202, 100, 253, 235, 16, 11, 236, | |
60, 240, 129, 70, 109, 156, 180, 228, | |
105, 220, 44, 130, 229, 54, 1, 61, | |
208, 37, 237, 196, 223, 38, 154, 226, | |
35, 159, 112, 72, 46, 200, 9, 22, | |
49, 234, 204, 164, 59, 126, 209, 201, | |
121, 171, 10, 26, 32, 212, 227, 28, | |
160, 15, 84, 147, 230, 149, 68, 96, | |
151, 205, 41, 197, 50, 176, 12, 2 | |
}; | |
void GetIntegerAndFractional(int& i, float& f, float v) | |
{ | |
const float l = floorf(v); | |
i = (int)l; | |
f = v - l; | |
} | |
Vector2 Gradient(int xi, int yi) | |
{ | |
const int hash = permutations[(permutations[xi & 0xff] + yi) & 0xff]; | |
switch (hash & 0x3) | |
{ | |
case 0x0: return Vector2(+1, +1); | |
case 0x1: return Vector2(-1, +1); | |
case 0x2: return Vector2(+1, -1); | |
case 0x3: return Vector2(-1, -1); | |
} | |
return 0; | |
} | |
float NoiseWithDerivatives(float& dndx, float& dndy, float x, float y) | |
{ | |
int i, j; | |
float u, v; | |
GetIntegerAndFractional(i, u, x); | |
GetIntegerAndFractional(j, v, y); | |
const Vector2 ga = Gradient(i, j); | |
const Vector2 gb = Gradient(i + 1, j); | |
const Vector2 gc = Gradient(i, j + 1); | |
const Vector2 gd = Gradient(i + 1, j + 1); | |
const float a = u * ga.x + v * ga.y; | |
const float b = (u - 1) * gb.x + v * gb.y; | |
const float c = u * gc.x + (v - 1) * gc.y; | |
const float d = (u - 1) * gd.x + (v - 1) * gd.y; | |
const float dudx = 30 * u * u * (u * (u - 2) + 1); | |
const float dvdy = 30 * v * v * (v * (v - 2) + 1); | |
u = u * u * u * (u * (u * 6 - 15) + 10); | |
v = v * v * v * (v * (v * 6 - 15) + 10); | |
const float k0 = 1 - u - v + u * v; | |
const float k1 = u - u * v; | |
const float k2 = v - u * v; | |
const float k3 = u * v; | |
const float n = a * k0 + b * k1 + c * k2 + d * k3; | |
// dndx = dadx * k0 + dbdx * k1 + dcdx * k2 + dddx * k3 + dudx * (b - a) + dudx * v * (a - b - c + d) | |
// dndy = dady * k0 + dbdy * k1 + dcdy * k2 + dddy * k3 + dvdy * (c - a) + dvdy * u * (a - b - c + d) | |
dndx = ga.x * k0 + gb.x * k1 + gc.x * k2 + gd.x * k3 + dudx * (b - a + (a - b - c + d) * v); | |
dndy = ga.y * k0 + gb.y * k1 + gc.y * k2 + gd.y * k3 + dvdy * (c - a + (a - b - c + d) * u); | |
return n; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment