@paper-design/shaders 0.0.45 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +1 -0
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.js +18 -0
  4. package/dist/index.js.map +2 -2
  5. package/dist/shader-mount.d.ts +1 -0
  6. package/dist/shader-mount.js +11 -12
  7. package/dist/shader-mount.js.map +2 -2
  8. package/dist/shader-sizing.d.ts +2 -2
  9. package/dist/shader-sizing.js +39 -1
  10. package/dist/shader-sizing.js.map +2 -2
  11. package/dist/shader-utils.d.ts +8 -5
  12. package/dist/shader-utils.js +70 -51
  13. package/dist/shader-utils.js.map +2 -2
  14. package/dist/shaders/dithering.js +13 -11
  15. package/dist/shaders/dithering.js.map +2 -2
  16. package/dist/shaders/dot-grid.js +2 -2
  17. package/dist/shaders/dot-grid.js.map +2 -2
  18. package/dist/shaders/dot-orbit.d.ts +3 -0
  19. package/dist/shaders/dot-orbit.js +9 -9
  20. package/dist/shaders/dot-orbit.js.map +2 -2
  21. package/dist/shaders/fluted-glass.d.ts +72 -0
  22. package/dist/shaders/fluted-glass.js +188 -0
  23. package/dist/shaders/fluted-glass.js.map +7 -0
  24. package/dist/shaders/god-rays.d.ts +2 -0
  25. package/dist/shaders/god-rays.js +20 -9
  26. package/dist/shaders/god-rays.js.map +2 -2
  27. package/dist/shaders/grain-gradient.js +60 -37
  28. package/dist/shaders/grain-gradient.js.map +2 -2
  29. package/dist/shaders/image-dithering.d.ts +49 -0
  30. package/dist/shaders/image-dithering.js +164 -0
  31. package/dist/shaders/image-dithering.js.map +7 -0
  32. package/dist/shaders/liquid-metal.js +4 -4
  33. package/dist/shaders/liquid-metal.js.map +2 -2
  34. package/dist/shaders/mesh-gradient.js +2 -2
  35. package/dist/shaders/mesh-gradient.js.map +2 -2
  36. package/dist/shaders/metaballs.d.ts +3 -0
  37. package/dist/shaders/metaballs.js +8 -7
  38. package/dist/shaders/metaballs.js.map +2 -2
  39. package/dist/shaders/neuro-noise.js +2 -2
  40. package/dist/shaders/neuro-noise.js.map +2 -2
  41. package/dist/shaders/paper-texture.d.ts +53 -0
  42. package/dist/shaders/paper-texture.js +236 -0
  43. package/dist/shaders/paper-texture.js.map +7 -0
  44. package/dist/shaders/perlin-noise.js +111 -117
  45. package/dist/shaders/perlin-noise.js.map +2 -2
  46. package/dist/shaders/pulsing-border.js +17 -9
  47. package/dist/shaders/pulsing-border.js.map +2 -2
  48. package/dist/shaders/simplex-noise.js +2 -2
  49. package/dist/shaders/simplex-noise.js.map +2 -2
  50. package/dist/shaders/smoke-ring.js +13 -8
  51. package/dist/shaders/smoke-ring.js.map +2 -2
  52. package/dist/shaders/spiral.js +3 -3
  53. package/dist/shaders/spiral.js.map +2 -2
  54. package/dist/shaders/static-mesh-gradient.d.ts +2 -0
  55. package/dist/shaders/static-mesh-gradient.js +15 -14
  56. package/dist/shaders/static-mesh-gradient.js.map +2 -2
  57. package/dist/shaders/static-radial-gradient.d.ts +2 -0
  58. package/dist/shaders/static-radial-gradient.js +15 -13
  59. package/dist/shaders/static-radial-gradient.js.map +2 -2
  60. package/dist/shaders/swirl.js +3 -3
  61. package/dist/shaders/swirl.js.map +2 -2
  62. package/dist/shaders/voronoi.js +6 -10
  63. package/dist/shaders/voronoi.js.map +2 -2
  64. package/dist/shaders/warp.d.ts +3 -0
  65. package/dist/shaders/warp.js +20 -4
  66. package/dist/shaders/warp.js.map +2 -2
  67. package/dist/shaders/water.d.ts +39 -0
  68. package/dist/shaders/water.js +119 -0
  69. package/dist/shaders/water.js.map +7 -0
  70. package/dist/vertex-shader.d.ts +1 -1
  71. package/dist/vertex-shader.js +53 -15
  72. package/dist/vertex-shader.js.map +2 -2
  73. package/package.json +1 -1
