1/* 2 * 2D, 3D and 4D Perlin noise, classic and simplex, in a GLSL fragment shader. 3 * 4 * Classic noise is implemented by the functions: 5 * float noise(vec2 P) 6 * float noise(vec3 P) 7 * float noise(vec4 P) 8 * 9 * Simplex noise is implemented by the functions: 10 * float snoise(vec2 P) 11 * float snoise(vec3 P) 12 * float snoise(vec4 P) 13 * 14 * Author: Stefan Gustavson ITN-LiTH (stegu@itn.liu.se) 2004-12-05 15 * Simplex indexing functions by Bill Licea-Kane, ATI 16 */ 17 18/* 19This code was irrevocably released into the public domain 20by its original author, Stefan Gustavson, in January 2011. 21Please feel free to use it for whatever you want. 22Credit is appreciated where appropriate, and I also 23appreciate being told where this code finds any use, 24but you may do as you like. Alternatively, if you want 25to have a familiar OSI-approved license, you may use 26This code under the terms of the MIT license: 27 28Copyright (C) 2004 by Stefan Gustavson. All rights reserved. 29This code is licensed to you under the terms of the MIT license: 30 31Permission is hereby granted, free of charge, to any person obtaining a copy 32of this software and associated documentation files (the "Software"), to deal 33in the Software without restriction, including without limitation the rights 34to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35copies of the Software, and to permit persons to whom the Software is 36furnished to do so, subject to the following conditions: 37 38The above copyright notice and this permission notice shall be included in 39all copies or substantial portions of the Software. 40 41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47THE SOFTWARE. 48*/ 49 50/* 51 * The value of classic 4D noise goes above 1.0 and below -1.0 at some 52 * points. Not much and only very sparsely, but it happens. This is a 53 * bug from the original software implementation, so I left it untouched. 54 */ 55 56 57/* 58 * "permTexture" is a 256x256 texture that is used for both the permutations 59 * and the 2D and 3D gradient lookup. For details, see the main C program. 60 * "gradTexture" is a 256x256 texture with 4D gradients, similar to 61 * "permTexture" but with the permutation index in the alpha component 62 * replaced by the w component of the 4D gradient. 63 * 2D classic noise uses only permTexture. 64 * 2D simplex noise uses only permTexture. 65 * 3D classic noise uses only permTexture. 66 * 3D simplex noise uses only permTexture. 67 * 4D classic noise uses permTexture and gradTexture. 68 * 4D simplex noise uses permTexture and gradTexture. 69 */ 70uniform sampler2D permTexture; 71uniform sampler2D gradTexture; 72uniform float time; // Used for texture animation 73 74/* 75 * Both 2D and 3D texture coordinates are defined, for testing purposes. 76 */ 77#ifdef FRAGMENT_SHADER 78in vec2 v_texCoord2D; 79in vec3 v_texCoord3D; 80in vec4 v_color; 81#endif // FRAGMENT_SHADER 82 83/* 84 * To create offsets of one texel and one half texel in the 85 * texture lookup, we need to know the texture image size. 86 */ 87#define ONE 0.00390625 88#define ONEHALF 0.001953125 89// The numbers above are 1/256 and 0.5/256, change accordingly 90// if you change the code to use another perm/grad texture size. 91 92 93/* 94 * The 5th degree smooth interpolation function for Perlin "improved noise". 95 */ 96float fade(const in float t) { 97 // return t*t*(3.0-2.0*t); // Old fade, yields discontinuous second derivative 98 return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise 99} 100 101/* 102 * Efficient simplex indexing functions by Bill Licea-Kane, ATI. Thanks! 103 * (This was originally implemented as a texture lookup. Nice to avoid that.) 104 */ 105void simplex( const in vec3 P, out vec3 offset1, out vec3 offset2 ) 106{ 107 vec3 offset0; 108 109 vec2 isX = step( P.yz, P.xx ); // P.x >= P.y ? 1.0 : 0.0; P.x >= P.z ? 1.0 : 0.0; 110 offset0.x = dot( isX, vec2( 1.0 ) ); // Accumulate all P.x >= other channels in offset.x 111 offset0.yz = 1.0 - isX; // Accumulate all P.x < other channels in offset.yz 112 113 float isY = step( P.z, P.y ); // P.y >= P.z ? 1.0 : 0.0; 114 offset0.y += isY; // Accumulate P.y >= P.z in offset.y 115 offset0.z += 1.0 - isY; // Accumulate P.y < P.z in offset.z 116 117 // offset0 now contains the unique values 0,1,2 in each channel 118 // 2 for the channel greater than other channels 119 // 1 for the channel that is less than one but greater than another 120 // 0 for the channel less than other channels 121 // Equality ties are broken in favor of first x, then y 122 // (z always loses ties) 123 124 offset2 = clamp( offset0, 0.0, 1.0 ); 125 // offset2 contains 1 in each channel that was 1 or 2 126 offset1 = clamp( --offset0, 0.0, 1.0 ); 127 // offset1 contains 1 in the single channel that was 1 128} 129 130void simplex( const in vec4 P, out vec4 offset1, out vec4 offset2, out vec4 offset3 ) 131{ 132 vec4 offset0; 133 134 vec3 isX = step( P.yzw, P.xxx ); // See comments in 3D simplex function 135 offset0.x = dot( isX, vec3( 1.0 ) ); 136 offset0.yzw = 1.0 - isX; 137 138 vec2 isY = step( P.zw, P.yy ); 139 offset0.y += dot( isY, vec2( 1.0 ) ); 140 offset0.zw += 1.0 - isY; 141 142 float isZ = step( P.w, P.z ); 143 offset0.z += isZ; 144 offset0.w += 1.0 - isZ; 145 146 // offset0 now contains the unique values 0,1,2,3 in each channel 147 148 offset3 = clamp( offset0, 0.0, 1.0 ); 149 offset2 = clamp( --offset0, 0.0, 1.0 ); 150 offset1 = clamp( --offset0, 0.0, 1.0 ); 151} 152 153 154/* 155 * 2D classic Perlin noise. Fast, but less useful than 3D noise. 156 */ 157float noise(const in vec2 P) 158{ 159 vec2 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled and offset for texture lookup 160 vec2 Pf = fract(P); // Fractional part for interpolation 161 162 // Noise contribution from lower left corner 163 vec2 grad00 = texture(permTexture, Pi).rg * 4.0 - 1.0; 164 float n00 = dot(grad00, Pf); 165 166 // Noise contribution from lower right corner 167 vec2 grad10 = texture(permTexture, Pi + vec2(ONE, 0.0)).rg * 4.0 - 1.0; 168 float n10 = dot(grad10, Pf - vec2(1.0, 0.0)); 169 170 // Noise contribution from upper left corner 171 vec2 grad01 = texture(permTexture, Pi + vec2(0.0, ONE)).rg * 4.0 - 1.0; 172 float n01 = dot(grad01, Pf - vec2(0.0, 1.0)); 173 174 // Noise contribution from upper right corner 175 vec2 grad11 = texture(permTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0; 176 float n11 = dot(grad11, Pf - vec2(1.0, 1.0)); 177 178 // Blend contributions along x 179 vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade(Pf.x)); 180 181 // Blend contributions along y 182 float n_xy = mix(n_x.x, n_x.y, fade(Pf.y)); 183 184 // We're done, return the final noise value. 185 return n_xy; 186} 187 188 189/* 190 * 3D classic noise. Slower, but a lot more useful than 2D noise. 191 */ 192float noise(const in vec3 P) 193{ 194 vec3 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel 195 // and offset 1/2 texel to sample texel centers 196 vec3 Pf = fract(P); // Fractional part for interpolation 197 198 // Noise contributions from (x=0, y=0), z=0 and z=1 199 float perm00 = texture(permTexture, Pi.xy).a ; 200 vec3 grad000 = texture(permTexture, vec2(perm00, Pi.z)).rgb * 4.0 - 1.0; 201 float n000 = dot(grad000, Pf); 202 vec3 grad001 = texture(permTexture, vec2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0; 203 float n001 = dot(grad001, Pf - vec3(0.0, 0.0, 1.0)); 204 205 // Noise contributions from (x=0, y=1), z=0 and z=1 206 float perm01 = texture(permTexture, Pi.xy + vec2(0.0, ONE)).a ; 207 vec3 grad010 = texture(permTexture, vec2(perm01, Pi.z)).rgb * 4.0 - 1.0; 208 float n010 = dot(grad010, Pf - vec3(0.0, 1.0, 0.0)); 209 vec3 grad011 = texture(permTexture, vec2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0; 210 float n011 = dot(grad011, Pf - vec3(0.0, 1.0, 1.0)); 211 212 // Noise contributions from (x=1, y=0), z=0 and z=1 213 float perm10 = texture(permTexture, Pi.xy + vec2(ONE, 0.0)).a ; 214 vec3 grad100 = texture(permTexture, vec2(perm10, Pi.z)).rgb * 4.0 - 1.0; 215 float n100 = dot(grad100, Pf - vec3(1.0, 0.0, 0.0)); 216 vec3 grad101 = texture(permTexture, vec2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0; 217 float n101 = dot(grad101, Pf - vec3(1.0, 0.0, 1.0)); 218 219 // Noise contributions from (x=1, y=1), z=0 and z=1 220 float perm11 = texture(permTexture, Pi.xy + vec2(ONE, ONE)).a ; 221 vec3 grad110 = texture(permTexture, vec2(perm11, Pi.z)).rgb * 4.0 - 1.0; 222 float n110 = dot(grad110, Pf - vec3(1.0, 1.0, 0.0)); 223 vec3 grad111 = texture(permTexture, vec2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0; 224 float n111 = dot(grad111, Pf - vec3(1.0, 1.0, 1.0)); 225 226 // Blend contributions along x 227 vec4 n_x = mix(vec4(n000, n001, n010, n011), 228 vec4(n100, n101, n110, n111), fade(Pf.x)); 229 230 // Blend contributions along y 231 vec2 n_xy = mix(n_x.xy, n_x.zw, fade(Pf.y)); 232 233 // Blend contributions along z 234 float n_xyz = mix(n_xy.x, n_xy.y, fade(Pf.z)); 235 236 // We're done, return the final noise value. 237 return n_xyz; 238} 239 240 241/* 242 * 4D classic noise. Slow, but very useful. 4D simplex noise is a lot faster. 243 * 244 * This function performs 8 texture lookups and 16 dependent texture lookups, 245 * 16 dot products, 4 mix operations and a lot of additions and multiplications. 246 * Needless to say, it's not super fast. But it's not dead slow either. 247 */ 248float noise(const in vec4 P) 249{ 250 vec4 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel 251 // and offset 1/2 texel to sample texel centers 252 vec4 Pf = fract(P); // Fractional part for interpolation 253 254 // "n0000" is the noise contribution from (x=0, y=0, z=0, w=0), and so on 255 float perm00xy = texture(permTexture, Pi.xy).a ; 256 float perm00zw = texture(permTexture, Pi.zw).a ; 257 vec4 grad0000 = texture(gradTexture, vec2(perm00xy, perm00zw)).rgba * 4.0 -1.0; 258 float n0000 = dot(grad0000, Pf); 259 260 float perm01zw = texture(permTexture, Pi.zw + vec2(0.0, ONE)).a ; 261 vec4 grad0001 = texture(gradTexture, vec2(perm00xy, perm01zw)).rgba * 4.0 - 1.0; 262 float n0001 = dot(grad0001, Pf - vec4(0.0, 0.0, 0.0, 1.0)); 263 264 float perm10zw = texture(permTexture, Pi.zw + vec2(ONE, 0.0)).a ; 265 vec4 grad0010 = texture(gradTexture, vec2(perm00xy, perm10zw)).rgba * 4.0 - 1.0; 266 float n0010 = dot(grad0010, Pf - vec4(0.0, 0.0, 1.0, 0.0)); 267 268 float perm11zw = texture(permTexture, Pi.zw + vec2(ONE, ONE)).a ; 269 vec4 grad0011 = texture(gradTexture, vec2(perm00xy, perm11zw)).rgba * 4.0 - 1.0; 270 float n0011 = dot(grad0011, Pf - vec4(0.0, 0.0, 1.0, 1.0)); 271 272 float perm01xy = texture(permTexture, Pi.xy + vec2(0.0, ONE)).a ; 273 vec4 grad0100 = texture(gradTexture, vec2(perm01xy, perm00zw)).rgba * 4.0 - 1.0; 274 float n0100 = dot(grad0100, Pf - vec4(0.0, 1.0, 0.0, 0.0)); 275 276 vec4 grad0101 = texture(gradTexture, vec2(perm01xy, perm01zw)).rgba * 4.0 - 1.0; 277 float n0101 = dot(grad0101, Pf - vec4(0.0, 1.0, 0.0, 1.0)); 278 279 vec4 grad0110 = texture(gradTexture, vec2(perm01xy, perm10zw)).rgba * 4.0 - 1.0; 280 float n0110 = dot(grad0110, Pf - vec4(0.0, 1.0, 1.0, 0.0)); 281 282 vec4 grad0111 = texture(gradTexture, vec2(perm01xy, perm11zw)).rgba * 4.0 - 1.0; 283 float n0111 = dot(grad0111, Pf - vec4(0.0, 1.0, 1.0, 1.0)); 284 285 float perm10xy = texture(permTexture, Pi.xy + vec2(ONE, 0.0)).a ; 286 vec4 grad1000 = texture(gradTexture, vec2(perm10xy, perm00zw)).rgba * 4.0 - 1.0; 287 float n1000 = dot(grad1000, Pf - vec4(1.0, 0.0, 0.0, 0.0)); 288 289 vec4 grad1001 = texture(gradTexture, vec2(perm10xy, perm01zw)).rgba * 4.0 - 1.0; 290 float n1001 = dot(grad1001, Pf - vec4(1.0, 0.0, 0.0, 1.0)); 291 292 vec4 grad1010 = texture(gradTexture, vec2(perm10xy, perm10zw)).rgba * 4.0 - 1.0; 293 float n1010 = dot(grad1010, Pf - vec4(1.0, 0.0, 1.0, 0.0)); 294 295 vec4 grad1011 = texture(gradTexture, vec2(perm10xy, perm11zw)).rgba * 4.0 - 1.0; 296 float n1011 = dot(grad1011, Pf - vec4(1.0, 0.0, 1.0, 1.0)); 297 298 float perm11xy = texture(permTexture, Pi.xy + vec2(ONE, ONE)).a ; 299 vec4 grad1100 = texture(gradTexture, vec2(perm11xy, perm00zw)).rgba * 4.0 - 1.0; 300 float n1100 = dot(grad1100, Pf - vec4(1.0, 1.0, 0.0, 0.0)); 301 302 vec4 grad1101 = texture(gradTexture, vec2(perm11xy, perm01zw)).rgba * 4.0 - 1.0; 303 float n1101 = dot(grad1101, Pf - vec4(1.0, 1.0, 0.0, 1.0)); 304 305 vec4 grad1110 = texture(gradTexture, vec2(perm11xy, perm10zw)).rgba * 4.0 - 1.0; 306 float n1110 = dot(grad1110, Pf - vec4(1.0, 1.0, 1.0, 0.0)); 307 308 vec4 grad1111 = texture(gradTexture, vec2(perm11xy, perm11zw)).rgba * 4.0 - 1.0; 309 float n1111 = dot(grad1111, Pf - vec4(1.0, 1.0, 1.0, 1.0)); 310 311 // Blend contributions along x 312 float fadex = fade(Pf.x); 313 vec4 n_x0 = mix(vec4(n0000, n0001, n0010, n0011), 314 vec4(n1000, n1001, n1010, n1011), fadex); 315 vec4 n_x1 = mix(vec4(n0100, n0101, n0110, n0111), 316 vec4(n1100, n1101, n1110, n1111), fadex); 317 318 // Blend contributions along y 319 vec4 n_xy = mix(n_x0, n_x1, fade(Pf.y)); 320 321 // Blend contributions along z 322 vec2 n_xyz = mix(n_xy.xy, n_xy.zw, fade(Pf.z)); 323 324 // Blend contributions along w 325 float n_xyzw = mix(n_xyz.x, n_xyz.y, fade(Pf.w)); 326 327 // We're done, return the final noise value. 328 return n_xyzw; 329} 330 331 332/* 333 * 2D simplex noise. Somewhat slower but much better looking than classic noise. 334 */ 335float snoise(const in vec2 P) { 336 337// Skew and unskew factors are a bit hairy for 2D, so define them as constants 338// This is (sqrt(3.0)-1.0)/2.0 339#define F2 0.366025403784 340// This is (3.0-sqrt(3.0))/6.0 341#define G2 0.211324865405 342 343 // Skew the (x,y) space to determine which cell of 2 simplices we're in 344 float s = (P.x + P.y) * F2; // Hairy factor for 2D skewing 345 vec2 Pi = floor(P + s); 346 float t = (Pi.x + Pi.y) * G2; // Hairy factor for unskewing 347 vec2 P0 = Pi - t; // Unskew the cell origin back to (x,y) space 348 Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup 349 350 vec2 Pf0 = P - P0; // The x,y distances from the cell origin 351 352 // For the 2D case, the simplex shape is an equilateral triangle. 353 // Find out whether we are above or below the x=y diagonal to 354 // determine which of the two triangles we're in. 355 vec2 o1; 356 if(Pf0.x > Pf0.y) o1 = vec2(1.0, 0.0); // +x, +y traversal order 357 else o1 = vec2(0.0, 1.0); // +y, +x traversal order 358 359 // Noise contribution from simplex origin 360 vec2 grad0 = texture(permTexture, Pi).rg * 4.0 - 1.0; 361 float t0 = 0.5 - dot(Pf0, Pf0); 362 float n0; 363 if (t0 < 0.0) n0 = 0.0; 364 else { 365 t0 *= t0; 366 n0 = t0 * t0 * dot(grad0, Pf0); 367 } 368 369 // Noise contribution from middle corner 370 vec2 Pf1 = Pf0 - o1 + G2; 371 vec2 grad1 = texture(permTexture, Pi + o1*ONE).rg * 4.0 - 1.0; 372 float t1 = 0.5 - dot(Pf1, Pf1); 373 float n1; 374 if (t1 < 0.0) n1 = 0.0; 375 else { 376 t1 *= t1; 377 n1 = t1 * t1 * dot(grad1, Pf1); 378 } 379 380 // Noise contribution from last corner 381 vec2 Pf2 = Pf0 - vec2(1.0-2.0*G2); 382 vec2 grad2 = texture(permTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0; 383 float t2 = 0.5 - dot(Pf2, Pf2); 384 float n2; 385 if(t2 < 0.0) n2 = 0.0; 386 else { 387 t2 *= t2; 388 n2 = t2 * t2 * dot(grad2, Pf2); 389 } 390 391 // Sum up and scale the result to cover the range [-1,1] 392 return 70.0 * (n0 + n1 + n2); 393} 394 395 396/* 397 * 3D simplex noise. Comparable in speed to classic noise, better looking. 398 */ 399float snoise(const in vec3 P) { 400 401// The skewing and unskewing factors are much simpler for the 3D case 402#define F3 0.333333333333 403#define G3 0.166666666667 404 405 // Skew the (x,y,z) space to determine which cell of 6 simplices we're in 406 float s = (P.x + P.y + P.z) * F3; // Factor for 3D skewing 407 vec3 Pi = floor(P + s); 408 float t = (Pi.x + Pi.y + Pi.z) * G3; 409 vec3 P0 = Pi - t; // Unskew the cell origin back to (x,y,z) space 410 Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup 411 412 vec3 Pf0 = P - P0; // The x,y distances from the cell origin 413 414 // For the 3D case, the simplex shape is a slightly irregular tetrahedron. 415 // To find out which of the six possible tetrahedra we're in, we need to 416 // determine the magnitude ordering of x, y and z components of Pf0. 417 vec3 o1; 418 vec3 o2; 419 simplex(Pf0, o1, o2); 420 421 // Noise contribution from simplex origin 422 float perm0 = texture(permTexture, Pi.xy).a; 423 vec3 grad0 = texture(permTexture, vec2(perm0, Pi.z)).rgb * 4.0 - 1.0; 424 float t0 = 0.6 - dot(Pf0, Pf0); 425 float n0; 426 if (t0 < 0.0) n0 = 0.0; 427 else { 428 t0 *= t0; 429 n0 = t0 * t0 * dot(grad0, Pf0); 430 } 431 432 // Noise contribution from second corner 433 vec3 Pf1 = Pf0 - o1 + G3; 434 float perm1 = texture(permTexture, Pi.xy + o1.xy*ONE).a; 435 vec3 grad1 = texture(permTexture, vec2(perm1, Pi.z + o1.z*ONE)).rgb * 4.0 - 1.0; 436 float t1 = 0.6 - dot(Pf1, Pf1); 437 float n1; 438 if (t1 < 0.0) n1 = 0.0; 439 else { 440 t1 *= t1; 441 n1 = t1 * t1 * dot(grad1, Pf1); 442 } 443 444 // Noise contribution from third corner 445 vec3 Pf2 = Pf0 - o2 + 2.0 * G3; 446 float perm2 = texture(permTexture, Pi.xy + o2.xy*ONE).a; 447 vec3 grad2 = texture(permTexture, vec2(perm2, Pi.z + o2.z*ONE)).rgb * 4.0 - 1.0; 448 float t2 = 0.6 - dot(Pf2, Pf2); 449 float n2; 450 if (t2 < 0.0) n2 = 0.0; 451 else { 452 t2 *= t2; 453 n2 = t2 * t2 * dot(grad2, Pf2); 454 } 455 456 // Noise contribution from last corner 457 vec3 Pf3 = Pf0 - vec3(1.0-3.0*G3); 458 float perm3 = texture(permTexture, Pi.xy + vec2(ONE, ONE)).a; 459 vec3 grad3 = texture(permTexture, vec2(perm3, Pi.z + ONE)).rgb * 4.0 - 1.0; 460 float t3 = 0.6 - dot(Pf3, Pf3); 461 float n3; 462 if(t3 < 0.0) n3 = 0.0; 463 else { 464 t3 *= t3; 465 n3 = t3 * t3 * dot(grad3, Pf3); 466 } 467 468 // Sum up and scale the result to cover the range [-1,1] 469 return 32.0 * (n0 + n1 + n2 + n3); 470} 471 472 473/* 474 * 4D simplex noise. A lot faster than classic 4D noise, and better looking. 475 */ 476 477float snoise(const in vec4 P) { 478 479// The skewing and unskewing factors are hairy again for the 4D case 480// This is (sqrt(5.0)-1.0)/4.0 481#define F4 0.309016994375 482// This is (5.0-sqrt(5.0))/20.0 483#define G4 0.138196601125 484 485 // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in 486 float s = (P.x + P.y + P.z + P.w) * F4; // Factor for 4D skewing 487 vec4 Pi = floor(P + s); 488 float t = (Pi.x + Pi.y + Pi.z + Pi.w) * G4; 489 vec4 P0 = Pi - t; // Unskew the cell origin back to (x,y,z,w) space 490 Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup 491 492 vec4 Pf0 = P - P0; // The x,y distances from the cell origin 493 494 // For the 4D case, the simplex is a 4D shape I won't even try to describe. 495 // To find out which of the 24 possible simplices we're in, we need to 496 // determine the magnitude ordering of x, y, z and w components of Pf0. 497 vec4 o1; 498 vec4 o2; 499 vec4 o3; 500 simplex(Pf0, o1, o2, o3); 501 502 // Noise contribution from simplex origin 503 float perm0xy = texture(permTexture, Pi.xy).a; 504 float perm0zw = texture(permTexture, Pi.zw).a; 505 vec4 grad0 = texture(gradTexture, vec2(perm0xy, perm0zw)).rgba * 4.0 - 1.0; 506 float t0 = 0.6 - dot(Pf0, Pf0); 507 float n0; 508 if (t0 < 0.0) n0 = 0.0; 509 else { 510 t0 *= t0; 511 n0 = t0 * t0 * dot(grad0, Pf0); 512 } 513 514 // Noise contribution from second corner 515 vec4 Pf1 = Pf0 - o1 + G4; 516 o1 = o1 * ONE; 517 float perm1xy = texture(permTexture, Pi.xy + o1.xy).a; 518 float perm1zw = texture(permTexture, Pi.zw + o1.zw).a; 519 vec4 grad1 = texture(gradTexture, vec2(perm1xy, perm1zw)).rgba * 4.0 - 1.0; 520 float t1 = 0.6 - dot(Pf1, Pf1); 521 float n1; 522 if (t1 < 0.0) n1 = 0.0; 523 else { 524 t1 *= t1; 525 n1 = t1 * t1 * dot(grad1, Pf1); 526 } 527 528 // Noise contribution from third corner 529 vec4 Pf2 = Pf0 - o2 + 2.0 * G4; 530 o2 = o2 * ONE; 531 float perm2xy = texture(permTexture, Pi.xy + o2.xy).a; 532 float perm2zw = texture(permTexture, Pi.zw + o2.zw).a; 533 vec4 grad2 = texture(gradTexture, vec2(perm2xy, perm2zw)).rgba * 4.0 - 1.0; 534 float t2 = 0.6 - dot(Pf2, Pf2); 535 float n2; 536 if (t2 < 0.0) n2 = 0.0; 537 else { 538 t2 *= t2; 539 n2 = t2 * t2 * dot(grad2, Pf2); 540 } 541 542 // Noise contribution from fourth corner 543 vec4 Pf3 = Pf0 - o3 + 3.0 * G4; 544 o3 = o3 * ONE; 545 float perm3xy = texture(permTexture, Pi.xy + o3.xy).a; 546 float perm3zw = texture(permTexture, Pi.zw + o3.zw).a; 547 vec4 grad3 = texture(gradTexture, vec2(perm3xy, perm3zw)).rgba * 4.0 - 1.0; 548 float t3 = 0.6 - dot(Pf3, Pf3); 549 float n3; 550 if (t3 < 0.0) n3 = 0.0; 551 else { 552 t3 *= t3; 553 n3 = t3 * t3 * dot(grad3, Pf3); 554 } 555 556 // Noise contribution from last corner 557 vec4 Pf4 = Pf0 - vec4(1.0-4.0*G4); 558 float perm4xy = texture(permTexture, Pi.xy + vec2(ONE, ONE)).a; 559 float perm4zw = texture(permTexture, Pi.zw + vec2(ONE, ONE)).a; 560 vec4 grad4 = texture(gradTexture, vec2(perm4xy, perm4zw)).rgba * 4.0 - 1.0; 561 float t4 = 0.6 - dot(Pf4, Pf4); 562 float n4; 563 if(t4 < 0.0) n4 = 0.0; 564 else { 565 t4 *= t4; 566 n4 = t4 * t4 * dot(grad4, Pf4); 567 } 568 569 // Sum up and scale the result to cover the range [-1,1] 570 return 27.0 * (n0 + n1 + n2 + n3 + n4); 571} 572 573float fbm(vec3 position, int octaves, float frequency, float persistence) { 574 float total = 0.0; 575 float maxAmplitude = 0.0; 576 float amplitude = 1.0; 577 for (int i = 0; i < octaves; i++) { 578 total += snoise(vec4(position * frequency, time)) * amplitude; 579 frequency *= 2.0; 580 maxAmplitude += amplitude; 581 amplitude *= persistence; 582 } 583 return total / maxAmplitude; 584} 585 586float absNoise(vec3 position, int octaves, float frequency, float persistence) { 587 float total = 0.0; 588 float maxAmplitude = 0.0; 589 float amplitude = 1.0; 590 for (int i = 0; i < octaves; i++) { 591 total += abs(snoise(vec4(position * frequency, time))) * amplitude; 592 frequency *= 2.0; 593 maxAmplitude += amplitude; 594 amplitude *= persistence; 595 } 596 return total / maxAmplitude; 597} 598 599float ridgedNoise(vec3 position, int octaves, float frequency, float persistence) { 600 float total = 0.0; 601 float maxAmplitude = 0.0; 602 float amplitude = 1.0; 603 for (int i = 0; i < octaves; i++) { 604 total += ((1.0 - abs(snoise(vec4(position * frequency, time)))) * 2.0 - 1.0) * amplitude; 605 frequency *= 2.0; 606 maxAmplitude += amplitude; 607 amplitude *= persistence; 608 } 609 return total / maxAmplitude; 610} 611 612float squaredNoise(vec3 position, int octaves, float frequency, float persistence) { 613 float total = 0.0; 614 float maxAmplitude = 0.0; 615 float amplitude = 1.0; 616 for (int i = 0; i < octaves; i++) { 617 float tmp = snoise(vec4(position * frequency, time)); 618 total += tmp * tmp * amplitude; 619 frequency *= 2.0; 620 maxAmplitude += amplitude; 621 amplitude *= persistence; 622 } 623 return total / maxAmplitude; 624} 625 626float cubedNoise(vec3 position, int octaves, float frequency, float persistence) { 627 float total = 0.0; 628 float maxAmplitude = 0.0; 629 float amplitude = 1.0; 630 for (int i = 0; i < octaves; i++) { 631 float tmp = snoise(vec4(position * frequency, time)); 632 total += tmp * tmp * tmp * amplitude; 633 frequency *= 2.0; 634 maxAmplitude += amplitude; 635 amplitude *= persistence; 636 } 637 return total / maxAmplitude; 638} 639 640//void main( void ) 641//{ 642// 643 /* These lines test, in order, 2D classic noise, 2D simplex noise, 644 * 3D classic noise, 3D simplex noise, 4D classic noise, and finally 645 * 4D simplex noise. 646 * Everything but the 4D simplex noise will make some uniform 647 * variables remain unused and be optimized away by the compiler, 648 * so OpenGL will fail to bind them. It's safe to ignore these 649 * warnings from the C program. The program is designed to work anyway. 650 */ 651 //float n = noise(v_texCoord2D * 32.0 + 240.0); 652 //float n = noise(vec3(4.0 * v_texCoord3D.xyz * (2.0 + sin(0.5 * time)))); 653 //float n = snoise(vec3(2.0 * v_texCoord3D.xyz * (2.0 + sin(0.5 * time)))); 654 //float n = noise(vec4(8.0 * v_texCoord3D.xyz, 0.5 * time)); 655 //float n = snoise(vec4(4.0 * v_texCoord3D.xyz, 0.5 * time)); 656 //float n = fbm(v_texCoord3D.xyz, 8, 8.0, 0.5, time); 657// 658 //gl_FragColor = v_color * vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); 659// 660//} 661