* 3D Perlin simplex noise * * @param[in] x float coordinate * @param[in] y float coordinate * @param[in] z float coordinate * * @return Noise value in the range[-1; 1], value of 0 on all integer coordinates. */
| 301 | * @return Noise value in the range[-1; 1], value of 0 on all integer coordinates. |
| 302 | */ |
| 303 | float SimplexNoise::noiseXYZ(float x, float y, float z) { |
| 304 | float n0, n1, n2, n3; // Noise contributions from the four corners |
| 305 | |
| 306 | // Skewing/Unskewing factors for 3D |
| 307 | static const float F3 = 1.0f / 3.0f; |
| 308 | static const float G3 = 1.0f / 6.0f; |
| 309 | |
| 310 | // Skew the input space to determine which simplex cell we're in |
| 311 | float s = (x + y + z) * F3; // Very nice and simple skew factor for 3D |
| 312 | int i = fastfloor(x + s); |
| 313 | int j = fastfloor(y + s); |
| 314 | int k = fastfloor(z + s); |
| 315 | float t = (i + j + k) * G3; |
| 316 | float X0 = i - t; // Unskew the cell origin back to (x,y,z) space |
| 317 | float Y0 = j - t; |
| 318 | float Z0 = k - t; |
| 319 | float x0 = x - X0; // The x,y,z distances from the cell origin |
| 320 | float y0 = y - Y0; |
| 321 | float z0 = z - Z0; |
| 322 | |
| 323 | // For the 3D case, the simplex shape is a slightly irregular tetrahedron. |
| 324 | // Determine which simplex we are in. |
| 325 | int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords |
| 326 | int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords |
| 327 | if (x0 >= y0) { |
| 328 | if (y0 >= z0) { |
| 329 | i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; // X Y Z order |
| 330 | } else if (x0 >= z0) { |
| 331 | i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; // X Z Y order |
| 332 | } else { |
| 333 | i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; // Z X Y order |
| 334 | } |
| 335 | } else { // x0<y0 |
| 336 | if (y0 < z0) { |
| 337 | i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1; // Z Y X order |
| 338 | } else if (x0 < z0) { |
| 339 | i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1; // Y Z X order |
| 340 | } else { |
| 341 | i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0; // Y X Z order |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z), |
| 346 | // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and |
| 347 | // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where |
| 348 | // c = 1/6. |
| 349 | float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords |
| 350 | float y1 = y0 - j1 + G3; |
| 351 | float z1 = z0 - k1 + G3; |
| 352 | float x2 = x0 - i2 + 2.0f * G3; // Offsets for third corner in (x,y,z) coords |
| 353 | float y2 = y0 - j2 + 2.0f * G3; |
| 354 | float z2 = z0 - k2 + 2.0f * G3; |
| 355 | float x3 = x0 - 1.0f + 3.0f * G3; // Offsets for last corner in (x,y,z) coords |
| 356 | float y3 = y0 - 1.0f + 3.0f * G3; |
| 357 | float z3 = z0 - 1.0f + 3.0f * G3; |
| 358 | |
| 359 | // Work out the hashed gradient indices of the four simplex corners |
| 360 | int gi0 = hash(i + hash(j + hash(k))); |