@@ -0,0 +1,236 @@
1
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
+ * Paper Shaders *
3
+ * https://github.com/paper-design/shaders *
4
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
+
6
+ import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
+ import { rotation2, declarePI, fiberNoise, textureRandomizerR } from "../shader-utils.js";
8
+ const paperTextureFragmentShader = `#version 300 es
9
+ precision mediump float;
10
+
11
+ uniform float u_time;
12
+ uniform vec2 u_resolution;
13
+ uniform float u_pixelRatio;
14
+
15
+ uniform vec4 u_colorFront;
16
+ uniform vec4 u_colorBack;
17
+
18
+ uniform sampler2D u_image;
19
+ uniform float u_imageAspectRatio;
20
+
21
+ uniform float u_contrast;
22
+ uniform float u_roughness;
23
+ uniform float u_fiber;
24
+ uniform float u_fiberScale;
25
+ uniform float u_crumples;
26
+ uniform float u_crumplesScale;
27
+ uniform float u_folds;
28
+ uniform float u_foldsNumber;
29
+ uniform float u_drops;
30
+ uniform float u_seed;
31
+ uniform float u_blur;
32
+
33
+ uniform sampler2D u_noiseTexture;
34
+
35
+ ${sizingVariablesDeclaration}
36
+
37
+ out vec4 fragColor;
38
+
39
+ float getUvFrame(vec2 uv) {
40
+ float aax = 2. * fwidth(uv.x);
41
+ float aay = 2. * fwidth(uv.y);
42
+
43
+ float left = smoothstep(0., aax, uv.x);
44
+ float right = smoothstep(1., 1. - aax, uv.x);
45
+ float bottom = smoothstep(0., aay, uv.y);
46
+ float top = smoothstep(1., 1. - aay, uv.y);
47
+
48
+ return left * right * bottom * top;
49
+ }
50
+
51
+ ${declarePI}
52
+ ${rotation2}
53
+ ${textureRandomizerR}
54
+ float valueNoise(vec2 st) {
55
+ vec2 i = floor(st);
56
+ vec2 f = fract(st);
57
+ float a = randomR(i);
58
+ float b = randomR(i + vec2(1.0, 0.0));
59
+ float c = randomR(i + vec2(0.0, 1.0));
60
+ float d = randomR(i + vec2(1.0, 1.0));
61
+ vec2 u = f * f * (3.0 - 2.0 * f);
62
+ float x1 = mix(a, b, u.x);
63
+ float x2 = mix(c, d, u.x);
64
+ return mix(x1, x2, u.y);
65
+ }
66
+ float fbm(vec2 n) {
67
+ float total = 0.0, amplitude = .4;
68
+ for (int i = 0; i < 3; i++) {
69
+ total += valueNoise(n) * amplitude;
70
+ n *= 1.99;
71
+ amplitude *= 0.65;
72
+ }
73
+ return total;
74
+ }
75
+
76
+
77
+ float randomG(vec2 p) {
78
+ vec2 uv = floor(p) / 50. + .5;
79
+ return texture(u_noiseTexture, fract(uv)).g;
80
+ }
81
+ float roughness(vec2 p) {
82
+ p *= .1;
83
+ float o = 0.;
84
+ for (float i = 0.; ++i < 4.; p *= 2.1) {
85
+ vec4 w = vec4(floor(p), ceil(p));
86
+ vec2 f = fract(p);
87
+ o += mix(
88
+ mix(randomG(w.xy), randomG(w.xw), f.y),
89
+ mix(randomG(w.zy), randomG(w.zw), f.y),
90
+ f.x);
91
+ o += .2 / exp(2. * abs(sin(.2 * p.x + .5 * p.y)));
92
+ }
93
+ return o / 3.;
94
+ }
95
+
96
+ ${fiberNoise}
97
+
98
+ vec2 randomGB(vec2 p) {
99
+ vec2 uv = floor(p) / 50. + .5;
100
+ return texture(u_noiseTexture, fract(uv)).gb;
101
+ }
102
+ float crumpledNoise(vec2 t, float pw) {
103
+ vec2 p = floor(t);
104
+ float wsum = 0.;
105
+ float cl = 0.;
106
+ for (int y = -1; y < 2; y += 1) {
107
+ for (int x = -1; x < 2; x += 1) {
108
+ vec2 b = vec2(float(x), float(y));
109
+ vec2 q = b + p;
110
+ vec2 q2 = q - floor(q / 8.) * 8.;
111
+ vec2 c = q + randomGB(q2);
112
+ vec2 r = c - t;
113
+ float w = pow(smoothstep(0., 1., 1. - abs(r.x)), pw) * pow(smoothstep(0., 1., 1. - abs(r.y)), pw);
114
+ cl += (.5 + .5 * sin((q2.x + q2.y * 5.) * 8.)) * w;
115
+ wsum += w;
116
+ }
117
+ }
118
+ return pow(cl / wsum, .5) * 2.;
119
+ }
120
+ float crumplesShape(vec2 uv) {
121
+ return crumpledNoise(uv * .25, 16.) * crumpledNoise(uv * .5, 2.);
122
+ }
123
+
124
+
125
+ vec2 folds(vec2 uv) {
126
+ vec3 pp = vec3(0.);
127
+ float l = 9.;
128
+ for (float i = 0.; i < 15.; i++) {
129
+ if (i >= u_foldsNumber) break;
130
+ vec2 rand = randomGB(vec2(i, i * u_seed));
131
+ float an = rand.x * TWO_PI;
132
+ vec2 p = vec2(cos(an), sin(an)) * rand.y;
133
+ float dist = distance(uv, p);
134
+ l = min(l, dist);
135
+
136
+ if (l == dist) {
137
+ pp.xy = (uv - p.xy);
138
+ pp.z = dist;
139
+ }
140
+ }
141
+ return mix(pp.xy, vec2(0.), pow(pp.z, .25));
142
+ }
143
+
144
+ float drops(vec2 uv) {
145
+ vec2 iDropsUV = floor(uv);
146
+ vec2 fDropsUV = fract(uv);
147
+ float dropsMinDist = 1.;
148
+ for (int j = -1; j <= 1; j++) {
149
+ for (int i = -1; i <= 1; i++) {
150
+ vec2 neighbor = vec2(float(i), float(j));
151
+ vec2 offset = randomGB(iDropsUV + neighbor);
152
+ offset = .5 + .5 * sin(10. * u_seed + TWO_PI * offset);
153
+ vec2 pos = neighbor + offset - fDropsUV;
154
+ float dist = length(pos);
155
+ dropsMinDist = min(dropsMinDist, dropsMinDist*dist);
156
+ }
157
+ }
158
+ return 1. - smoothstep(.05, .09, pow(dropsMinDist, .5));
159
+ }
160
+
161
+ void main() {
162
+
163
+ vec2 imageUV = v_imageUV;
164
+ vec2 patternUV = v_imageUV - .5;
165
+ patternUV = 5. * (patternUV * vec2(u_imageAspectRatio, 1.));
166
+
167
+ vec2 roughnessUv = 1.5 * (gl_FragCoord.xy - .5 * u_resolution) / u_pixelRatio;
168
+ float roughness = roughness(roughnessUv + vec2(1., 0.)) - roughness(roughnessUv - vec2(1., 0.));
169
+
170
+ vec2 crumplesUV = fract(patternUV * .1 * u_crumplesScale - u_seed) * 32.;
171
+ float crumples = u_crumples * (crumplesShape(crumplesUV + vec2(.05, 0.)) - crumplesShape(crumplesUV));
172
+
173
+ vec2 fiberUV = 10. * u_fiberScale * patternUV;
174
+ float fiber = fiberNoise(fiberUV, vec2(0.));
175
+ fiber = .5 * u_fiber * (fiber - 1.);
176
+
177
+ vec2 normal = vec2(0.);
178
+ vec2 normalImage = vec2(0.);
179
+
180
+ vec2 foldsUV = patternUV * .12;
181
+ foldsUV = rotate(foldsUV, 4. * u_seed);
182
+ vec2 w = folds(foldsUV);
183
+ foldsUV = rotate(foldsUV + .007 * cos(u_seed), .01 * sin(u_seed));
184
+ vec2 w2 = folds(foldsUV);
185
+
186
+ float drops = u_drops * drops(patternUV * 2.);
187
+
188
+ normal.xy += u_folds * min(5. * u_contrast, 1.) * 4. * max(vec2(0.), w + w2);
189
+ normalImage.xy += u_folds * 2. * w;
190
+
191
+ normal.xy += crumples;
192
+ normalImage.xy += 1.5 * crumples;
193
+
194
+ normal.xy += 3. * drops;
195
+ normalImage.xy += .2 * drops;
196
+
197
+ float blur = u_blur * smoothstep(0., 1., fbm(.17 * patternUV + 10. * u_seed));
198
+ normal *= (1. - 2. * blur);
199
+ fiber *= (1. - blur);
200
+
201
+ normal.xy += u_roughness * 1.5 * roughness;
202
+ normal.xy += fiber;
203
+
204
+ normalImage += u_roughness * .75 * roughness;
205
+ normalImage += .2 * fiber;
206
+
207
+ vec3 lightPos = vec3(1., 2., 1.);
208
+ float res = clamp(dot(normalize(vec3(normal, 9.5 - 9. * pow(u_contrast, .1))), normalize(lightPos)), 0., 1.);
209
+
210
+ vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
211
+ float fgOpacity = u_colorFront.a;
212
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
213
+ float bgOpacity = u_colorBack.a;
214
+
215
+ vec3 color = fgColor * res;
216
+ float opacity = fgOpacity * res;
217
+
218
+ color += bgColor * (1. - opacity);
219
+ opacity += bgOpacity * (1. - opacity);
220
+
221
+ color -= .007 * drops;
222
+
223
+ imageUV += .02 * normalImage;
224
+ vec4 image = texture(u_image, imageUV);
225
+ image.rgb += .5 * (res - .6);
226
+
227
+ float frame = getUvFrame(imageUV);
228
+ color.rgb = mix(color, image.rgb, min(.8 * frame, image.a));
229
+
230
+ fragColor = vec4(color, opacity);
231
+ }
232
+ `;
233
+ export {
234
+ paperTextureFragmentShader
235
+ };
236
+ //# sourceMappingURL=paper-texture.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shaders/paper-texture.ts"],
4
+ "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { rotation2, declarePI, fiberNoise, textureRandomizerR } from '../shader-utils.js';\n\n/**\n * Mimicking paper texture with a combination of noises\n *\n * Uniforms:\n * - u_colorFront, u_colorBack (RGBA)\n * - u_contrast - mixing front and back colors\n * - u_roughness - pixel noise, related to canvas => not scalable\n * - u_fiber, u_fiberScale - curly shaped noise\n * - u_crumples, u_crumplesScale - cell-based pattern\n * - u_folds, u_foldsNumber - lines pattern, 15 max\n * - u_drops - metaballs-like pattern\n * - u_seed - applied to folds, crumples and dots\n * - u_blur - big-scale noise mask applied to everything but roughness\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n */\n\n// language=GLSL\nexport const paperTextureFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorBack;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_contrast;\nuniform float u_roughness;\nuniform float u_fiber;\nuniform float u_fiberScale;\nuniform float u_crumples;\nuniform float u_crumplesScale;\nuniform float u_folds;\nuniform float u_foldsNumber;\nuniform float u_drops;\nuniform float u_seed;\nuniform float u_blur;\n\nuniform sampler2D u_noiseTexture;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\nfloat getUvFrame(vec2 uv) {\n float aax = 2. * fwidth(uv.x);\n float aay = 2. * fwidth(uv.y);\n\n float left = smoothstep(0., aax, uv.x);\n float right = smoothstep(1., 1. - aax, uv.x);\n float bottom = smoothstep(0., aay, uv.y);\n float top = smoothstep(1., 1. - aay, uv.y);\n\n return left * right * bottom * top;\n}\n\n${declarePI}\n${rotation2}\n${textureRandomizerR}\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomR(i);\n float b = randomR(i + vec2(1.0, 0.0));\n float c = randomR(i + vec2(0.0, 1.0));\n float d = randomR(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\nfloat fbm(vec2 n) {\n float total = 0.0, amplitude = .4;\n for (int i = 0; i < 3; i++) {\n total += valueNoise(n) * amplitude;\n n *= 1.99;\n amplitude *= 0.65;\n }\n return total;\n}\n\n\nfloat randomG(vec2 p) {\n vec2 uv = floor(p) / 50. + .5;\n return texture(u_noiseTexture, fract(uv)).g;\n}\nfloat roughness(vec2 p) {\n p *= .1;\n float o = 0.;\n for (float i = 0.; ++i < 4.; p *= 2.1) {\n vec4 w = vec4(floor(p), ceil(p));\n vec2 f = fract(p);\n o += mix(\n mix(randomG(w.xy), randomG(w.xw), f.y),\n mix(randomG(w.zy), randomG(w.zw), f.y),\n f.x);\n o += .2 / exp(2. * abs(sin(.2 * p.x + .5 * p.y)));\n }\n return o / 3.;\n}\n\n${fiberNoise}\n\nvec2 randomGB(vec2 p) {\n vec2 uv = floor(p) / 50. + .5;\n return texture(u_noiseTexture, fract(uv)).gb;\n}\nfloat crumpledNoise(vec2 t, float pw) {\n vec2 p = floor(t);\n float wsum = 0.;\n float cl = 0.;\n for (int y = -1; y < 2; y += 1) {\n for (int x = -1; x < 2; x += 1) {\n vec2 b = vec2(float(x), float(y));\n vec2 q = b + p;\n vec2 q2 = q - floor(q / 8.) * 8.;\n vec2 c = q + randomGB(q2);\n vec2 r = c - t;\n float w = pow(smoothstep(0., 1., 1. - abs(r.x)), pw) * pow(smoothstep(0., 1., 1. - abs(r.y)), pw);\n cl += (.5 + .5 * sin((q2.x + q2.y * 5.) * 8.)) * w;\n wsum += w;\n }\n }\n return pow(cl / wsum, .5) * 2.;\n}\nfloat crumplesShape(vec2 uv) {\n return crumpledNoise(uv * .25, 16.) * crumpledNoise(uv * .5, 2.);\n}\n\n\nvec2 folds(vec2 uv) {\n vec3 pp = vec3(0.);\n float l = 9.;\n for (float i = 0.; i < 15.; i++) {\n if (i >= u_foldsNumber) break;\n vec2 rand = randomGB(vec2(i, i * u_seed));\n float an = rand.x * TWO_PI;\n vec2 p = vec2(cos(an), sin(an)) * rand.y;\n float dist = distance(uv, p);\n l = min(l, dist);\n \n if (l == dist) {\n pp.xy = (uv - p.xy);\n pp.z = dist;\n }\n }\n return mix(pp.xy, vec2(0.), pow(pp.z, .25));\n}\n\nfloat drops(vec2 uv) {\n vec2 iDropsUV = floor(uv);\n vec2 fDropsUV = fract(uv);\n float dropsMinDist = 1.;\n for (int j = -1; j <= 1; j++) {\n for (int i = -1; i <= 1; i++) {\n vec2 neighbor = vec2(float(i), float(j));\n vec2 offset = randomGB(iDropsUV + neighbor);\n offset = .5 + .5 * sin(10. * u_seed + TWO_PI * offset);\n vec2 pos = neighbor + offset - fDropsUV;\n float dist = length(pos);\n dropsMinDist = min(dropsMinDist, dropsMinDist*dist);\n }\n }\n return 1. - smoothstep(.05, .09, pow(dropsMinDist, .5));\n}\n\nvoid main() {\n\n vec2 imageUV = v_imageUV;\n vec2 patternUV = v_imageUV - .5;\n patternUV = 5. * (patternUV * vec2(u_imageAspectRatio, 1.));\n\n vec2 roughnessUv = 1.5 * (gl_FragCoord.xy - .5 * u_resolution) / u_pixelRatio;\n float roughness = roughness(roughnessUv + vec2(1., 0.)) - roughness(roughnessUv - vec2(1., 0.));\n\n vec2 crumplesUV = fract(patternUV * .1 * u_crumplesScale - u_seed) * 32.;\n float crumples = u_crumples * (crumplesShape(crumplesUV + vec2(.05, 0.)) - crumplesShape(crumplesUV));\n\n vec2 fiberUV = 10. * u_fiberScale * patternUV;\n float fiber = fiberNoise(fiberUV, vec2(0.));\n fiber = .5 * u_fiber * (fiber - 1.);\n\n vec2 normal = vec2(0.);\n vec2 normalImage = vec2(0.);\n\n vec2 foldsUV = patternUV * .12;\n foldsUV = rotate(foldsUV, 4. * u_seed);\n vec2 w = folds(foldsUV);\n foldsUV = rotate(foldsUV + .007 * cos(u_seed), .01 * sin(u_seed));\n vec2 w2 = folds(foldsUV);\n\n float drops = u_drops * drops(patternUV * 2.);\n \n normal.xy += u_folds * min(5. * u_contrast, 1.) * 4. * max(vec2(0.), w + w2);\n normalImage.xy += u_folds * 2. * w;\n\n normal.xy += crumples;\n normalImage.xy += 1.5 * crumples;\n\n normal.xy += 3. * drops;\n normalImage.xy += .2 * drops;\n\n float blur = u_blur * smoothstep(0., 1., fbm(.17 * patternUV + 10. * u_seed));\n normal *= (1. - 2. * blur);\n fiber *= (1. - blur);\n\n normal.xy += u_roughness * 1.5 * roughness;\n normal.xy += fiber;\n \n normalImage += u_roughness * .75 * roughness;\n normalImage += .2 * fiber;\n\n vec3 lightPos = vec3(1., 2., 1.);\n float res = clamp(dot(normalize(vec3(normal, 9.5 - 9. * pow(u_contrast, .1))), normalize(lightPos)), 0., 1.);\n\n vec3 fgColor = u_colorFront.rgb * u_colorFront.a;\n float fgOpacity = u_colorFront.a;\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n float bgOpacity = u_colorBack.a;\n\n vec3 color = fgColor * res;\n float opacity = fgOpacity * res;\n\n color += bgColor * (1. - opacity);\n opacity += bgOpacity * (1. - opacity);\n \n color -= .007 * drops;\n\n imageUV += .02 * normalImage;\n vec4 image = texture(u_image, imageUV);\n image.rgb += .5 * (res - .6);\n\n float frame = getUvFrame(imageUV);\n color.rgb = mix(color, image.rgb, min(.8 * frame, image.a));\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface PaperTextureUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_noiseTexture?: HTMLImageElement;\n u_colorFront: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_contrast: number;\n u_roughness: number;\n u_fiber: number;\n u_fiberScale: number;\n u_crumples: number;\n u_foldsNumber: number;\n u_folds: number;\n u_blur: number;\n u_crumplesScale: number;\n u_drops: number;\n u_seed: number;\n}\n\nexport interface PaperTextureParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string | undefined;\n colorFront?: string;\n colorBack?: string;\n contrast?: number;\n roughness?: number;\n fiber?: number;\n fiberScale?: number;\n crumples?: number;\n foldsNumber?: number;\n folds?: number;\n blur?: number;\n crumplesScale?: number;\n drops?: number;\n seed?: number;\n}\n"],
5
+ "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,YAAY,0BAA0B;AAqB9D,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BhD,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2ClB,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
+ "names": []
7
+ }
@@ -24,137 +24,131 @@ out vec4 fragColor;
24
24
 
