* 2D Perlin simplex noise * * Takes around 150ns on an AMD APU. * * @param[in] x float coordinate * @param[in] y float coordinate * * @return Noise value in the range[-1; 1], value of 0 on all integer coordinates. */
| 213 | * @return Noise value in the range[-1; 1], value of 0 on all integer coordinates. |
| 214 | */ |
| 215 | float SimplexNoise::noiseXY(float x, float y) { |
| 216 | float n0, n1, n2; // Noise contributions from the three corners |
| 217 | |
| 218 | // Skewing/Unskewing factors for 2D |
| 219 | static const float F2 = 0.366025403f; // F2 = (sqrt(3) - 1) / 2 |
| 220 | static const float G2 = 0.211324865f; // G2 = (3 - sqrt(3)) / 6 = F2 / (1 + 2 * K) |
| 221 | |
| 222 | // Skew the input space to determine which simplex cell we're in |
| 223 | const float s = (x + y) * F2; // Hairy factor for 2D |
| 224 | const float xs = x + s; |
| 225 | const float ys = y + s; |
| 226 | const int32_t i = fastfloor(xs); |
| 227 | const int32_t j = fastfloor(ys); |
| 228 | |
| 229 | // Unskew the cell origin back to (x,y) space |
| 230 | const float t = static_cast<float>(i + j) * G2; |
| 231 | const float X0 = i - t; |
| 232 | const float Y0 = j - t; |
| 233 | const float x0 = x - X0; // The x,y distances from the cell origin |
| 234 | const float y0 = y - Y0; |
| 235 | |
| 236 | // For the 2D case, the simplex shape is an equilateral triangle. |
| 237 | // Determine which simplex we are in. |
| 238 | int32_t i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords |
| 239 | if (x0 > y0) { // lower triangle, XY order: (0,0)->(1,0)->(1,1) |
| 240 | i1 = 1; |
| 241 | j1 = 0; |
| 242 | } else { // upper triangle, YX order: (0,0)->(0,1)->(1,1) |
| 243 | i1 = 0; |
| 244 | j1 = 1; |
| 245 | } |
| 246 | |
| 247 | // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and |
| 248 | // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where |
| 249 | // c = (3-sqrt(3))/6 |
| 250 | |
| 251 | const float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords |
| 252 | const float y1 = y0 - j1 + G2; |
| 253 | const float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords |
| 254 | const float y2 = y0 - 1.0f + 2.0f * G2; |
| 255 | |
| 256 | // Work out the hashed gradient indices of the three simplex corners |
| 257 | const int gi0 = hash(i + hash(j)); |
| 258 | const int gi1 = hash(i + i1 + hash(j + j1)); |
| 259 | const int gi2 = hash(i + 1 + hash(j + 1)); |
| 260 | |
| 261 | // Calculate the contribution from the first corner |
| 262 | float t0 = 0.5f - x0*x0 - y0*y0; |
| 263 | if (t0 < 0.0f) { |
| 264 | n0 = 0.0f; |
| 265 | } else { |
| 266 | t0 *= t0; |
| 267 | n0 = t0 * t0 * grad(gi0, x0, y0); |
| 268 | } |
| 269 | |
| 270 | // Calculate the contribution from the second corner |
| 271 | float t1 = 0.5f - x1*x1 - y1*y1; |
| 272 | if (t1 < 0.0f) { |