-
Notifications
You must be signed in to change notification settings - Fork 0
/
shaderChunks.js
807 lines (677 loc) · 23.7 KB
/
shaderChunks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
THREE.ShaderChunk.simple_lambert_vertex = `
vec3 vLightFront, vLightBack;
#include <beginnormal_vertex>
#include <defaultnormal_vertex>
#include <begin_vertex>
#include <project_vertex>
#include <lights_lambert_vertex>
`
THREE.ShaderChunk.noise = `
#define PI 3.14159265359
#define TWO_PI 6.28318530718
//
// Description : Array and textureless GLSL 2D/3D/4D simplex
// noise functions.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : stegu
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
// https://github.com/stegu/webgl-noise
//
vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
// Permutation polynomial (ring size 289 = 17*17)
vec3 permute(vec3 x) {
return mod289(((x*34.0)+1.0)*x);
}
float permute(float x){
return x - floor(x * (1.0 / 289.0)) * 289.0;;
}
vec4 taylorInvSqrt(vec4 r){
return 1.79284291400159 - 0.85373472095314 * r;
}
vec2 fade(vec2 t) {
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
vec3 fade(vec3 t) {
return t*t*t*(t*(t*6.0-15.0)+10.0);
}
// Hashed 2-D gradients with an extra rotation.
// (The constant 0.0243902439 is 1/41)
vec2 rgrad2(vec2 p, float rot) {
#if 0
// Map from a line to a diamond such that a shift maps to a rotation.
float u = permute(permute(p.x) + p.y) * 0.0243902439 + rot; // Rotate by shift
u = 4.0 * fract(u) - 2.0;
// (This vector could be normalized, exactly or approximately.)
return vec2(abs(u)-1.0, abs(abs(u+1.0)-2.0)-1.0);
#else
// For more isotropic gradients, sin/cos can be used instead.
float u = permute(permute(p.x) + p.y) * 0.0243902439 + rot; // Rotate by shift
u = fract(u) * 6.28318530718; // 2*pi
return vec2(cos(u), sin(u));
#endif
}
float snoise(vec3 v){
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
// Classic Perlin noise
float cnoise(vec2 P){
vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
Pi = mod289(Pi); // To avoid truncation effects in permutation
vec4 ix = Pi.xzxz;
vec4 iy = Pi.yyww;
vec4 fx = Pf.xzxz;
vec4 fy = Pf.yyww;
vec4 i = permute(permute(ix) + iy);
vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
vec4 gy = abs(gx) - 0.5 ;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;
vec2 g00 = vec2(gx.x,gy.x);
vec2 g10 = vec2(gx.y,gy.y);
vec2 g01 = vec2(gx.z,gy.z);
vec2 g11 = vec2(gx.w,gy.w);
vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
float n00 = dot(g00, vec2(fx.x, fy.x));
float n10 = dot(g10, vec2(fx.y, fy.y));
float n01 = dot(g01, vec2(fx.z, fy.z));
float n11 = dot(g11, vec2(fx.w, fy.w));
vec2 fade_xy = fade(Pf.xy);
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return 2.3 * n_xy;
}
// Classic Perlin noise, periodic variant
float pnoise(vec2 P, vec2 rep){
vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
Pi = mod(Pi, rep.xyxy); // To create noise with explicit period
Pi = mod289(Pi); // To avoid truncation effects in permutation
vec4 ix = Pi.xzxz;
vec4 iy = Pi.yyww;
vec4 fx = Pf.xzxz;
vec4 fy = Pf.yyww;
vec4 i = permute(permute(ix) + iy);
vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
vec4 gy = abs(gx) - 0.5 ;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;
vec2 g00 = vec2(gx.x,gy.x);
vec2 g10 = vec2(gx.y,gy.y);
vec2 g01 = vec2(gx.z,gy.z);
vec2 g11 = vec2(gx.w,gy.w);
vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
float n00 = dot(g00, vec2(fx.x, fy.x));
float n10 = dot(g10, vec2(fx.y, fy.y));
float n01 = dot(g01, vec2(fx.z, fy.z));
float n11 = dot(g11, vec2(fx.w, fy.w));
vec2 fade_xy = fade(Pf.xy);
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return 2.3 * n_xy;
}
// Classic Perlin noise
float cnoise(vec3 P)
{
vec3 Pi0 = floor(P); // Integer part for indexing
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
Pi0 = mod289(Pi0);
Pi1 = mod289(Pi1);
vec3 Pf0 = fract(P); // Fractional part for interpolation
vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec4 iy = vec4(Pi0.yy, Pi1.yy);
vec4 iz0 = Pi0.zzzz;
vec4 iz1 = Pi1.zzzz;
vec4 ixy = permute(permute(ix) + iy);
vec4 ixy0 = permute(ixy + iz0);
vec4 ixy1 = permute(ixy + iz1);
vec4 gx0 = ixy0 * (1.0 / 7.0);
vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
gx0 = fract(gx0);
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
vec4 sz0 = step(gz0, vec4(0.0));
gx0 -= sz0 * (step(0.0, gx0) - 0.5);
gy0 -= sz0 * (step(0.0, gy0) - 0.5);
vec4 gx1 = ixy1 * (1.0 / 7.0);
vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
gx1 = fract(gx1);
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
vec4 sz1 = step(gz1, vec4(0.0));
gx1 -= sz1 * (step(0.0, gx1) - 0.5);
gy1 -= sz1 * (step(0.0, gy1) - 0.5);
vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
float n000 = dot(g000, Pf0);
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
float n111 = dot(g111, Pf1);
vec3 fade_xyz = fade(Pf0);
vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return 2.2 * n_xyz;
}
// Classic Perlin noise, periodic variant
float pnoise(vec3 P, vec3 rep)
{
vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period
vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period
Pi0 = mod289(Pi0);
Pi1 = mod289(Pi1);
vec3 Pf0 = fract(P); // Fractional part for interpolation
vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
vec4 iy = vec4(Pi0.yy, Pi1.yy);
vec4 iz0 = Pi0.zzzz;
vec4 iz1 = Pi1.zzzz;
vec4 ixy = permute(permute(ix) + iy);
vec4 ixy0 = permute(ixy + iz0);
vec4 ixy1 = permute(ixy + iz1);
vec4 gx0 = ixy0 * (1.0 / 7.0);
vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
gx0 = fract(gx0);
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
vec4 sz0 = step(gz0, vec4(0.0));
gx0 -= sz0 * (step(0.0, gx0) - 0.5);
gy0 -= sz0 * (step(0.0, gy0) - 0.5);
vec4 gx1 = ixy1 * (1.0 / 7.0);
vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
gx1 = fract(gx1);
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
vec4 sz1 = step(gz1, vec4(0.0));
gx1 -= sz1 * (step(0.0, gx1) - 0.5);
gy1 -= sz1 * (step(0.0, gy1) - 0.5);
vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
g000 *= norm0.x;
g010 *= norm0.y;
g100 *= norm0.z;
g110 *= norm0.w;
vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
g001 *= norm1.x;
g011 *= norm1.y;
g101 *= norm1.z;
g111 *= norm1.w;
float n000 = dot(g000, Pf0);
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
float n111 = dot(g111, Pf1);
vec3 fade_xyz = fade(Pf0);
vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
return 2.2 * n_xyz;
}
float turbulence( vec3 p ) {
float w = 100.0;
float t = -.5;
for (float f = 1.0 ; f <= 10.0 ; f++ ){
float power = pow( 2.0, f );
t += abs( pnoise( vec3( power * p ), vec3( 10.0, 10.0, 10.0 ) ) / power );
}
return t;
}
float turbulence3( vec3 p ) {
float w = 100.0;
float t = -.5;
for (float f = 1.0 ; f <= 3.0 ; f++ ){
float power = pow( 2.0, f );
t += abs( pnoise( vec3( power * p ), vec3( 3.0, 3.0, 3.0 ) ) / power );
}
return t;
}
float turbulence6( vec3 p ) {
float w = 100.0;
float t = -.5;
for (float f = 1.0 ; f <= 6.0 ; f++ ){
float power = pow( 2.0, f );
t += abs( pnoise( vec3( power * p ), vec3( 6.0, 6.0, 6.0 ) ) / power );
}
return t;
}
//
// 2-D tiling simplex noise with rotating gradients and analytical derivative.
// The first component of the 3-element return vector is the noise value,
// and the second and third components are the x and y partial derivatives.
//
vec3 psrdnoise(vec2 pos, vec2 per, float rot) {
// Hack: offset y slightly to hide some rare artifacts
pos.y += 0.01;
// Skew to hexagonal grid
vec2 uv = vec2(pos.x + pos.y*0.5, pos.y);
vec2 i0 = floor(uv);
vec2 f0 = fract(uv);
// Traversal order
vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Unskewed grid points in (x,y) space
vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y);
vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y);
vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0);
// Integer grid point indices in (u,v) space
i1 = i0 + i1;
vec2 i2 = i0 + vec2(1.0, 1.0);
// Vectors in unskewed (x,y) coordinates from
// each of the simplex corners to the evaluation point
vec2 d0 = pos - p0;
vec2 d1 = pos - p1;
vec2 d2 = pos - p2;
// Wrap i0, i1 and i2 to the desired period before gradient hashing:
// wrap points in (x,y), map to (u,v)
vec3 xw = mod(vec3(p0.x, p1.x, p2.x), per.x);
vec3 yw = mod(vec3(p0.y, p1.y, p2.y), per.y);
vec3 iuw = xw + 0.5 * yw;
vec3 ivw = yw;
// Create gradients from indices
vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot);
vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot);
vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot);
// Gradients dot vectors to corresponding corners
// (The derivatives of this are simply the gradients)
vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2));
// Radial weights from corners
// 0.8 is the square of 2/sqrt(5), the distance from
// a grid point to the nearest simplex boundary
vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2));
// Partial derivatives for analytical gradient computation
vec3 dtdx = -2.0 * vec3(d0.x, d1.x, d2.x);
vec3 dtdy = -2.0 * vec3(d0.y, d1.y, d2.y);
// Set influence of each surflet to zero outside radius sqrt(0.8)
if (t.x < 0.0) {
dtdx.x = 0.0;
dtdy.x = 0.0;
t.x = 0.0;
}
if (t.y < 0.0) {
dtdx.y = 0.0;
dtdy.y = 0.0;
t.y = 0.0;
}
if (t.z < 0.0) {
dtdx.z = 0.0;
dtdy.z = 0.0;
t.z = 0.0;
}
// Fourth power of t (and third power for derivative)
vec3 t2 = t * t;
vec3 t4 = t2 * t2;
vec3 t3 = t2 * t;
// Final noise value is:
// sum of ((radial weights) times (gradient dot vector from corner))
float n = dot(t4, w);
// Final analytical derivative (gradient of a sum of scalar products)
vec2 dt0 = vec2(dtdx.x, dtdy.x) * 4.0 * t3.x;
vec2 dn0 = t4.x * g0 + dt0 * w.x;
vec2 dt1 = vec2(dtdx.y, dtdy.y) * 4.0 * t3.y;
vec2 dn1 = t4.y * g1 + dt1 * w.y;
vec2 dt2 = vec2(dtdx.z, dtdy.z) * 4.0 * t3.z;
vec2 dn2 = t4.z * g2 + dt2 * w.z;
return 11.0*vec3(n, dn0 + dn1 + dn2);
}
//
// 2-D tiling simplex noise with fixed gradients
// and analytical derivative.
// This function is implemented as a wrapper to "psrdnoise",
// at the minimal cost of three extra additions.
//
vec3 psdnoise(vec2 pos, vec2 per) {
return psrdnoise(pos, per, 0.0);
}
//
// 2-D tiling simplex noise with rotating gradients,
// but without the analytical derivative.
//
float psrnoise(vec2 pos, vec2 per, float rot) {
// Offset y slightly to hide some rare artifacts
pos.y += 0.001;
// Skew to hexagonal grid
vec2 uv = vec2(pos.x + pos.y*0.5, pos.y);
vec2 i0 = floor(uv);
vec2 f0 = fract(uv);
// Traversal order
vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Unskewed grid points in (x,y) space
vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y);
vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y);
vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0);
// Integer grid point indices in (u,v) space
i1 = i0 + i1;
vec2 i2 = i0 + vec2(1.0, 1.0);
// Vectors in unskewed (x,y) coordinates from
// each of the simplex corners to the evaluation point
vec2 d0 = pos - p0;
vec2 d1 = pos - p1;
vec2 d2 = pos - p2;
// Wrap i0, i1 and i2 to the desired period before gradient hashing:
// wrap points in (x,y), map to (u,v)
vec3 xw = mod(vec3(p0.x, p1.x, p2.x), per.x);
vec3 yw = mod(vec3(p0.y, p1.y, p2.y), per.y);
vec3 iuw = xw + 0.5 * yw;
vec3 ivw = yw;
// Create gradients from indices
vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot);
vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot);
vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot);
// Gradients dot vectors to corresponding corners
// (The derivatives of this are simply the gradients)
vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2));
// Radial weights from corners
// 0.8 is the square of 2/sqrt(5), the distance from
// a grid point to the nearest simplex boundary
vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2));
// Set influence of each surflet to zero outside radius sqrt(0.8)
t = max(t, 0.0);
// Fourth power of t
vec3 t2 = t * t;
vec3 t4 = t2 * t2;
// Final noise value is:
// sum of ((radial weights) times (gradient dot vector from corner))
float n = dot(t4, w);
// Rescale to cover the range [-1,1] reasonably well
return 11.0*n;
}
//
// 2-D tiling simplex noise with fixed gradients,
// without the analytical derivative.
// This function is implemented as a wrapper to "psrnoise",
// at the minimal cost of three extra additions.
//
float psnoise(vec2 pos, vec2 per) {
return psrnoise(pos, per, 0.0);
}
//
// 2-D non-tiling simplex noise with rotating gradients and analytical derivative.
// The first component of the 3-element return vector is the noise value,
// and the second and third components are the x and y partial derivatives.
//
vec3 srdnoise(vec2 pos, float rot) {
// Offset y slightly to hide some rare artifacts
pos.y += 0.001;
// Skew to hexagonal grid
vec2 uv = vec2(pos.x + pos.y*0.5, pos.y);
vec2 i0 = floor(uv);
vec2 f0 = fract(uv);
// Traversal order
vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Unskewed grid points in (x,y) space
vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y);
vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y);
vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0);
// Integer grid point indices in (u,v) space
i1 = i0 + i1;
vec2 i2 = i0 + vec2(1.0, 1.0);
// Vectors in unskewed (x,y) coordinates from
// each of the simplex corners to the evaluation point
vec2 d0 = pos - p0;
vec2 d1 = pos - p1;
vec2 d2 = pos - p2;
vec3 x = vec3(p0.x, p1.x, p2.x);
vec3 y = vec3(p0.y, p1.y, p2.y);
vec3 iuw = x + 0.5 * y;
vec3 ivw = y;
// Avoid precision issues in permutation
iuw = mod289(iuw);
ivw = mod289(ivw);
// Create gradients from indices
vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot);
vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot);
vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot);
// Gradients dot vectors to corresponding corners
// (The derivatives of this are simply the gradients)
vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2));
// Radial weights from corners
// 0.8 is the square of 2/sqrt(5), the distance from
// a grid point to the nearest simplex boundary
vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2));
// Partial derivatives for analytical gradient computation
vec3 dtdx = -2.0 * vec3(d0.x, d1.x, d2.x);
vec3 dtdy = -2.0 * vec3(d0.y, d1.y, d2.y);
// Set influence of each surflet to zero outside radius sqrt(0.8)
if (t.x < 0.0) {
dtdx.x = 0.0;
dtdy.x = 0.0;
t.x = 0.0;
}
if (t.y < 0.0) {
dtdx.y = 0.0;
dtdy.y = 0.0;
t.y = 0.0;
}
if (t.z < 0.0) {
dtdx.z = 0.0;
dtdy.z = 0.0;
t.z = 0.0;
}
// Fourth power of t (and third power for derivative)
vec3 t2 = t * t;
vec3 t4 = t2 * t2;
vec3 t3 = t2 * t;
// Final noise value is:
// sum of ((radial weights) times (gradient dot vector from corner))
float n = dot(t4, w);
// Final analytical derivative (gradient of a sum of scalar products)
vec2 dt0 = vec2(dtdx.x, dtdy.x) * 4.0 * t3.x;
vec2 dn0 = t4.x * g0 + dt0 * w.x;
vec2 dt1 = vec2(dtdx.y, dtdy.y) * 4.0 * t3.y;
vec2 dn1 = t4.y * g1 + dt1 * w.y;
vec2 dt2 = vec2(dtdx.z, dtdy.z) * 4.0 * t3.z;
vec2 dn2 = t4.z * g2 + dt2 * w.z;
return 11.0*vec3(n, dn0 + dn1 + dn2);
}
//
// 2-D non-tiling simplex noise with fixed gradients and analytical derivative.
// This function is implemented as a wrapper to "srdnoise",
// at the minimal cost of three extra additions.
//
vec3 sdnoise(vec2 pos) {
return srdnoise(pos, 0.0);
}
//
// 2-D non-tiling simplex noise with rotating gradients,
// without the analytical derivative.
//
float srnoise(vec2 pos, float rot) {
// Offset y slightly to hide some rare artifacts
pos.y += 0.001;
// Skew to hexagonal grid
vec2 uv = vec2(pos.x + pos.y*0.5, pos.y);
vec2 i0 = floor(uv);
vec2 f0 = fract(uv);
// Traversal order
vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Unskewed grid points in (x,y) space
vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y);
vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y);
vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0);
// Integer grid point indices in (u,v) space
i1 = i0 + i1;
vec2 i2 = i0 + vec2(1.0, 1.0);
// Vectors in unskewed (x,y) coordinates from
// each of the simplex corners to the evaluation point
vec2 d0 = pos - p0;
vec2 d1 = pos - p1;
vec2 d2 = pos - p2;
// Wrap i0, i1 and i2 to the desired period before gradient hashing:
// wrap points in (x,y), map to (u,v)
vec3 x = vec3(p0.x, p1.x, p2.x);
vec3 y = vec3(p0.y, p1.y, p2.y);
vec3 iuw = x + 0.5 * y;
vec3 ivw = y;
// Avoid precision issues in permutation
iuw = mod289(iuw);
ivw = mod289(ivw);
// Create gradients from indices
vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot);
vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot);
vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot);
// Gradients dot vectors to corresponding corners
// (The derivatives of this are simply the gradients)
vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2));
// Radial weights from corners
// 0.8 is the square of 2/sqrt(5), the distance from
// a grid point to the nearest simplex boundary
vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2));
// Set influence of each surflet to zero outside radius sqrt(0.8)
t = max(t, 0.0);
// Fourth power of t
vec3 t2 = t * t;
vec3 t4 = t2 * t2;
// Final noise value is:
// sum of ((radial weights) times (gradient dot vector from corner))
float n = dot(t4, w);
// Rescale to cover the range [-1,1] reasonably well
return 11.0*n;
}
//
// 2-D non-tiling simplex noise with fixed gradients,
// without the analytical derivative.
// This function is implemented as a wrapper to "srnoise",
// at the minimal cost of three extra additions.
// Note: if this kind of noise is all you want, there are faster
// GLSL implementations of non-tiling simplex noise out there.
// This one is included mainly for completeness and compatibility
// with the other functions in the file.
//
float snoise(vec2 pos) {
return srnoise(pos, 0.0);
}
float hash(float x, float y) {
return fract(abs(sin(sin(123.321 + x) * (y + 321.123)) * 456.654));
}
float lerp(float a, float b, float t) {
return a * (1.0 - t) + b * t;
}
float perlin(float x, float y){
float col = 0.0;
for (int i = 0; i < 8; i++)
{
float fx = floor(x);
float fy = floor(y);
float cx = ceil(x);
float cy = ceil(y);
float a = hash(fx, fy);
float b = hash(fx, cy);
float c = hash(cx, fy);
float d = hash(cx, cy);
col += lerp(lerp(a, b, fract(y)), lerp(c, d, fract(y)), fract(x));
col /= 2.0;
x /= 2.0;
y /= 2.0;
}
return col;
}
float dperlin(float x, float y){
float d = perlin(x, y) * 800.0;
return perlin(x + d, y + d);
}
float ddperlin(float x, float y){
float d = perlin(x, y) * 800.0;
return dperlin(x + d, y + d);
}
`