25
25
  ${declarePI}
26
26
 
27
- uint hash(uint x, uint seed) {
28
- const uint m = 0x5bd1e995U;
29
- uint hash = seed;
30
- // process input
31
- uint k = x;
32
- k *= m;
33
- k ^= k >> 24;
34
- k *= m;
35
- hash *= m;
36
- hash ^= k;
37
- // some final mixing
38
- hash ^= hash >> 13;
39
- hash *= m;
40
- hash ^= hash >> 15;
41
- return hash;
27
+ float hash11(float p) {
28
+ p = fract(p * 0.3183099) + 0.1;
29
+ p *= p + 19.19;
30
+ return fract(p * p);
42
31
  }
43
32
 
44
- uint hash(uvec3 x, uint seed){
45
- const uint m = 0x5bd1e995U;
46
- uint hash = seed;
47
- // process first vector element
48
- uint k = x.x;
49
- k *= m;
50
- k ^= k >> 24;
51
- k *= m;
52
- hash *= m;
53
- hash ^= k;
54
- // process second vector element
55
- k = x.y;
56
- k *= m;
57
- k ^= k >> 24;
58
- k *= m;
59
- hash *= m;
60
- hash ^= k;
61
- // process third vector element
62
- k = x.z;
63
- k *= m;
64
- k ^= k >> 24;
65
- k *= m;
66
- hash *= m;
67
- hash ^= k;
68
- // some final mixing
69
- hash ^= hash >> 13;
70
- hash *= m;
71
- hash ^= hash >> 15;
72
- return hash;
33
+ float hash21(vec2 p) {
34
+ p = fract(p * vec2(0.3183099, 0.3678794)) + 0.1;
35
+ p += dot(p, p + 19.19);
36
+ return fract(p.x * p.y);
73
37
  }
74
38
 
39
+ float hash31(vec3 p) {
40
+ p = fract(p * 0.3183099) + 0.1;
41
+ p += dot(p, p.yzx + 19.19);
42
+ return fract(p.x * (p.y + p.z));
43
+ }
44
+
45
+ vec3 hash33(vec3 p) {
46
+ p = fract(p * 0.3183099) + 0.1;
47
+ p += dot(p, p.yzx + 19.19);
48
+ return fract(vec3(p.x * p.y, p.y * p.z, p.z * p.x));
49
+ }
50
+
51
+ vec3 gradientSafe(vec3 p) {
52
+ vec3 h = hash33(p) * 2.0 - 1.;
53
+ return normalize(h + 0.001);
54
+ }
75
55
 
76
- vec3 gradientdy(uint hash) {
77
- switch (int(hash) & 15) { // look at the last four bits to pick a gradient dy
78
- case 0:
79
- return vec3(1, 1, 0);
80
- case 1:
81
- return vec3(-1, 1, 0);
82
- case 2:
83
- return vec3(1, -1, 0);
84
- case 3:
85
- return vec3(-1, -1, 0);
86
- case 4:
87
- return vec3(1, 0, 1);
88
- case 5:
89
- return vec3(-1, 0, 1);
90
- case 6:
91
- return vec3(1, 0, -1);
92
- case 7:
93
- return vec3(-1, 0, -1);
94
- case 8:
95
- return vec3(0, 1, 1);
96
- case 9:
97
- return vec3(0, -1, 1);
98
- case 10:
99
- return vec3(0, 1, -1);
100
- case 11:
101
- return vec3(0, -1, -1);
102
- case 12:
103
- return vec3(1, 1, 0);
104
- case 13:
105
- return vec3(-1, 1, 0);
106
- case 14:
107
- return vec3(0, -1, 1);
108
- case 15:
109
- return vec3(0, -1, -1);
110
- }
56
+ vec3 gradientPredefined(float hash) {
57
+ int idx = int(hash * 12.0) % 12;
58
+
59
+ if (idx == 0) return vec3(1, 1, 0);
60
+ if (idx == 1) return vec3(-1, 1, 0);
61
+ if (idx == 2) return vec3(1, -1, 0);
62
+ if (idx == 3) return vec3(-1, -1, 0);
63
+ if (idx == 4) return vec3(1, 0, 1);
64
+ if (idx == 5) return vec3(-1, 0, 1);
65
+ if (idx == 6) return vec3(1, 0, -1);
66
+ if (idx == 7) return vec3(-1, 0, -1);
67
+ if (idx == 8) return vec3(0, 1, 1);
68
+ if (idx == 9) return vec3(0, -1, 1);
69
+ if (idx == 10) return vec3(0, 1, -1);
70
+ return vec3(0, -1, -1);// idx == 11
111
71
  }
112
72
 
113
- float interpolate(float value1, float value2, float value3, float value4, float value5, float value6, float value7, float value8, vec3 t) {
114
- return mix(
115
- mix(mix(value1, value2, t.x), mix(value3, value4, t.x), t.y),
116
- mix(mix(value5, value6, t.x), mix(value7, value8, t.x), t.y),
117
- t.z
118
- );
73
+ float interpolateSafe(float v000, float v001, float v010, float v011,
74
+ float v100, float v101, float v110, float v111, vec3 t) {
75
+ t = clamp(t, 0.0, 1.0);
76
+
77
+ float v00 = mix(v000, v100, t.x);
78
+ float v01 = mix(v001, v101, t.x);
79
+ float v10 = mix(v010, v110, t.x);
80
+ float v11 = mix(v011, v111, t.x);
81
+
82
+ float v0 = mix(v00, v10, t.y);
83
+ float v1 = mix(v01, v11, t.y);
84
+
85
+ return mix(v0, v1, t.z);
119
86
  }
120
87
 
121
88
  vec3 fade(vec3 t) {
122
89
  return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
123
90
  }
124
91
 
125
- float perlinNoise(vec3 position, uint seed) {
126
- position += 1e+4;
127
- vec3 floorPosition = floor(position);
128
- vec3 fractPosition = fract(position);
129
- uvec3 cellCoordinates = uvec3(floorPosition);
130
- float value1 = dot(gradientdy(hash(cellCoordinates, seed)), fractPosition);
131
- float value2 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 0, 0)), seed)), fractPosition - vec3(1, 0, 0));
132
- float value3 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 1, 0)), seed)), fractPosition - vec3(0, 1, 0));
133
- float value4 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 1, 0)), seed)), fractPosition - vec3(1, 1, 0));
134
- float value5 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 0, 1)), seed)), fractPosition - vec3(0, 0, 1));
135
- float value6 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 0, 1)), seed)), fractPosition - vec3(1, 0, 1));
136
- float value7 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 1, 1)), seed)), fractPosition - vec3(0, 1, 1));
137
- float value8 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 1, 1)), seed)), fractPosition - vec3(1, 1, 1));
138
- return interpolate(value1, value2, value3, value4, value5, value6, value7, value8, fade(fractPosition));
92
+ float perlinNoise(vec3 position, float seed) {
93
+ position += vec3(seed * 127.1, seed * 311.7, seed * 74.7);
94
+
95
+ vec3 i = floor(position);
96
+ vec3 f = fract(position);
97
+ float h000 = hash31(i);
98
+ float h001 = hash31(i + vec3(0, 0, 1));
99
+ float h010 = hash31(i + vec3(0, 1, 0));
100
+ float h011 = hash31(i + vec3(0, 1, 1));
101
+ float h100 = hash31(i + vec3(1, 0, 0));
102
+ float h101 = hash31(i + vec3(1, 0, 1));
103
+ float h110 = hash31(i + vec3(1, 1, 0));
104
+ float h111 = hash31(i + vec3(1, 1, 1));
105
+ vec3 g000 = gradientPredefined(h000);
106
+ vec3 g001 = gradientPredefined(h001);
107
+ vec3 g010 = gradientPredefined(h010);
108
+ vec3 g011 = gradientPredefined(h011);
109
+ vec3 g100 = gradientPredefined(h100);
110
+ vec3 g101 = gradientPredefined(h101);
111
+ vec3 g110 = gradientPredefined(h110);
112
+ vec3 g111 = gradientPredefined(h111);
113
+ float v000 = dot(g000, f - vec3(0, 0, 0));
114
+ float v001 = dot(g001, f - vec3(0, 0, 1));
115
+ float v010 = dot(g010, f - vec3(0, 1, 0));
116
+ float v011 = dot(g011, f - vec3(0, 1, 1));
117
+ float v100 = dot(g100, f - vec3(1, 0, 0));
118
+ float v101 = dot(g101, f - vec3(1, 0, 1));
119
+ float v110 = dot(g110, f - vec3(1, 1, 0));
120
+ float v111 = dot(g111, f - vec3(1, 1, 1));
121
+
122
+ vec3 u = fade(f);
123
+ return interpolateSafe(v000, v001, v010, v011, v100, v101, v110, v111, u);
139
124
  }
