@paper-design/shaders 0.0.0-canary.0d8316e

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 (127) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +7 -0
  4. package/dist/empty-pixel.d.ts +1 -0
  5. package/dist/empty-pixel.js +10 -0
  6. package/dist/empty-pixel.js.map +7 -0
  7. package/dist/get-shader-color-from-string.d.ts +3 -0
  8. package/dist/get-shader-color-from-string.js +101 -0
  9. package/dist/get-shader-color-from-string.js.map +7 -0
  10. package/dist/get-shader-noise-texture.d.ts +1 -0
  11. package/dist/get-shader-noise-texture.js +18 -0
  12. package/dist/get-shader-noise-texture.js.map +7 -0
  13. package/dist/html-in-canvas.d.ts +35 -0
  14. package/dist/html-in-canvas.js +79 -0
  15. package/dist/html-in-canvas.js.map +7 -0
  16. package/dist/index.d.ts +69 -0
  17. package/dist/index.js +196 -0
  18. package/dist/index.js.map +7 -0
  19. package/dist/shader-color-spaces.d.ts +6 -0
  20. package/dist/shader-color-spaces.js +96 -0
  21. package/dist/shader-color-spaces.js.map +7 -0
  22. package/dist/shader-mount.d.ts +151 -0
  23. package/dist/shader-mount.js +605 -0
  24. package/dist/shader-mount.js.map +7 -0
  25. package/dist/shader-sizing.d.ts +30 -0
  26. package/dist/shader-sizing.js +38 -0
  27. package/dist/shader-sizing.js.map +7 -0
  28. package/dist/shader-utils.d.ts +10 -0
  29. package/dist/shader-utils.js +131 -0
  30. package/dist/shader-utils.js.map +7 -0
  31. package/dist/shaders/color-panels.d.ts +70 -0
  32. package/dist/shaders/color-panels.js +224 -0
  33. package/dist/shaders/color-panels.js.map +7 -0
  34. package/dist/shaders/dithering.d.ts +62 -0
  35. package/dist/shaders/dithering.js +271 -0
  36. package/dist/shaders/dithering.js.map +7 -0
  37. package/dist/shaders/dot-grid.d.ts +65 -0
  38. package/dist/shaders/dot-grid.js +110 -0
  39. package/dist/shaders/dot-grid.js.map +7 -0
  40. package/dist/shaders/dot-orbit.d.ts +57 -0
  41. package/dist/shaders/dot-orbit.js +123 -0
  42. package/dist/shaders/dot-orbit.js.map +7 -0
  43. package/dist/shaders/fluted-glass.d.ts +115 -0
  44. package/dist/shaders/fluted-glass.js +361 -0
  45. package/dist/shaders/fluted-glass.js.map +7 -0
  46. package/dist/shaders/gem-smoke.d.ts +96 -0
  47. package/dist/shaders/gem-smoke.js +573 -0
  48. package/dist/shaders/gem-smoke.js.map +7 -0
  49. package/dist/shaders/god-rays.d.ts +67 -0
  50. package/dist/shaders/god-rays.js +133 -0
  51. package/dist/shaders/god-rays.js.map +7 -0
  52. package/dist/shaders/grain-gradient.d.ts +80 -0
  53. package/dist/shaders/grain-gradient.js +301 -0
  54. package/dist/shaders/grain-gradient.js.map +7 -0
  55. package/dist/shaders/halftone-cmyk.d.ts +107 -0
  56. package/dist/shaders/halftone-cmyk.js +319 -0
  57. package/dist/shaders/halftone-cmyk.js.map +7 -0
  58. package/dist/shaders/halftone-dots.d.ts +83 -0
  59. package/dist/shaders/halftone-dots.js +345 -0
  60. package/dist/shaders/halftone-dots.js.map +7 -0
  61. package/dist/shaders/heatmap.d.ts +66 -0
  62. package/dist/shaders/heatmap.js +384 -0
  63. package/dist/shaders/heatmap.js.map +7 -0
  64. package/dist/shaders/image-dithering.d.ts +66 -0
  65. package/dist/shaders/image-dithering.js +209 -0
  66. package/dist/shaders/image-dithering.js.map +7 -0
  67. package/dist/shaders/lens-distortion.d.ts +100 -0
  68. package/dist/shaders/lens-distortion.js +290 -0
  69. package/dist/shaders/lens-distortion.js.map +7 -0
  70. package/dist/shaders/liquid-metal.d.ts +89 -0
  71. package/dist/shaders/liquid-metal.js +633 -0
  72. package/dist/shaders/liquid-metal.js.map +7 -0
  73. package/dist/shaders/mesh-gradient.d.ts +52 -0
  74. package/dist/shaders/mesh-gradient.js +131 -0
  75. package/dist/shaders/mesh-gradient.js.map +7 -0
  76. package/dist/shaders/metaballs.d.ts +51 -0
  77. package/dist/shaders/metaballs.js +111 -0
  78. package/dist/shaders/metaballs.js.map +7 -0
  79. package/dist/shaders/neuro-noise.d.ts +47 -0
  80. package/dist/shaders/neuro-noise.js +77 -0
  81. package/dist/shaders/neuro-noise.js.map +7 -0
  82. package/dist/shaders/paper-texture.d.ts +113 -0
  83. package/dist/shaders/paper-texture.js +541 -0
  84. package/dist/shaders/paper-texture.js.map +7 -0
  85. package/dist/shaders/perlin-noise.d.ts +52 -0
  86. package/dist/shaders/perlin-noise.js +167 -0
  87. package/dist/shaders/perlin-noise.js.map +7 -0
  88. package/dist/shaders/pulsing-border.d.ts +98 -0
  89. package/dist/shaders/pulsing-border.js +239 -0
  90. package/dist/shaders/pulsing-border.js.map +7 -0
  91. package/dist/shaders/simplex-noise.d.ts +45 -0
  92. package/dist/shaders/simplex-noise.js +92 -0
  93. package/dist/shaders/simplex-noise.js.map +7 -0
  94. package/dist/shaders/smoke-ring.d.ts +61 -0
  95. package/dist/shaders/smoke-ring.js +133 -0
  96. package/dist/shaders/smoke-ring.js.map +7 -0
  97. package/dist/shaders/spiral.d.ts +61 -0
  98. package/dist/shaders/spiral.js +83 -0
  99. package/dist/shaders/spiral.js.map +7 -0
  100. package/dist/shaders/static-mesh-gradient.d.ts +63 -0
  101. package/dist/shaders/static-mesh-gradient.js +131 -0
  102. package/dist/shaders/static-mesh-gradient.js.map +7 -0
  103. package/dist/shaders/static-radial-gradient.d.ts +72 -0
  104. package/dist/shaders/static-radial-gradient.js +188 -0
  105. package/dist/shaders/static-radial-gradient.js.map +7 -0
  106. package/dist/shaders/swirl.d.ts +63 -0
  107. package/dist/shaders/swirl.js +104 -0
  108. package/dist/shaders/swirl.js.map +7 -0
  109. package/dist/shaders/voronoi.d.ts +65 -0
  110. package/dist/shaders/voronoi.js +139 -0
  111. package/dist/shaders/voronoi.js.map +7 -0
  112. package/dist/shaders/warp.d.ts +70 -0
  113. package/dist/shaders/warp.js +130 -0
  114. package/dist/shaders/warp.js.map +7 -0
  115. package/dist/shaders/water.d.ts +63 -0
  116. package/dist/shaders/water.js +135 -0
  117. package/dist/shaders/water.js.map +7 -0
  118. package/dist/shaders/waves.d.ts +53 -0
  119. package/dist/shaders/waves.js +66 -0
  120. package/dist/shaders/waves.js.map +7 -0
  121. package/dist/types.d.ts +3 -0
  122. package/dist/types.js +6 -0
  123. package/dist/types.js.map +7 -0
  124. package/dist/vertex-shader.d.ts +2 -0
  125. package/dist/vertex-shader.js +163 -0
  126. package/dist/vertex-shader.js.map +7 -0
  127. package/package.json +29 -0