140
125
 
141
126
  float p_noise(vec3 position, int octaveCount, float persistence, float lacunarity) {
142
- float value = 0.0;
143
- float amplitude = 1.0;
144
- float currentFrequency = 10.;
145
- uint currentSeed = uint(0);
146
- for (int i = 0; i < octaveCount; i++) {
147
- currentSeed = hash(currentSeed, 0x0U);
148
- value += perlinNoise(position * currentFrequency, currentSeed) * amplitude;
149
- amplitude *= persistence;
150
- currentFrequency *= lacunarity;
151
- }
152
- return value;
127
+ float value = 0.0;
128
+ float amplitude = 1.0;
129
+ float frequency = 10.0;
130
+ float maxValue = 0.0;
131
+ octaveCount = clamp(octaveCount, 1, 8);
132
+
133
+ for (int i = 0; i < octaveCount; i++) {
134
+ float seed = float(i) * 0.7319;
135
+ value += perlinNoise(position * frequency, seed) * amplitude;
136
+ maxValue += amplitude;
137
+ amplitude *= persistence;
138
+ frequency *= lacunarity;
139
+ }
140
+ return value;
153
141
  }
154
142
 
155
143
  float get_max_amp(float persistence, float octaveCount) {
156
- persistence *= .999;
157
- return (1. - pow(persistence, octaveCount)) / (1. - persistence);
144
+ persistence = clamp(persistence * 0.999, 0.0, 0.999);
145
+ octaveCount = clamp(octaveCount, 1.0, 8.0);
146
+
147
+ if (abs(persistence - 1.0) < 0.001) {
148
+ return octaveCount;
149
+ }
150
+
151
+ return (1.0 - pow(persistence, octaveCount)) / (1.0 - persistence);
158
152
  }