@@ -0,0 +1,345 @@
1
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
+ * Paper Shaders *
3
+ * https://github.com/paper-design/shaders *
4
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
+
6
+ import {} from "../shader-sizing.js";
7
+ import { declarePI, rotation2, proceduralHash21 } from "../shader-utils.js";
8
+ const halftoneDotsFragmentShader = `#version 300 es
9
+ precision mediump float;
10
+
11
+ uniform vec4 u_colorFront;
12
+ uniform vec4 u_colorBack;
13
+ uniform float u_radius;
14
+ uniform float u_contrast;
15
+
16
+ uniform sampler2D u_image;
17
+ uniform float u_imageAspectRatio;
18
+ uniform float u_imageIsHtml;
19
+ uniform float u_originX;
20
+ uniform float u_originY;
21
+ uniform vec2 u_resolution;
22
+ uniform float u_pixelRatio;
23
+
24
+ uniform float u_size;
25
+ uniform float u_grainMixer;
26
+ uniform float u_grainOverlay;
27
+ uniform float u_grainSize;
28
+ uniform float u_grid;
29
+ uniform bool u_originalColors;
30
+ uniform bool u_inverted;
31
+ uniform float u_type;
32
+
33
+ in vec2 v_imageUV;
34
+
35
+ float getImageAspectRatio() {
36
+ return mix(u_imageAspectRatio, u_resolution.x / u_resolution.y, u_imageIsHtml);
37
+ }
38
+
39
+ out vec4 fragColor;
40
+
41
+ vec4 sampleImage(vec2 uv) {
42
+ vec4 image = texture(u_image, uv);
43
+ image.rgb /= max(image.a, .0001);
44
+ return image;
45
+ }
46
+
47
+ ${declarePI}
48
+ ${rotation2}
49
+ ${proceduralHash21}
50
+
51
+ float valueNoise(vec2 st) {
52
+ vec2 i = floor(st);
53
+ vec2 f = fract(st);
54
+ float a = hash21(i);
55
+ float b = hash21(i + vec2(1.0, 0.0));
56
+ float c = hash21(i + vec2(0.0, 1.0));
57
+ float d = hash21(i + vec2(1.0, 1.0));
58
+ vec2 u = f * f * (3.0 - 2.0 * f);
59
+ float x1 = mix(a, b, u.x);
60
+ float x2 = mix(c, d, u.x);
61
+ return mix(x1, x2, u.y);
62
+ }
63
+
64
+ float lst(float edge0, float edge1, float x) {
65
+ return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
66
+ }
67
+
68
+ float sst(float edge0, float edge1, float x) {
69
+ return smoothstep(edge0, edge1, x);
70
+ }
71
+
72
+ float getCircle(vec2 uv, float r, float baseR) {
73
+ r = mix(.25 * baseR, 0., r);
74
+ float d = length(uv - .5);
75
+ float aa = fwidth(d);
76
+ return 1. - smoothstep(r - aa, r + aa, d);
77
+ }
78
+
79
+ float getCell(vec2 uv) {
80
+ float insideX = step(0.0, uv.x) * (1.0 - step(1.0, uv.x));
81
+ float insideY = step(0.0, uv.y) * (1.0 - step(1.0, uv.y));
82
+ return insideX * insideY;
83
+ }
84
+
85
+ float getCircleWithHole(vec2 uv, float r, float baseR) {
86
+ float cell = getCell(uv);
87
+
88
+ r = mix(.75 * baseR, 0., r);
89
+ float rMod = mod(r, .5);
90
+
91
+ float d = length(uv - .5);
92
+ float aa = fwidth(d);
93
+ float circle = 1. - smoothstep(rMod - aa, rMod + aa, d);
94
+ if (r < .5) {
95
+ return circle;
96
+ } else {
97
+ return cell - circle;
98
+ }
99
+ }
100
+
101
+ float getGooeyBall(vec2 uv, float r, float baseR) {
102
+ float d = length(uv - .5);
103
+ float sizeRadius = .3;
104
+ if (u_grid == 1.) {
105
+ sizeRadius = .42;
106
+ }
107
+ sizeRadius = mix(sizeRadius * baseR, 0., r);
108
+ d = 1. - sst(0., sizeRadius, d);
109
+
110
+ d = pow(d, 2. + baseR);
111
+ return d;
112
+ }
113
+
114
+ float getSoftBall(vec2 uv, float r, float baseR) {
115
+ float d = length(uv - .5);
116
+ float sizeRadius = clamp(baseR, 0., 1.);
117
+ sizeRadius = mix(.5 * sizeRadius, 0., r);
118
+ d = 1. - lst(0., sizeRadius, d);
119
+ float powRadius = 1. - lst(0., 2., baseR);
120
+ d = pow(d, 4. + 3. * powRadius);
121
+ return d;
122
+ }
123
+
124
+ float getUvFrame(vec2 uv, vec2 pad) {
125
+ float aa = 0.0001;
126
+
127
+ float left = smoothstep(-pad.x, -pad.x + aa, uv.x);
128
+ float right = smoothstep(1.0 + pad.x, 1.0 + pad.x - aa, uv.x);
129
+ float bottom = smoothstep(-pad.y, -pad.y + aa, uv.y);
130
+ float top = smoothstep(1.0 + pad.y, 1.0 + pad.y - aa, uv.y);
131
+
132
+ return left * right * bottom * top;
133
+ }
134
+
135
+ float sigmoid(float x, float k) {
136
+ return 1.0 / (1.0 + exp(-k * (x - 0.5)));
137
+ }
138
+
139
+ float getLumAtPx(vec2 uv, float contrast) {
140
+ vec4 tex = sampleImage(uv);
141
+ vec3 color = vec3(
142
+ sigmoid(tex.r, contrast),
143
+ sigmoid(tex.g, contrast),
144
+ sigmoid(tex.b, contrast)
145
+ );
146
+ float lum = dot(vec3(0.2126, 0.7152, 0.0722), color);
147
+ lum = mix(1., lum, tex.a);
148
+ lum = u_inverted ? (1. - lum) : lum;
149
+ return lum;
150
+ }
151
+
152
+ vec2 getGridOrigin() {
153
+ return mix(vec2(.5), vec2(u_originX, u_originY), u_imageIsHtml);
154
+ }
155
+
156
+ float sizeToPx(float size) {
157
+ return 1000. / mix(300., 7., pow(size, .7));
158
+ }
159
+
160
+ float getLumBall(vec2 p, vec2 pad, vec2 inCellOffset, float contrast, float baseR, float stepSize, out vec4 ballColor) {
161
+ p += inCellOffset;
162
+ vec2 uv_i = floor(p);
163
+ vec2 uv_f = fract(p);
164
+ vec2 samplingUV = (uv_i + .5 - inCellOffset) * pad + getGridOrigin();
165
+ float outOfFrame = getUvFrame(samplingUV, pad * stepSize);
166
+
167
+ float lum = getLumAtPx(samplingUV, contrast);
168
+ ballColor = sampleImage(samplingUV);
169
+ ballColor.rgb *= ballColor.a;
170
+ ballColor *= outOfFrame;
171
+
172
+ float ball = 0.;
173
+ if (u_type == 0.) {
174
+ // classic
175
+ ball = getCircle(uv_f, lum, baseR);
176
+ } else if (u_type == 1.) {
177
+ // gooey
178
+ ball = getGooeyBall(uv_f, lum, baseR);
179
+ } else if (u_type == 2.) {
180
+ // holes
181
+ ball = getCircleWithHole(uv_f, lum, baseR);
182
+ } else if (u_type == 3.) {
183
+ // soft
184
+ ball = getSoftBall(uv_f, lum, baseR);
185
+ }
186
+
187
+ return ball * outOfFrame;
188
+ }
189
+
190
+
191
+ void main() {
192
+
193
+ float stepMultiplier = 1.;
194
+ if (u_type == 0.) {
195
+ // classic
196
+ stepMultiplier = 2.;
197
+ } else if (u_type == 1. || u_type == 3.) {
198
+ // gooey & soft
199
+ stepMultiplier = 6.;
200
+ }
201
+
202
+ vec2 cssSize = u_resolution / u_pixelRatio;
203
+ float cellsPerSide = mix(mix(300., 7., pow(u_size, .7)), cssSize.y / sizeToPx(u_size), u_imageIsHtml);
204
+ cellsPerSide /= stepMultiplier;
205
+ float cellSizeY = 1. / cellsPerSide;
206
+ vec2 pad = cellSizeY * vec2(1. / getImageAspectRatio(), 1.);
207
+ if (u_type == 1. && u_grid == 1.) {
208
+ // gooey diagonal grid works differently
209
+ pad *= .7;
210
+ }
211
+
212
+ vec2 uv = v_imageUV;
213
+ uv -= getGridOrigin();
214
+ uv /= pad;
215
+
216
+ float contrast = mix(0., 15., pow(u_contrast, 1.5));
217
+ float baseRadius = u_radius;
218
+ if (u_originalColors == true) {
219
+ contrast = mix(.1, 4., pow(u_contrast, 2.));
220
+ baseRadius = 2. * pow(.5 * u_radius, .3);
221
+ }
222
+
223
+ float totalShape = 0.;
224
+ vec3 totalColor = vec3(0.);
225
+ float totalOpacity = 0.;
226
+
227
+ vec4 ballColor;
228
+ float shape;
229
+ float stepSize = 1. / stepMultiplier;
230
+ for (float x = -0.5; x < 0.5; x += stepSize) {
231
+ for (float y = -0.5; y < 0.5; y += stepSize) {
232
+ vec2 offset = vec2(x, y);
233
+
234
+ if (u_grid == 1.) {
235
+ float rowIndex = floor((y + .5) / stepSize);
236
+ float colIndex = floor((x + .5) / stepSize);
237
+ if (stepSize == 1.) {
238
+ rowIndex = floor(uv.y + y + 1.);
239
+ if (u_type == 1.) {
240
+ colIndex = floor(uv.x + x + 1.);
241
+ }
242
+ }
243
+ if (u_type == 1.) {
244
+ if (mod(rowIndex + colIndex, 2.) == 1.) {
245
+ continue;
246
+ }
247
+ } else {
248
+ if (mod(rowIndex, 2.) == 1.) {
249
+ offset.x += .5 * stepSize;
250
+ }
251
+ }
252
+ }
253
+
254
+ shape = getLumBall(uv, pad, offset, contrast, baseRadius, stepSize, ballColor);
255
+ totalColor += ballColor.rgb * shape;
256
+ totalShape += shape;
257
+ totalOpacity += shape;
258
+ }
259
+ }
260
+
261
+ const float eps = 1e-4;
262
+
263
+ totalColor /= max(totalShape, eps);
264
+ totalOpacity /= max(totalShape, eps);
265
+
266
+ float finalShape = 0.;
267
+ if (u_type == 0.) {
268
+ finalShape = min(1., totalShape);
269
+ } else if (u_type == 1.) {
270
+ float aa = fwidth(totalShape);
271
+ float th = .5;
272
+ finalShape = smoothstep(th - aa, th + aa, totalShape);
273
+ } else if (u_type == 2.) {
274
+ finalShape = min(1., totalShape);
275
+ } else if (u_type == 3.) {
276
+ finalShape = totalShape;
277
+ }
278
+
279
+ vec2 grainSize = mix(2000., 200., u_grainSize) * mix(vec2(1., 1. / getImageAspectRatio()), cssSize / 1000., u_imageIsHtml);
280
+ vec2 grainUV = v_imageUV - getGridOrigin();
281
+ grainUV *= grainSize;
282
+ grainUV += .5;
283
+ if (u_grainMixer > 0.) {
284
+ float grain = valueNoise(grainUV);
285
+ grain = smoothstep(.55, .7 + .2 * u_grainMixer, grain);
286
+ grain *= u_grainMixer;
287
+ finalShape = mix(finalShape, 0., grain);
288
+ }
289
+
290
+ vec3 color = vec3(0.);
291
+ float opacity = 0.;
292
+
293
+ if (u_originalColors == true) {
294
+ color = totalColor * finalShape;
295
+ opacity = totalOpacity * finalShape;
296
+
297
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
298
+ color = color + bgColor * (1. - opacity);
299
+ opacity = opacity + u_colorBack.a * (1. - opacity);
300
+ } else {
301
+ vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
302
+ float fgOpacity = u_colorFront.a;
303
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
304
+ float bgOpacity = u_colorBack.a;
305
+
306
+ color = fgColor * finalShape;
307
+ opacity = fgOpacity * finalShape;
308
+ color += bgColor * (1. - opacity);
309
+ opacity += bgOpacity * (1. - opacity);
310
+ }
311
+
312
+ if (u_grainOverlay > 0.) {
313
+ float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));
314
+ grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);
315
+ grainOverlay = pow(grainOverlay, 1.3);
316
+
317
+ float grainOverlayV = grainOverlay * 2. - 1.;
318
+ vec3 grainOverlayColor = vec3(step(0., grainOverlayV));
319
+ float grainOverlayStrength = u_grainOverlay * abs(grainOverlayV);
320
+ grainOverlayStrength = pow(grainOverlayStrength, .8);
321
+ color = mix(color, grainOverlayColor, .5 * grainOverlayStrength);
322
+
323
+ opacity += .5 * grainOverlayStrength;
324
+ }
325
+ opacity = clamp(opacity, 0., 1.);
326
+
327
+ fragColor = vec4(color, opacity);
328
+ }
329
+ `;
330
+ const HalftoneDotsTypes = {
331
+ classic: 0,
332
+ gooey: 1,
333
+ holes: 2,
334
+ soft: 3
335
+ };
336
+ const HalftoneDotsGrids = {
337
+ square: 0,
338
+ hex: 1
339
+ };
340
+ export {
341
+ HalftoneDotsGrids,
342
+ HalftoneDotsTypes,
343
+ halftoneDotsFragmentShader
344
+ };
345
+ //# sourceMappingURL=halftone-dots.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shaders/halftone-dots.ts"],
4
+ "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\n/**\n * A halftone-dot image filter featuring customizable grids, color palettes, and dot styles.\n *\n * Fragment shader uniforms:\n * - u_image (sampler2D): Source image texture, premultiplied alpha\n * - u_imageAspectRatio (float): Aspect ratio of the source image; over HTML the canvas aspect from u_resolution is used instead\n * - u_imageIsHtml (float): 1 when u_image is HTML. HTML is drawn 1:1, so the grid and grain are sized in CSS px to keep\n * their size over it: size sets the grid cell from about 3px to 143px, and the grain looks as it does over an image box 1000px wide.\n * The grid and grain are anchored at originX / originY instead of the center, 0 0 being the top left like CSS\n * - u_colorFront (vec4): Foreground color in RGBA, needs originalColors off\n * - u_colorBack (vec4): Background color in RGBA\n * - u_originalColors (bool): Use sampled image's original colors instead of colorFront\n * - u_type (float): Dot style (0 = classic, 1 = gooey, 2 = holes, 3 = soft)\n * - u_inverted (bool): Inverts the image luminance, doesn't affect the color scheme, needs contrast > 0\n * - u_grid (float): Grid type (0 = square, 1 = hex)\n * - u_size (float): Grid size relative to the image box (0 to 1)\n * - u_radius (float): Maximum dot size relative to grid cell (0 to 2)\n * - u_contrast (float): Contrast applied to the sampled image, at 0 the luminance is flat so all the dots get equal size (0 to 1)\n * - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)\n * - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)\n * - u_grainSize (float): Scale applied to both grain distortion and grain overlay, needs grainMixer or grainOverlay > 0 (0 to 1)\n *\n * Vertex shader outputs (used in fragment shader):\n * - v_imageUV (vec2): Image UV coordinates with global sizing (rotation, scale, offset, etc) applied\n *\n * Vertex shader uniforms:\n * - u_resolution (vec2): Canvas resolution in pixels\n * - u_pixelRatio (float): Device pixel ratio\n * - u_originX (float): Reference point for positioning world width in the canvas, over HTML where the grid is anchored (0 to 1)\n * - u_originY (float): Reference point for positioning world height in the canvas, over HTML where the grid is anchored from the top (0 to 1)\n * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)\n * - u_scale (float): Overall zoom level of the graphics (0.1 to 4)\n * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)\n * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)\n * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)\n * - u_imageAspectRatio (float): Aspect ratio of the source image\n *\n */\n\n// language=GLSL\nexport const halftoneDotsFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorBack;\nuniform float u_radius;\nuniform float u_contrast;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\nuniform float u_imageIsHtml;\nuniform float u_originX;\nuniform float u_originY;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform float u_size;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\nuniform float u_grainSize;\nuniform float u_grid;\nuniform bool u_originalColors;\nuniform bool u_inverted;\nuniform float u_type;\n\nin vec2 v_imageUV;\n\nfloat getImageAspectRatio() {\n return mix(u_imageAspectRatio, u_resolution.x / u_resolution.y, u_imageIsHtml);\n}\n\nout vec4 fragColor;\n\nvec4 sampleImage(vec2 uv) {\n vec4 image = texture(u_image, uv);\n image.rgb /= max(image.a, .0001);\n return image;\n}\n\n${ declarePI }\n${ rotation2 }\n${ proceduralHash21 }\n\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = hash21(i);\n float b = hash21(i + vec2(1.0, 0.0));\n float c = hash21(i + vec2(0.0, 1.0));\n float d = hash21(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}\n\nfloat lst(float edge0, float edge1, float x) {\n return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n}\n\nfloat sst(float edge0, float edge1, float x) {\n return smoothstep(edge0, edge1, x);\n}\n\nfloat getCircle(vec2 uv, float r, float baseR) {\n r = mix(.25 * baseR, 0., r);\n float d = length(uv - .5);\n float aa = fwidth(d);\n return 1. - smoothstep(r - aa, r + aa, d);\n}\n\nfloat getCell(vec2 uv) {\n float insideX = step(0.0, uv.x) * (1.0 - step(1.0, uv.x));\n float insideY = step(0.0, uv.y) * (1.0 - step(1.0, uv.y));\n return insideX * insideY;\n}\n\nfloat getCircleWithHole(vec2 uv, float r, float baseR) {\n float cell = getCell(uv);\n\n r = mix(.75 * baseR, 0., r);\n float rMod = mod(r, .5);\n\n float d = length(uv - .5);\n float aa = fwidth(d);\n float circle = 1. - smoothstep(rMod - aa, rMod + aa, d);\n if (r < .5) {\n return circle;\n } else {\n return cell - circle;\n }\n}\n\nfloat getGooeyBall(vec2 uv, float r, float baseR) {\n float d = length(uv - .5);\n float sizeRadius = .3;\n if (u_grid == 1.) {\n sizeRadius = .42;\n }\n sizeRadius = mix(sizeRadius * baseR, 0., r);\n d = 1. - sst(0., sizeRadius, d);\n\n d = pow(d, 2. + baseR);\n return d;\n}\n\nfloat getSoftBall(vec2 uv, float r, float baseR) {\n float d = length(uv - .5);\n float sizeRadius = clamp(baseR, 0., 1.);\n sizeRadius = mix(.5 * sizeRadius, 0., r);\n d = 1. - lst(0., sizeRadius, d);\n float powRadius = 1. - lst(0., 2., baseR);\n d = pow(d, 4. + 3. * powRadius);\n return d;\n}\n\nfloat getUvFrame(vec2 uv, vec2 pad) {\n float aa = 0.0001;\n\n float left = smoothstep(-pad.x, -pad.x + aa, uv.x);\n float right = smoothstep(1.0 + pad.x, 1.0 + pad.x - aa, uv.x);\n float bottom = smoothstep(-pad.y, -pad.y + aa, uv.y);\n float top = smoothstep(1.0 + pad.y, 1.0 + pad.y - aa, uv.y);\n\n return left * right * bottom * top;\n}\n\nfloat sigmoid(float x, float k) {\n return 1.0 / (1.0 + exp(-k * (x - 0.5)));\n}\n\nfloat getLumAtPx(vec2 uv, float contrast) {\n vec4 tex = sampleImage(uv);\n vec3 color = vec3(\n sigmoid(tex.r, contrast),\n sigmoid(tex.g, contrast),\n sigmoid(tex.b, contrast)\n );\n float lum = dot(vec3(0.2126, 0.7152, 0.0722), color);\n lum = mix(1., lum, tex.a);\n lum = u_inverted ? (1. - lum) : lum;\n return lum;\n}\n\nvec2 getGridOrigin() {\n return mix(vec2(.5), vec2(u_originX, u_originY), u_imageIsHtml);\n}\n\nfloat sizeToPx(float size) {\n return 1000. / mix(300., 7., pow(size, .7));\n}\n\nfloat getLumBall(vec2 p, vec2 pad, vec2 inCellOffset, float contrast, float baseR, float stepSize, out vec4 ballColor) {\n p += inCellOffset;\n vec2 uv_i = floor(p);\n vec2 uv_f = fract(p);\n vec2 samplingUV = (uv_i + .5 - inCellOffset) * pad + getGridOrigin();\n float outOfFrame = getUvFrame(samplingUV, pad * stepSize);\n\n float lum = getLumAtPx(samplingUV, contrast);\n ballColor = sampleImage(samplingUV);\n ballColor.rgb *= ballColor.a;\n ballColor *= outOfFrame;\n\n float ball = 0.;\n if (u_type == 0.) {\n // classic\n ball = getCircle(uv_f, lum, baseR);\n } else if (u_type == 1.) {\n // gooey\n ball = getGooeyBall(uv_f, lum, baseR);\n } else if (u_type == 2.) {\n // holes\n ball = getCircleWithHole(uv_f, lum, baseR);\n } else if (u_type == 3.) {\n // soft\n ball = getSoftBall(uv_f, lum, baseR);\n }\n\n return ball * outOfFrame;\n}\n\n\nvoid main() {\n\n float stepMultiplier = 1.;\n if (u_type == 0.) {\n // classic\n stepMultiplier = 2.;\n } else if (u_type == 1. || u_type == 3.) {\n // gooey & soft\n stepMultiplier = 6.;\n }\n\n vec2 cssSize = u_resolution / u_pixelRatio;\n float cellsPerSide = mix(mix(300., 7., pow(u_size, .7)), cssSize.y / sizeToPx(u_size), u_imageIsHtml);\n cellsPerSide /= stepMultiplier;\n float cellSizeY = 1. / cellsPerSide;\n vec2 pad = cellSizeY * vec2(1. / getImageAspectRatio(), 1.);\n if (u_type == 1. && u_grid == 1.) {\n // gooey diagonal grid works differently\n pad *= .7;\n }\n\n vec2 uv = v_imageUV;\n uv -= getGridOrigin();\n uv /= pad;\n\n float contrast = mix(0., 15., pow(u_contrast, 1.5));\n float baseRadius = u_radius;\n if (u_originalColors == true) {\n contrast = mix(.1, 4., pow(u_contrast, 2.));\n baseRadius = 2. * pow(.5 * u_radius, .3);\n }\n\n float totalShape = 0.;\n vec3 totalColor = vec3(0.);\n float totalOpacity = 0.;\n\n vec4 ballColor;\n float shape;\n float stepSize = 1. / stepMultiplier;\n for (float x = -0.5; x < 0.5; x += stepSize) {\n for (float y = -0.5; y < 0.5; y += stepSize) {\n vec2 offset = vec2(x, y);\n\n if (u_grid == 1.) {\n float rowIndex = floor((y + .5) / stepSize);\n float colIndex = floor((x + .5) / stepSize);\n if (stepSize == 1.) {\n rowIndex = floor(uv.y + y + 1.);\n if (u_type == 1.) {\n colIndex = floor(uv.x + x + 1.);\n }\n }\n if (u_type == 1.) {\n if (mod(rowIndex + colIndex, 2.) == 1.) {\n continue;\n }\n } else {\n if (mod(rowIndex, 2.) == 1.) {\n offset.x += .5 * stepSize;\n }\n }\n }\n\n shape = getLumBall(uv, pad, offset, contrast, baseRadius, stepSize, ballColor);\n totalColor += ballColor.rgb * shape;\n totalShape += shape;\n totalOpacity += shape;\n }\n }\n\n const float eps = 1e-4;\n\n totalColor /= max(totalShape, eps);\n totalOpacity /= max(totalShape, eps);\n\n float finalShape = 0.;\n if (u_type == 0.) {\n finalShape = min(1., totalShape);\n } else if (u_type == 1.) {\n float aa = fwidth(totalShape);\n float th = .5;\n finalShape = smoothstep(th - aa, th + aa, totalShape);\n } else if (u_type == 2.) {\n finalShape = min(1., totalShape);\n } else if (u_type == 3.) {\n finalShape = totalShape;\n }\n\n vec2 grainSize = mix(2000., 200., u_grainSize) * mix(vec2(1., 1. / getImageAspectRatio()), cssSize / 1000., u_imageIsHtml);\n vec2 grainUV = v_imageUV - getGridOrigin();\n grainUV *= grainSize;\n grainUV += .5;\n if (u_grainMixer > 0.) {\n float grain = valueNoise(grainUV);\n grain = smoothstep(.55, .7 + .2 * u_grainMixer, grain);\n grain *= u_grainMixer;\n finalShape = mix(finalShape, 0., grain);\n }\n\n vec3 color = vec3(0.);\n float opacity = 0.;\n\n if (u_originalColors == true) {\n color = totalColor * finalShape;\n opacity = totalOpacity * finalShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n } else {\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 color = fgColor * finalShape;\n opacity = fgOpacity * finalShape;\n color += bgColor * (1. - opacity);\n opacity += bgOpacity * (1. - opacity);\n }\n\n if (u_grainOverlay > 0.) {\n float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));\n grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);\n grainOverlay = pow(grainOverlay, 1.3);\n\n float grainOverlayV = grainOverlay * 2. - 1.;\n vec3 grainOverlayColor = vec3(step(0., grainOverlayV));\n float grainOverlayStrength = u_grainOverlay * abs(grainOverlayV);\n grainOverlayStrength = pow(grainOverlayStrength, .8);\n color = mix(color, grainOverlayColor, .5 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n }\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface HalftoneDotsUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_colorFront: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_size: number;\n u_grid: (typeof HalftoneDotsGrids)[HalftoneDotsGrid];\n u_radius: number;\n u_contrast: number;\n u_originalColors: boolean;\n u_inverted: boolean;\n u_grainMixer: number;\n u_grainOverlay: number;\n u_grainSize: number;\n u_type: (typeof HalftoneDotsTypes)[HalftoneDotsType];\n}\n\nexport interface HalftoneDotsParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string;\n colorFront?: string;\n colorBack?: string;\n size?: number;\n grid?: HalftoneDotsGrid;\n radius?: number;\n contrast?: number;\n originalColors?: boolean;\n inverted?: boolean;\n grainMixer?: number;\n grainOverlay?: number;\n grainSize?: number;\n type?: HalftoneDotsType;\n}\n\nexport const HalftoneDotsTypes = {\n classic: 0,\n gooey: 1,\n holes: 2,\n soft: 3,\n} as const;\n\nexport type HalftoneDotsType = keyof typeof HalftoneDotsTypes;\n\nexport const HalftoneDotsGrids = {\n square: 0,\n hex: 1,\n} as const;\n\nexport type HalftoneDotsGrid = keyof typeof HalftoneDotsGrids;\n"],
5
+ "mappings": ";;;;;AACA,eAAmE;AACnE,SAAS,WAAW,WAAW,wBAAwB;AA0ChD,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuC/C,SAAU;AAAA,EACV,SAAU;AAAA,EACV,gBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0Tb,MAAM,oBAAoB;AAAA,EAC/B,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AACR;AAIO,MAAM,oBAAoB;AAAA,EAC/B,QAAQ;AAAA,EACR,KAAK;AACP;",
6
+ "names": []
7
+ }
@@ -0,0 +1,66 @@
1
+ import type { vec4 } from '../types.js';
2
+ import type { ShaderMotionParams } from '../shader-mount.js';
3
+ import type { ShaderSizingParams, ShaderSizingUniforms } from '../shader-sizing.js';
4
+ export declare const heatmapMeta: {
5
+ readonly maxColorCount: 10;
6
+ };
7
+ /**
8
+ * A glowing gradient of colors flowing through an input shape.
9
+ * The effect creates a smoothly animated wave of intensity across the image.
10
+ *
11
+ * Fragment shader uniforms:
12
+ * - u_time (float): Animation time
13
+ * - u_image (sampler2D): Pre-processed source image texture (R = contour, G = outer blur, B = inner blur)
14
+ * - u_colorBack (vec4): Background color in RGBA
15
+ * - u_colors (vec4[]): Up to 10 heatmap colors in RGBA
16
+ * - u_colorsCount (float): Number of active colors
17
+ * - u_contour (float): Heat intensity near the edges of the input shape (0 to 1)
18
+ * - u_angle (float): Direction of the heatwaves in degrees, needs innerGlow or outerGlow > 0 (0 to 360)
19
+ * - u_noise (float): Grain applied across the entire graphic (0 to 1)
20
+ * - u_innerGlow (float): Size of the heated area inside the input shape (0 to 1)
21
+ * - u_outerGlow (float): Size of the heated area outside the input shape (0 to 1)
22
+ *
23
+ * Vertex shader outputs (used in fragment shader):
24
+ * - v_imageUV (vec2): UV coordinates for sampling the source image, with fit, scale, rotation, and offset applied
25
+ * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
26
+ *
27
+ * Vertex shader uniforms:
28
+ * - u_resolution (vec2): Canvas resolution in pixels
29
+ * - u_pixelRatio (float): Device pixel ratio
30
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
31
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
32
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
33
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
34
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
35
+ * - u_scale (float): Overall zoom level of the graphics (0.1 to 4)
36
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
37
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
38
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
39
+ * - u_imageAspectRatio (float): Aspect ratio of the source image
40
+ *
41
+ */
42
+ export declare const heatmapFragmentShader: string;
43
+ export declare function toProcessedHeatmap(file: File | string): Promise<{
44
+ blob: Blob;
45
+ }>;
46
+ export interface HeatmapUniforms extends ShaderSizingUniforms {
47
+ u_image: HTMLImageElement | string;
48
+ u_contour: number;
49
+ u_angle: number;
50
+ u_noise: number;
51
+ u_innerGlow: number;
52
+ u_outerGlow: number;
53
+ u_colorBack: [number, number, number, number];
54
+ u_colors: vec4[];
55
+ u_colorsCount: number;
56
+ }
57
+ export interface HeatmapParams extends ShaderSizingParams, ShaderMotionParams {
58
+ image: HTMLImageElement | string;
59
+ contour?: number;
60
+ angle?: number;
61
+ noise?: number;
62
+ innerGlow?: number;
63
+ outerGlow?: number;
64
+ colorBack?: string;
65
+ colors?: string[];
66
+ }