159
153
 
160
154
  void main() {
@@ -165,14 +159,14 @@ void main() {
165
159
 
166
160
  vec3 p = vec3(uv, t);
167
161
 
168
- float oct_count = max(0., floor(u_octaveCount));
162
+ float octCount = clamp(floor(u_octaveCount), 1.0, 8.0);
169
163
  float persistence = clamp(u_persistence, 0., 1.);
170
- float noise = p_noise(p, int(oct_count), persistence, u_lacunarity);
164
+ float noise = p_noise(p, int(octCount), persistence, u_lacunarity);
171
165
 
172
- float max_amp = get_max_amp(persistence, oct_count);
173
- float noise_normalized = (noise + max_amp) / (2. * max_amp) + (u_proportion - .5);
166
+ float max_amp = get_max_amp(persistence, octCount);
167
+ float noise_normalized = clamp((noise + max_amp) / (2. * max_amp) + (u_proportion - .5), 0.0, 1.0);
174
168
  float sharpness = clamp(u_softness, 0., 1.);
175
- float smooth_w = 0.5 * fwidth(noise_normalized);
169
+ float smooth_w = 0.5 * max(fwidth(noise_normalized), 0.001);
176
170
  float res = smoothstep(
177
171
  .5 - .5 * sharpness - smooth_w,
178
172
  .5 + .5 * sharpness + smooth_w,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/perlin-noise.ts"],
4
- "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, colorBandingFix } from '../shader-utils.js';\n\n/**\n * 3d Perlin noise; original algorithm: https://www.shadertoy.com/view/NlSGDz\n *\n * Uniforms:\n * - u_colorBack, u_colorFront (RGBA)\n * - u_proportion: (0..1) blend point between 2 colors (0.5 = equal distribution)\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n * - u_octaveCount: more octaves => more detailed pattern\n * - u_persistence: roughness, falloff between octaves\n * - u_lacunarity: frequency step, typically around 2, defines how compressed is the pattern\n *\n */\n\n// language=GLSL\nexport const perlinNoiseFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorBack;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_octaveCount;\nuniform float u_persistence;\nuniform float u_lacunarity;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nuint hash(uint x, uint seed) {\n const uint m = 0x5bd1e995U;\n uint hash = seed;\n // process input\n uint k = x;\n k *= m;\n k ^= k >> 24;\n k *= m;\n hash *= m;\n hash ^= k;\n // some final mixing\n hash ^= hash >> 13;\n hash *= m;\n hash ^= hash >> 15;\n return hash;\n}\n\nuint hash(uvec3 x, uint seed){\n const uint m = 0x5bd1e995U;\n uint hash = seed;\n // process first vector element\n uint k = x.x;\n k *= m;\n k ^= k >> 24;\n k *= m;\n hash *= m;\n hash ^= k;\n // process second vector element\n k = x.y;\n k *= m;\n k ^= k >> 24;\n k *= m;\n hash *= m;\n hash ^= k;\n // process third vector element\n k = x.z;\n k *= m;\n k ^= k >> 24;\n k *= m;\n hash *= m;\n hash ^= k;\n // some final mixing\n hash ^= hash >> 13;\n hash *= m;\n hash ^= hash >> 15;\n return hash;\n}\n\n\nvec3 gradientdy(uint hash) {\n switch (int(hash) & 15) { // look at the last four bits to pick a gradient dy\n case 0:\n return vec3(1, 1, 0);\n case 1:\n return vec3(-1, 1, 0);\n case 2:\n return vec3(1, -1, 0);\n case 3:\n return vec3(-1, -1, 0);\n case 4:\n return vec3(1, 0, 1);\n case 5:\n return vec3(-1, 0, 1);\n case 6:\n return vec3(1, 0, -1);\n case 7:\n return vec3(-1, 0, -1);\n case 8:\n return vec3(0, 1, 1);\n case 9:\n return vec3(0, -1, 1);\n case 10:\n return vec3(0, 1, -1);\n case 11:\n return vec3(0, -1, -1);\n case 12:\n return vec3(1, 1, 0);\n case 13:\n return vec3(-1, 1, 0);\n case 14:\n return vec3(0, -1, 1);\n case 15:\n return vec3(0, -1, -1);\n }\n}\n\nfloat interpolate(float value1, float value2, float value3, float value4, float value5, float value6, float value7, float value8, vec3 t) {\n return mix(\n mix(mix(value1, value2, t.x), mix(value3, value4, t.x), t.y),\n mix(mix(value5, value6, t.x), mix(value7, value8, t.x), t.y),\n t.z\n );\n}\n\nvec3 fade(vec3 t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\n\nfloat perlinNoise(vec3 position, uint seed) {\n position += 1e+4;\n vec3 floorPosition = floor(position);\n vec3 fractPosition = fract(position);\n uvec3 cellCoordinates = uvec3(floorPosition);\n float value1 = dot(gradientdy(hash(cellCoordinates, seed)), fractPosition);\n float value2 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 0, 0)), seed)), fractPosition - vec3(1, 0, 0));\n float value3 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 1, 0)), seed)), fractPosition - vec3(0, 1, 0));\n float value4 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 1, 0)), seed)), fractPosition - vec3(1, 1, 0));\n float value5 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 0, 1)), seed)), fractPosition - vec3(0, 0, 1));\n float value6 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 0, 1)), seed)), fractPosition - vec3(1, 0, 1));\n float value7 = dot(gradientdy(hash((cellCoordinates + uvec3(0, 1, 1)), seed)), fractPosition - vec3(0, 1, 1));\n float value8 = dot(gradientdy(hash((cellCoordinates + uvec3(1, 1, 1)), seed)), fractPosition - vec3(1, 1, 1));\n return interpolate(value1, value2, value3, value4, value5, value6, value7, value8, fade(fractPosition));\n}\n\nfloat p_noise(vec3 position, int octaveCount, float persistence, float lacunarity) {\n float value = 0.0;\n float amplitude = 1.0;\n float currentFrequency = 10.;\n uint currentSeed = uint(0);\n for (int i = 0; i < octaveCount; i++) {\n currentSeed = hash(currentSeed, 0x0U);\n value += perlinNoise(position * currentFrequency, currentSeed) * amplitude;\n amplitude *= persistence;\n currentFrequency *= lacunarity;\n }\n return value;\n}\n\nfloat get_max_amp(float persistence, float octaveCount) {\n persistence *= .999;\n return (1. - pow(persistence, octaveCount)) / (1. - persistence);\n}\n\nvoid main() {\n vec2 uv = v_patternUV;\n uv *= .5;\n \n float t = .2 * u_time;\n\n vec3 p = vec3(uv, t);\n\n float oct_count = max(0., floor(u_octaveCount));\n float persistence = clamp(u_persistence, 0., 1.);\n float noise = p_noise(p, int(oct_count), persistence, u_lacunarity);\n\n float max_amp = get_max_amp(persistence, oct_count);\n float noise_normalized = (noise + max_amp) / (2. * max_amp) + (u_proportion - .5);\n float sharpness = clamp(u_softness, 0., 1.);\n float smooth_w = 0.5 * fwidth(noise_normalized);\n float res = smoothstep(\n .5 - .5 * sharpness - smooth_w,\n .5 + .5 * sharpness + smooth_w,\n noise_normalized\n );\n\n vec3 fgColor = u_colorFront.rgb * u_colorFront.a;\n float fgOpacity = u_colorFront.a;\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n float bgOpacity = u_colorBack.a;\n\n vec3 color = fgColor * res;\n float opacity = fgOpacity * res;\n\n color += bgColor * (1. - opacity);\n opacity += bgOpacity * (1. - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface PerlinNoiseUniforms extends ShaderSizingUniforms {\n u_colorFront: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_proportion: number;\n u_softness: number;\n u_octaveCount: number;\n u_persistence: number;\n u_lacunarity: number;\n}\n\nexport interface PerlinNoiseParams extends ShaderSizingParams, ShaderMotionParams {\n colorFront?: string;\n colorBack?: string;\n proportion?: number;\n softness?: number;\n octaveCount?: number;\n persistence?: number;\n lacunarity?: number;\n}\n"],
5
- "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;AAgBpC,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAa/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwKP,eAAe;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, colorBandingFix } from '../shader-utils.js';\n\n/**\n * 3d Perlin noise; original algorithm: https://www.shadertoy.com/view/NlSGDz\n *\n * Uniforms:\n * - u_colorBack, u_colorFront (RGBA)\n * - u_proportion: (0..1) blend point between 2 colors (0.5 = equal distribution)\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n * - u_octaveCount: more octaves => more detailed pattern\n * - u_persistence: roughness, falloff between octaves\n * - u_lacunarity: frequency step, typically around 2, defines how compressed is the pattern\n *\n */\n\n// language=GLSL\nexport const perlinNoiseFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorBack;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_octaveCount;\nuniform float u_persistence;\nuniform float u_lacunarity;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nfloat hash11(float p) {\n p = fract(p * 0.3183099) + 0.1;\n p *= p + 19.19;\n return fract(p * p);\n}\n\nfloat hash21(vec2 p) {\n p = fract(p * vec2(0.3183099, 0.3678794)) + 0.1;\n p += dot(p, p + 19.19);\n return fract(p.x * p.y);\n}\n\nfloat hash31(vec3 p) {\n p = fract(p * 0.3183099) + 0.1;\n p += dot(p, p.yzx + 19.19);\n return fract(p.x * (p.y + p.z));\n}\n\nvec3 hash33(vec3 p) {\n p = fract(p * 0.3183099) + 0.1;\n p += dot(p, p.yzx + 19.19);\n return fract(vec3(p.x * p.y, p.y * p.z, p.z * p.x));\n}\n\nvec3 gradientSafe(vec3 p) {\n vec3 h = hash33(p) * 2.0 - 1.;\n return normalize(h + 0.001);\n}\n\nvec3 gradientPredefined(float hash) {\n int idx = int(hash * 12.0) % 12;\n\n if (idx == 0) return vec3(1, 1, 0);\n if (idx == 1) return vec3(-1, 1, 0);\n if (idx == 2) return vec3(1, -1, 0);\n if (idx == 3) return vec3(-1, -1, 0);\n if (idx == 4) return vec3(1, 0, 1);\n if (idx == 5) return vec3(-1, 0, 1);\n if (idx == 6) return vec3(1, 0, -1);\n if (idx == 7) return vec3(-1, 0, -1);\n if (idx == 8) return vec3(0, 1, 1);\n if (idx == 9) return vec3(0, -1, 1);\n if (idx == 10) return vec3(0, 1, -1);\n return vec3(0, -1, -1);// idx == 11\n}\n\nfloat interpolateSafe(float v000, float v001, float v010, float v011,\nfloat v100, float v101, float v110, float v111, vec3 t) {\n t = clamp(t, 0.0, 1.0);\n\n float v00 = mix(v000, v100, t.x);\n float v01 = mix(v001, v101, t.x);\n float v10 = mix(v010, v110, t.x);\n float v11 = mix(v011, v111, t.x);\n\n float v0 = mix(v00, v10, t.y);\n float v1 = mix(v01, v11, t.y);\n\n return mix(v0, v1, t.z);\n}\n\nvec3 fade(vec3 t) {\n return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n}\n\nfloat perlinNoise(vec3 position, float seed) {\n position += vec3(seed * 127.1, seed * 311.7, seed * 74.7);\n\n vec3 i = floor(position);\n vec3 f = fract(position);\n float h000 = hash31(i);\n float h001 = hash31(i + vec3(0, 0, 1));\n float h010 = hash31(i + vec3(0, 1, 0));\n float h011 = hash31(i + vec3(0, 1, 1));\n float h100 = hash31(i + vec3(1, 0, 0));\n float h101 = hash31(i + vec3(1, 0, 1));\n float h110 = hash31(i + vec3(1, 1, 0));\n float h111 = hash31(i + vec3(1, 1, 1));\n vec3 g000 = gradientPredefined(h000);\n vec3 g001 = gradientPredefined(h001);\n vec3 g010 = gradientPredefined(h010);\n vec3 g011 = gradientPredefined(h011);\n vec3 g100 = gradientPredefined(h100);\n vec3 g101 = gradientPredefined(h101);\n vec3 g110 = gradientPredefined(h110);\n vec3 g111 = gradientPredefined(h111);\n float v000 = dot(g000, f - vec3(0, 0, 0));\n float v001 = dot(g001, f - vec3(0, 0, 1));\n float v010 = dot(g010, f - vec3(0, 1, 0));\n float v011 = dot(g011, f - vec3(0, 1, 1));\n float v100 = dot(g100, f - vec3(1, 0, 0));\n float v101 = dot(g101, f - vec3(1, 0, 1));\n float v110 = dot(g110, f - vec3(1, 1, 0));\n float v111 = dot(g111, f - vec3(1, 1, 1));\n\n vec3 u = fade(f);\n return interpolateSafe(v000, v001, v010, v011, v100, v101, v110, v111, u);\n}\n\nfloat p_noise(vec3 position, int octaveCount, float persistence, float lacunarity) {\n float value = 0.0;\n float amplitude = 1.0;\n float frequency = 10.0;\n float maxValue = 0.0;\n octaveCount = clamp(octaveCount, 1, 8);\n\n for (int i = 0; i < octaveCount; i++) {\n float seed = float(i) * 0.7319;\n value += perlinNoise(position * frequency, seed) * amplitude;\n maxValue += amplitude;\n amplitude *= persistence;\n frequency *= lacunarity;\n }\n return value;\n}\n\nfloat get_max_amp(float persistence, float octaveCount) {\n persistence = clamp(persistence * 0.999, 0.0, 0.999);\n octaveCount = clamp(octaveCount, 1.0, 8.0);\n\n if (abs(persistence - 1.0) < 0.001) {\n return octaveCount;\n }\n\n return (1.0 - pow(persistence, octaveCount)) / (1.0 - persistence);\n}\n\nvoid main() {\n vec2 uv = v_patternUV;\n uv *= .5;\n \n float t = .2 * u_time;\n\n vec3 p = vec3(uv, t);\n\n float octCount = clamp(floor(u_octaveCount), 1.0, 8.0);\n float persistence = clamp(u_persistence, 0., 1.);\n float noise = p_noise(p, int(octCount), persistence, u_lacunarity);\n\n float max_amp = get_max_amp(persistence, octCount);\n float noise_normalized = clamp((noise + max_amp) / (2. * max_amp) + (u_proportion - .5), 0.0, 1.0);\n float sharpness = clamp(u_softness, 0., 1.);\n float smooth_w = 0.5 * max(fwidth(noise_normalized), 0.001);\n float res = smoothstep(\n .5 - .5 * sharpness - smooth_w,\n .5 + .5 * sharpness + smooth_w,\n noise_normalized\n );\n\n vec3 fgColor = u_colorFront.rgb * u_colorFront.a;\n float fgOpacity = u_colorFront.a;\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n float bgOpacity = u_colorBack.a;\n\n vec3 color = fgColor * res;\n float opacity = fgOpacity * res;\n\n color += bgColor * (1. - opacity);\n opacity += bgOpacity * (1. - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface PerlinNoiseUniforms extends ShaderSizingUniforms {\n u_colorFront: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_proportion: number;\n u_softness: number;\n u_octaveCount: number;\n u_persistence: number;\n u_lacunarity: number;\n}\n\nexport interface PerlinNoiseParams extends ShaderSizingParams, ShaderMotionParams {\n colorFront?: string;\n colorBack?: string;\n proportion?: number;\n softness?: number;\n octaveCount?: number;\n persistence?: number;\n lacunarity?: number;\n}\n"],
5
+ "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;AAgBpC,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAa/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkKP,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -4,7 +4,7 @@
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
6
  import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
- import { declarePI, declareValueNoise, colorBandingFix } from "../shader-utils.js";
7
+ import { declarePI, textureRandomizerGB, colorBandingFix } from "../shader-utils.js";
8
8
  const pulsingBorderMeta = {
9
9
  maxColorCount: 5,
10
10
  maxSpots: 4
@@ -59,17 +59,25 @@ float roundedBoxSmoke(vec2 uv, float distance, float size) {
59
59
  return border;
60
60
  }
61
61
 
62
- float random(vec2 p) {
62
+ ${textureRandomizerGB}
63
+
64
+ float randomG(vec2 p) {
63
65
  vec2 uv = floor(p) / 100. + .5;
64
- return texture(u_noiseTexture, uv).g;
66
+ return texture(u_noiseTexture, fract(uv)).g;
65
67
  }
66
- vec2 rand2(vec2 p) {
67
- vec2 uv = floor(p) / 100. + .5;
68
- return texture(u_noiseTexture, uv).gb;
68
+ float valueNoise(vec2 st) {
69
+ vec2 i = floor(st);
70
+ vec2 f = fract(st);
71
+ float a = randomG(i);
72
+ float b = randomG(i + vec2(1.0, 0.0));
73
+ float c = randomG(i + vec2(0.0, 1.0));
74
+ float d = randomG(i + vec2(1.0, 1.0));
75
+ vec2 u = f * f * (3.0 - 2.0 * f);
76
+ float x1 = mix(a, b, u.x);
77
+ float x2 = mix(c, d, u.x);
78
+ return mix(x1, x2, u.y);
69
79
  }
70
80
 
71
- ${declareValueNoise}
72
-
73
81
  float linearstep(float edge0, float edge1, float x) {
74
82
  return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
75
83
  }
@@ -174,7 +182,7 @@ void main() {
174
182
  if (spotIdx >= int(u_spots)) break;
175
183
  float spotIdxF = float(spotIdx);
176
184
 
177
- vec2 randVal = rand2(vec2(spotIdxF * 10. + 2., 40. + colorIdxF));
185
+ vec2 randVal = randomGB(vec2(spotIdxF * 10. + 2., 40. + colorIdxF));
178
186
 
179
187
  float time = (.1 + .15 * abs(sin(spotIdxF * (2. + colorIdxF)) * cos(spotIdxF * (2. + 2.5 * colorIdxF)))) * t + randVal.x * 3.;
180
188
  time *= mix(1., -1., step(.5, randVal.y));