@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,123 @@
1
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
+ * Paper Shaders *
3
+ * https://github.com/paper-design/shaders *
4
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
+
6
+ import {} from "../shader-sizing.js";
7
+ import { declarePI, rotation2, textureRandomizerR, textureRandomizerGB } from "../shader-utils.js";
8
+ const dotOrbitMeta = {
9
+ maxColorCount: 10
10
+ };
11
+ const dotOrbitFragmentShader = `#version 300 es
12
+ precision mediump float;
13
+
14
+ uniform float u_time;
15
+
16
+ uniform sampler2D u_noiseTexture;
17
+
18
+ uniform vec4 u_colorBack;
19
+ uniform vec4 u_colors[${dotOrbitMeta.maxColorCount}];
20
+ uniform float u_colorsCount;
21
+ uniform float u_stepsPerColor;
22
+ uniform float u_size;
23
+ uniform float u_sizeRange;
24
+ uniform float u_spreading;
25
+
26
+ in vec2 v_patternUV;
27
+
28
+ out vec4 fragColor;
29
+
30
+ ${declarePI}
31
+ ${rotation2}
32
+ ${textureRandomizerR}
33
+ ${textureRandomizerGB}
34
+
35
+
36
+ vec3 voronoiShape(vec2 uv, float time) {
37
+ vec2 i_uv = floor(uv);
38
+ vec2 f_uv = fract(uv);
39
+
40
+ float spreading = .25 * clamp(u_spreading, 0., 1.);
41
+
42
+ float minDist = 1.;
43
+ vec2 randomizer = vec2(0.);
44
+ for (int y = -1; y <= 1; y++) {
45
+ for (int x = -1; x <= 1; x++) {
46
+ vec2 tileOffset = vec2(float(x), float(y));
47
+ vec2 rand = randomGB(i_uv + tileOffset);
48
+ vec2 cellCenter = vec2(.5 + 1e-4);
49
+ cellCenter += spreading * cos(time + TWO_PI * rand);
50
+ cellCenter -= .5;
51
+ cellCenter = rotate(cellCenter, randomR(vec2(rand.x, rand.y)) + .1 * time);
52
+ cellCenter += .5;
53
+ float dist = length(tileOffset + cellCenter - f_uv);
54
+ if (dist < minDist) {
55
+ minDist = dist;
56
+ randomizer = rand;
57
+ }
58
+ }
59
+ }
60
+
61
+ return vec3(minDist, randomizer);
62
+ }
63
+
64
+ void main() {
65
+
66
+ vec2 shape_uv = v_patternUV;
67
+ shape_uv *= 1.5;
68
+
69
+ const float firstFrameOffset = -10.;
70
+ float t = u_time + firstFrameOffset;
71
+
72
+ vec3 voronoi = voronoiShape(shape_uv, t) + 1e-4;
73
+
74
+ float radius = .25 * clamp(u_size, 0., 1.) - .5 * clamp(u_sizeRange, 0., 1.) * voronoi[2];
75
+ float dist = voronoi[0];
76
+ float edgeWidth = fwidth(dist);
77
+ float dots = 1. - smoothstep(radius - edgeWidth, radius + edgeWidth, dist);
78
+
79
+ float shape = voronoi[1];
80
+
81
+ float mixer = shape * (u_colorsCount - 1.);
82
+ mixer = (shape - .5 / u_colorsCount) * u_colorsCount;
83
+ float steps = max(1., u_stepsPerColor);
84
+
85
+ vec4 gradient = u_colors[0];
86
+ gradient.rgb *= gradient.a;
87
+ for (int i = 1; i < ${dotOrbitMeta.maxColorCount}; i++) {
88
+ if (i >= int(u_colorsCount)) break;
89
+ float localT = clamp(mixer - float(i - 1), 0.0, 1.0);
90
+ localT = round(localT * steps) / steps;
91
+ vec4 c = u_colors[i];
92
+ c.rgb *= c.a;
93
+ gradient = mix(gradient, c, localT);
94
+ }
95
+
96
+ if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {
97
+ float localT = mixer + 1.;
98
+ if (mixer > (u_colorsCount - 1.)) {
99
+ localT = mixer - (u_colorsCount - 1.);
100
+ }
101
+ localT = round(localT * steps) / steps;
102
+ vec4 cFst = u_colors[0];
103
+ cFst.rgb *= cFst.a;
104
+ vec4 cLast = u_colors[int(u_colorsCount - 1.)];
105
+ cLast.rgb *= cLast.a;
106
+ gradient = mix(cLast, cFst, localT);
107
+ }
108
+
109
+ vec3 color = gradient.rgb * dots;
110
+ float opacity = gradient.a * dots;
111
+
112
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
113
+ color = color + bgColor * (1. - opacity);
114
+ opacity = opacity + u_colorBack.a * (1. - opacity);
115
+
116
+ fragColor = vec4(color, opacity);
117
+ }
118
+ `;
119
+ export {
120
+ dotOrbitFragmentShader,
121
+ dotOrbitMeta
122
+ };
123
+ //# sourceMappingURL=dot-orbit.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shaders/dot-orbit.ts"],
4
+ "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, textureRandomizerR, textureRandomizerGB } from '../shader-utils.js';\n\nexport const dotOrbitMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Animated multi-color dots pattern with each dot orbiting around its cell center.\n * Supports up to 10 colors and various shape and motion controls.\n *\n * Fragment shader uniforms:\n * - u_time (float): Animation time\n * - u_colorBack (vec4): Background color in RGBA\n * - u_colors (vec4[]): Up to 10 base colors in RGBA\n * - u_colorsCount (float): Number of active colors\n * - u_stepsPerColor (float): Number of extra colors between base colors, 1 = N colors, 2 = 2\u00D7N, etc., needs 2+ colors (1 to 4)\n * - u_size (float): Dot radius relative to cell size (0 to 1)\n * - u_sizeRange (float): Random variation in shape size, 0 = uniform, higher = random up to base size (0 to 1)\n * - u_spreading (float): Maximum orbit distance around cell center, dots are static at 0 (0 to 1)\n * - u_noiseTexture (sampler2D): Pre-computed randomizer source texture\n *\n * Vertex shader outputs (used in fragment shader):\n * - v_patternUV (vec2): UV coordinates in pixels (scaled by 0.01 for precision), with rotation and offset 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 (0 to 1)\n * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)\n * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas\n * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas\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.01 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 *\n */\n\n// language=GLSL\nexport const dotOrbitFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${ dotOrbitMeta.maxColorCount }];\nuniform float u_colorsCount;\nuniform float u_stepsPerColor;\nuniform float u_size;\nuniform float u_sizeRange;\nuniform float u_spreading;\n\nin vec2 v_patternUV;\n\nout vec4 fragColor;\n\n${ declarePI }\n${ rotation2 }\n${ textureRandomizerR }\n${ textureRandomizerGB }\n\n\nvec3 voronoiShape(vec2 uv, float time) {\n vec2 i_uv = floor(uv);\n vec2 f_uv = fract(uv);\n\n float spreading = .25 * clamp(u_spreading, 0., 1.);\n\n float minDist = 1.;\n vec2 randomizer = vec2(0.);\n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 tileOffset = vec2(float(x), float(y));\n vec2 rand = randomGB(i_uv + tileOffset);\n vec2 cellCenter = vec2(.5 + 1e-4);\n cellCenter += spreading * cos(time + TWO_PI * rand);\n cellCenter -= .5;\n cellCenter = rotate(cellCenter, randomR(vec2(rand.x, rand.y)) + .1 * time);\n cellCenter += .5;\n float dist = length(tileOffset + cellCenter - f_uv);\n if (dist < minDist) {\n minDist = dist;\n randomizer = rand;\n }\n }\n }\n\n return vec3(minDist, randomizer);\n}\n\nvoid main() {\n\n vec2 shape_uv = v_patternUV;\n shape_uv *= 1.5;\n\n const float firstFrameOffset = -10.;\n float t = u_time + firstFrameOffset;\n\n vec3 voronoi = voronoiShape(shape_uv, t) + 1e-4;\n\n float radius = .25 * clamp(u_size, 0., 1.) - .5 * clamp(u_sizeRange, 0., 1.) * voronoi[2];\n float dist = voronoi[0];\n float edgeWidth = fwidth(dist);\n float dots = 1. - smoothstep(radius - edgeWidth, radius + edgeWidth, dist);\n\n float shape = voronoi[1];\n\n float mixer = shape * (u_colorsCount - 1.);\n mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\n float steps = max(1., u_stepsPerColor);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${ dotOrbitMeta.maxColorCount }; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0.0, 1.0);\n localT = round(localT * steps) / steps;\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {\n float localT = mixer + 1.;\n if (mixer > (u_colorsCount - 1.)) {\n localT = mixer - (u_colorsCount - 1.);\n }\n localT = round(localT * steps) / steps;\n vec4 cFst = u_colors[0];\n cFst.rgb *= cFst.a;\n vec4 cLast = u_colors[int(u_colorsCount - 1.)];\n cLast.rgb *= cLast.a;\n gradient = mix(cLast, cFst, localT);\n }\n\n vec3 color = gradient.rgb * dots;\n float opacity = gradient.a * dots;\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\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DotOrbitUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_size: number;\n u_sizeRange: number;\n u_spreading: number;\n u_stepsPerColor: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface DotOrbitParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n size?: number;\n sizeRange?: number;\n spreading?: number;\n stepsPerColor?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,eAAmE;AACnE,SAAS,WAAW,WAAW,oBAAoB,2BAA2B;AAEvE,MAAM,eAAe;AAAA,EAC1B,eAAe;AACjB;AAoCO,MAAM,yBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQrB,aAAa,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWjD,SAAU;AAAA,EACV,SAAU;AAAA,EACV,kBAAmB;AAAA,EACnB,mBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAsDE,aAAa,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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
+ }
@@ -0,0 +1,115 @@
1
+ import type { ShaderMotionParams } from '../shader-mount.js';
2
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
3
+ /**
4
+ * Fluted glass image filter that transforms an image into streaked, ribbed distortions,
5
+ * giving a mix of clarity and obscurity.
6
+ *
7
+ * Fragment shader uniforms:
8
+ * - u_resolution (vec2): Canvas resolution in pixels
9
+ * - u_pixelRatio (float): Device pixel ratio
10
+ * - u_image (sampler2D): Source image texture, premultiplied alpha
11
+ * - u_imageAspectRatio (float): Aspect ratio of the source image; over HTML the canvas aspect from u_resolution is used instead
12
+ * - u_imageIsHtml (float): 1 when u_image is HTML. HTML is drawn 1:1, so the flutes are sized in CSS px to keep their size
13
+ * over it, size setting the flute width from 5px to 200px, and anchored at originX / originY instead of the center,
14
+ * 0 0 being the top left like CSS. Their distortion follows the flute size; margins and edges stay relative to the frame
15
+ * - u_colorBack (vec4): Background color in RGBA
16
+ * - u_colorShadow (vec4): Shadows color in RGBA, needs shadows > 0
17
+ * - u_colorHighlight (vec4): Highlights color in RGBA, needs highlights > 0
18
+ * - u_shadows (float): Color gradient added over image and background, following distortion shape, needs colorShadow alpha > 0 (0 to 1)
19
+ * - u_highlights (float): Thin strokes along distortion shape, useful for antialiasing on small grid (0 to 1)
20
+ * - u_size (float): Size of the distortion shape grid (0 to 1)
21
+ * - u_shape (float): Grid shape (1 = lines, 2 = linesIrregular, 3 = wave, 4 = zigzag, 5 = pattern)
22
+ * - u_angle (float): Direction of the grid relative to the image in degrees (0 to 180)
23
+ * - u_distortionShape (float): Shape of distortion (1 = prism, 2 = lens, 3 = contour, 4 = cascade, 5 = flat)
24
+ * - u_distortion (float): Power of distortion applied within each stripe (0 to 1)
25
+ * - u_shift (float): Texture shift in direction opposite to the grid, needs distortion > 0 (-1 to 1)
26
+ * - u_stretch (float): Extra distortion along the grid lines (0 to 1)
27
+ * - u_blur (float): One-directional blur over the image and extra blur around edges (0 to 1)
28
+ * - u_edges (float): Glass distortion and softness on the image edges (0 to 1)
29
+ * - u_marginLeft (float): Distance from the left edge to the effect (0 to 1)
30
+ * - u_marginRight (float): Distance from the right edge to the effect (0 to 1)
31
+ * - u_marginTop (float): Distance from the top edge to the effect (0 to 1)
32
+ * - u_marginBottom (float): Distance from the bottom edge to the effect (0 to 1)
33
+ * - u_grainMixer (float): Strength of grain distortion applied to shape edges, needs distortion > 0 (0 to 1)
34
+ * - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)
35
+ *
36
+ * Vertex shader outputs (used in fragment shader):
37
+ * - v_imageUV (vec2): Image UV coordinates with global sizing (rotation, scale, offset, etc) applied
38
+ *
39
+ * Vertex shader uniforms:
40
+ * - u_resolution (vec2): Canvas resolution in pixels
41
+ * - u_pixelRatio (float): Device pixel ratio
42
+ * - u_originX (float): Reference point for positioning world width in the canvas, over HTML where the effect is anchored (0 to 1)
43
+ * - u_originY (float): Reference point for positioning world height in the canvas, over HTML where the effect is anchored from the top (0 to 1)
44
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
45
+ * - u_scale (float): Overall zoom level of the graphics (0.1 to 4)
46
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
47
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
48
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
49
+ * - u_imageAspectRatio (float): Aspect ratio of the source image
50
+ *
51
+ */
52
+ export declare const flutedGlassFragmentShader: string;
53
+ export interface FlutedGlassUniforms extends ShaderSizingUniforms {
54
+ u_image: HTMLImageElement | string | undefined;
55
+ u_colorBack: [number, number, number, number];
56
+ u_colorShadow: [number, number, number, number];
57
+ u_colorHighlight: [number, number, number, number];
58
+ u_shadows: number;
59
+ u_size: number;
60
+ u_angle: number;
61
+ u_distortion: number;
62
+ u_shift: number;
63
+ u_blur: number;
64
+ u_edges: number;
65
+ u_marginLeft: number;
66
+ u_marginRight: number;
67
+ u_marginTop: number;
68
+ u_marginBottom: number;
69
+ u_stretch: number;
70
+ u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];
71
+ u_highlights: number;
72
+ u_shape: (typeof GlassGridShapes)[GlassGridShape];
73
+ u_grainMixer: number;
74
+ u_grainOverlay: number;
75
+ }
76
+ export interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {
77
+ image?: HTMLImageElement | string;
78
+ colorBack?: string;
79
+ colorShadow?: string;
80
+ colorHighlight?: string;
81
+ shadows?: number;
82
+ size?: number;
83
+ angle?: number;
84
+ distortion?: number;
85
+ shift?: number;
86
+ blur?: number;
87
+ edges?: number;
88
+ margin?: number;
89
+ marginLeft?: number;
90
+ marginRight?: number;
91
+ marginTop?: number;
92
+ marginBottom?: number;
93
+ stretch?: number;
94
+ distortionShape?: GlassDistortionShape;
95
+ highlights?: number;
96
+ shape?: GlassGridShape;
97
+ grainMixer?: number;
98
+ grainOverlay?: number;
99
+ }
100
+ export declare const GlassGridShapes: {
101
+ readonly lines: 1;
102
+ readonly linesIrregular: 2;
103
+ readonly wave: 3;
104
+ readonly zigzag: 4;
105
+ readonly pattern: 5;
106
+ };
107
+ export declare const GlassDistortionShapes: {
108
+ readonly prism: 1;
109
+ readonly lens: 2;
110
+ readonly contour: 3;
111
+ readonly cascade: 4;
112
+ readonly flat: 5;
113
+ };
114
+ export type GlassDistortionShape = keyof typeof GlassDistortionShapes;
115
+ export type GlassGridShape = keyof typeof GlassGridShapes;
@@ -0,0 +1,361 @@
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 flutedGlassFragmentShader = `#version 300 es
9
+ precision mediump float;
10
+
11
+ uniform vec2 u_resolution;
12
+ uniform float u_pixelRatio;
13
+
14
+ uniform vec4 u_colorBack;
15
+ uniform vec4 u_colorShadow;
16
+ uniform vec4 u_colorHighlight;
17
+
18
+ uniform sampler2D u_image;
19
+ uniform float u_imageAspectRatio;
20
+ uniform float u_imageIsHtml;
21
+ uniform float u_originX;
22
+ uniform float u_originY;
23
+
24
+ uniform float u_size;
25
+ uniform float u_shadows;
26
+ uniform float u_angle;
27
+ uniform float u_stretch;
28
+ uniform float u_shape;
29
+ uniform float u_distortion;
30
+ uniform float u_highlights;
31
+ uniform float u_distortionShape;
32
+ uniform float u_shift;
33
+ uniform float u_blur;
34
+ uniform float u_edges;
35
+ uniform float u_marginLeft;
36
+ uniform float u_marginRight;
37
+ uniform float u_marginTop;
38
+ uniform float u_marginBottom;
39
+ uniform float u_grainMixer;
40
+ uniform float u_grainOverlay;
41
+
42
+ in vec2 v_imageUV;
43
+
44
+ float getImageAspectRatio() {
45
+ return mix(u_imageAspectRatio, u_resolution.x / u_resolution.y, u_imageIsHtml);
46
+ }
47
+
48
+ out vec4 fragColor;
49
+
50
+ ${declarePI}
51
+ float sizeToPx(float size) {
52
+ return 1000. / mix(200., 5., size);
53
+ }
54
+ ${rotation2}
55
+ ${proceduralHash21}
56
+
57
+ float valueNoise(vec2 st) {
58
+ vec2 i = floor(st);
59
+ vec2 f = fract(st);
60
+ float a = hash21(i);
61
+ float b = hash21(i + vec2(1.0, 0.0));
62
+ float c = hash21(i + vec2(0.0, 1.0));
63
+ float d = hash21(i + vec2(1.0, 1.0));
64
+ vec2 u = f * f * (3.0 - 2.0 * f);
65
+ float x1 = mix(a, b, u.x);
66
+ float x2 = mix(c, d, u.x);
67
+ return mix(x1, x2, u.y);
68
+ }
69
+
70
+ float getUvFrame(vec2 uv, float softness) {
71
+ float aax = 2. * fwidth(uv.x);
72
+ float aay = 2. * fwidth(uv.y);
73
+ float left = smoothstep(0., aax + softness, uv.x);
74
+ float right = 1. - smoothstep(1. - softness - aax, 1., uv.x);
75
+ float bottom = smoothstep(0., aay + softness, uv.y);
76
+ float top = 1. - smoothstep(1. - softness - aay, 1., uv.y);
77
+ return left * right * bottom * top;
78
+ }
79
+
80
+ const int MAX_RADIUS = 50;
81
+ vec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {
82
+ if (sigma <= .5) return texture(tex, uv);
83
+ int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));
84
+
85
+ float twoSigma2 = 2.0 * sigma * sigma;
86
+ float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);
87
+
88
+ vec4 sum = texture(tex, uv) * gaussianNorm;
89
+ float weightSum = gaussianNorm;
90
+
91
+ for (int i = 1; i <= MAX_RADIUS; i++) {
92
+ if (i > radius) break;
93
+
94
+ float x = float(i);
95
+ float w = exp(-(x * x) / twoSigma2) * gaussianNorm;
96
+
97
+ vec2 offset = dir * texelSize * x;
98
+ vec4 s1 = texture(tex, uv + offset);
99
+ vec4 s2 = texture(tex, uv - offset);
100
+
101
+ sum += (s1 + s2) * w;
102
+ weightSum += 2.0 * w;
103
+ }
104
+
105
+ return sum / weightSum;
106
+ }
107
+
108
+ vec2 rotateAspect(vec2 p, float a, float aspect) {
109
+ p.x *= aspect;
110
+ p = rotate(p, a);
111
+ p.x /= aspect;
112
+ return p;
113
+ }
114
+
115
+ float smoothFract(float x) {
116
+ float f = fract(x);
117
+ float w = fwidth(x);
118
+
119
+ float edge = abs(f - 0.5) - 0.5;
120
+ float band = smoothstep(-w, w, edge);
121
+
122
+ return mix(f, 1.0 - f, band);
123
+ }
124
+
125
+ void main() {
126
+
127
+ float patternRotation = -u_angle * PI / 180.;
128
+ float patternSize = mix(mix(200., 2., u_size), u_resolution.x / u_pixelRatio / sizeToPx(u_size), u_imageIsHtml);
129
+ vec2 patternOrigin = mix(vec2(.5), vec2(u_originX, u_originY), u_imageIsHtml);
130
+
131
+ vec2 uv = v_imageUV;
132
+
133
+ vec2 uvMask = gl_FragCoord.xy / u_resolution.xy;
134
+ vec2 sw = vec2(.005);
135
+ vec4 margins = vec4(u_marginLeft, u_marginTop, u_marginRight, u_marginBottom);
136
+ float mask =
137
+ smoothstep(margins[0], margins[0] + sw.x, uvMask.x + sw.x) *
138
+ smoothstep(margins[2], margins[2] + sw.x, 1.0 - uvMask.x + sw.x) *
139
+ smoothstep(margins[1], margins[1] + sw.y, uvMask.y + sw.y) *
140
+ smoothstep(margins[3], margins[3] + sw.y, 1.0 - uvMask.y + sw.y);
141
+ float maskOuter =
142
+ smoothstep(margins[0] - sw.x, margins[0], uvMask.x + sw.x) *
143
+ smoothstep(margins[2] - sw.x, margins[2], 1.0 - uvMask.x + sw.x) *
144
+ smoothstep(margins[1] - sw.y, margins[1], uvMask.y + sw.y) *
145
+ smoothstep(margins[3] - sw.y, margins[3], 1.0 - uvMask.y + sw.y);
146
+ float maskStroke = maskOuter - mask;
147
+ float maskInner =
148
+ smoothstep(margins[0] - 2. * sw.x, margins[0], uvMask.x) *
149
+ smoothstep(margins[2] - 2. * sw.x, margins[2], 1.0 - uvMask.x) *
150
+ smoothstep(margins[1] - 2. * sw.y, margins[1], uvMask.y) *
151
+ smoothstep(margins[3] - 2. * sw.y, margins[3], 1.0 - uvMask.y);
152
+ float maskStrokeInner = maskInner - mask;
153
+
154
+ uv -= patternOrigin;
155
+ uv *= patternSize;
156
+ uv = rotateAspect(uv, patternRotation, getImageAspectRatio());
157
+
158
+ float curve = 0.;
159
+ float patternY = uv.y / getImageAspectRatio();
160
+ if (u_shape > 4.5) {
161
+ // pattern
162
+ curve = .5 + .5 * sin(.5 * PI * uv.x) * cos(.5 * PI * patternY);
163
+ } else if (u_shape > 3.5) {
164
+ // zigzag
165
+ curve = 10. * abs(fract(.1 * patternY) - .5);
166
+ } else if (u_shape > 2.5) {
167
+ // wave
168
+ curve = 4. * sin(.23 * patternY);
169
+ } else if (u_shape > 1.5) {
170
+ // lines irregular
171
+ curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);
172
+ } else {
173
+ // lines
174
+ }
175
+
176
+ vec2 UvToFract = uv + curve;
177
+ vec2 fractOrigUV = fract(uv);
178
+ vec2 floorOrigUV = floor(uv);
179
+
180
+ float x = smoothFract(UvToFract.x);
181
+ float xNonSmooth = fract(UvToFract.x) + .0001;
182
+
183
+ float highlightsWidth = 2. * max(.001, fwidth(UvToFract.x));
184
+ highlightsWidth += 2. * maskStrokeInner;
185
+ float highlights = smoothstep(0., highlightsWidth, xNonSmooth);
186
+ highlights *= smoothstep(1., 1. - highlightsWidth, xNonSmooth);
187
+ highlights = 1. - highlights;
188
+ highlights *= u_highlights;
189
+ highlights = clamp(highlights, 0., 1.);
190
+ highlights *= mask;
191
+
192
+ float shadows = pow(x, 1.3);
193
+ float distortion = 0.;
194
+ float fadeX = 1.;
195
+ float frameFade = 0.;
196
+
197
+ float aa = fwidth(xNonSmooth);
198
+ aa = max(aa, fwidth(uv.x));
199
+ aa = max(aa, fwidth(UvToFract.x));
200
+ aa = max(aa, .0001);
201
+
202
+ if (u_distortionShape == 1.) {
203
+ distortion = -pow(1.5 * x, 3.);
204
+ distortion += (.5 - u_shift);
205
+
206
+ frameFade = pow(1.5 * x, 3.);
207
+ aa = max(.2, aa);
208
+ aa += mix(.2, 0., u_size);
209
+ fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
210
+ distortion = mix(.5, distortion, fadeX);
211
+ } else if (u_distortionShape == 2.) {
212
+ distortion = 2. * pow(x, 2.);
213
+ distortion -= (.5 + u_shift);
214
+
215
+ frameFade = pow(abs(x - .5), 4.);
216
+ aa = max(.2, aa);
217
+ aa += mix(.2, 0., u_size);
218
+ fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
219
+ distortion = mix(.5, distortion, fadeX);
220
+ frameFade = mix(1., frameFade, .5 * fadeX);
221
+ } else if (u_distortionShape == 3.) {
222
+ distortion = pow(2. * (xNonSmooth - .5), 6.);
223
+ distortion -= .25;
224
+ distortion -= u_shift;
225
+
226
+ frameFade = 1. - 2. * pow(abs(x - .4), 2.);
227
+ aa = .15;
228
+ aa += mix(.1, 0., u_size);
229
+ fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
230
+ frameFade = mix(1., frameFade, fadeX);
231
+
232
+ } else if (u_distortionShape == 4.) {
233
+ x = xNonSmooth;
234
+ distortion = sin((x + .25) * TWO_PI);
235
+ shadows = .5 + .5 * asin(distortion) / (.5 * PI);
236
+ distortion *= .5;
237
+ distortion -= u_shift;
238
+ frameFade = .5 + .5 * sin(x * TWO_PI);
239
+ } else if (u_distortionShape == 5.) {
240
+ distortion -= pow(abs(x), .2) * x;
241
+ distortion += .33;
242
+ distortion -= 3. * u_shift;
243
+ distortion *= .33;
244
+
245
+ frameFade = .3 * (smoothstep(.0, 1., x));
246
+ shadows = pow(x, 2.5);
247
+
248
+ aa = max(.1, aa);
249
+ aa += mix(.1, 0., u_size);
250
+ fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
251
+ distortion *= fadeX;
252
+ }
253
+
254
+ vec2 dudx = dFdx(v_imageUV);
255
+ vec2 dudy = dFdy(v_imageUV);
256
+ vec2 grainUV = v_imageUV - patternOrigin;
257
+ grainUV *= (.8 / vec2(length(dudx), length(dudy)));
258
+ grainUV += .5;
259
+ if (u_grainMixer > 0.) {
260
+ float grain = valueNoise(grainUV);
261
+ grain = smoothstep(.4, .7, grain);
262
+ grain *= u_grainMixer;
263
+ distortion = mix(distortion, 0., grain);
264
+ }
265
+
266
+ shadows = min(shadows, 1.);
267
+ shadows += maskStrokeInner;
268
+ shadows *= mask;
269
+ shadows = min(shadows, 1.);
270
+ shadows *= pow(u_shadows, 2.);
271
+ shadows = clamp(shadows, 0., 1.);
272
+
273
+ distortion *= 3. * u_distortion;
274
+ frameFade *= u_distortion;
275
+
276
+ fractOrigUV.x += distortion;
277
+ floorOrigUV = rotateAspect(floorOrigUV, -patternRotation, getImageAspectRatio());
278
+ fractOrigUV = rotateAspect(fractOrigUV, -patternRotation, getImageAspectRatio());
279
+
280
+ uv = (floorOrigUV + fractOrigUV) / patternSize;
281
+ uv += pow(maskStroke, 4.);
282
+
283
+ uv += patternOrigin;
284
+
285
+ uv = mix(v_imageUV, uv, smoothstep(0., .7, mask));
286
+ float blur = mix(0., 50., u_blur);
287
+ blur = mix(0., blur, smoothstep(.5, 1., mask));
288
+
289
+ float edgeDistortion = mix(.0, .04, u_edges);
290
+ edgeDistortion += .06 * frameFade * u_edges;
291
+ edgeDistortion *= mask;
292
+ float frame = getUvFrame(uv, edgeDistortion);
293
+
294
+ float stretch = 1. - smoothstep(0., .5, xNonSmooth) * smoothstep(1., 1. - .5, xNonSmooth);
295
+ stretch = pow(stretch, 2.);
296
+ stretch *= mask;
297
+ stretch *= getUvFrame(uv, .1 + .05 * mask * frameFade);
298
+ uv.y = mix(uv.y, .5, u_stretch * stretch);
299
+
300
+ vec4 image = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);
301
+ vec4 backColor = u_colorBack;
302
+ backColor.rgb *= backColor.a;
303
+ vec4 highlightColor = u_colorHighlight;
304
+ highlightColor.rgb *= highlightColor.a;
305
+ vec4 shadowColor = u_colorShadow;
306
+
307
+ vec3 color = highlightColor.rgb * highlights;
308
+ float opacity = highlightColor.a * highlights;
309
+
310
+ shadows = mix(shadows * shadowColor.a, 0., highlights);
311
+ color = mix(color, shadowColor.rgb * shadowColor.a, .5 * shadows);
312
+ color += .5 * pow(shadows, .5) * shadowColor.rgb;
313
+ opacity += shadows;
314
+ color = clamp(color, vec3(0.), vec3(1.));
315
+ opacity = clamp(opacity, 0., 1.);
316
+
317
+ color += image.rgb * (1. - opacity) * frame;
318
+ opacity += image.a * (1. - opacity) * frame;
319
+
320
+ color += backColor.rgb * (1. - opacity);
321
+ opacity += backColor.a * (1. - opacity);
322
+
323
+ if (u_grainOverlay > 0.) {
324
+ float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));
325
+ grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);
326
+ grainOverlay = pow(grainOverlay, 1.3);
327
+
328
+ float grainOverlayV = grainOverlay * 2. - 1.;
329
+ vec3 grainOverlayColor = vec3(step(0., grainOverlayV));
330
+ float grainOverlayStrength = u_grainOverlay * abs(grainOverlayV);
331
+ grainOverlayStrength = pow(grainOverlayStrength, .8);
332
+ grainOverlayStrength *= mask;
333
+ color = mix(color, grainOverlayColor, .35 * grainOverlayStrength);
334
+
335
+ opacity += .5 * grainOverlayStrength;
336
+ }
337
+ opacity = clamp(opacity, 0., 1.);
338
+
339
+ fragColor = vec4(color, opacity);
340
+ }
341
+ `;
342
+ const GlassGridShapes = {
343
+ lines: 1,
344
+ linesIrregular: 2,
345
+ wave: 3,
346
+ zigzag: 4,
347
+ pattern: 5
348
+ };
349
+ const GlassDistortionShapes = {
350
+ prism: 1,
351
+ lens: 2,
352
+ contour: 3,
353
+ cascade: 4,
354
+ flat: 5
355
+ };
356
+ export {
357
+ GlassDistortionShapes,
358
+ GlassGridShapes,
359
+ flutedGlassFragmentShader
360
+ };
361
+ //# sourceMappingURL=fluted-glass.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shaders/fluted-glass.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 * Fluted glass image filter that transforms an image into streaked, ribbed distortions,\n * giving a mix of clarity and obscurity.\n *\n * Fragment shader uniforms:\n * - u_resolution (vec2): Canvas resolution in pixels\n * - u_pixelRatio (float): Device pixel ratio\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 flutes are sized in CSS px to keep their size\n * over it, size setting the flute width from 5px to 200px, and anchored at originX / originY instead of the center,\n * 0 0 being the top left like CSS. Their distortion follows the flute size; margins and edges stay relative to the frame\n * - u_colorBack (vec4): Background color in RGBA\n * - u_colorShadow (vec4): Shadows color in RGBA, needs shadows > 0\n * - u_colorHighlight (vec4): Highlights color in RGBA, needs highlights > 0\n * - u_shadows (float): Color gradient added over image and background, following distortion shape, needs colorShadow alpha > 0 (0 to 1)\n * - u_highlights (float): Thin strokes along distortion shape, useful for antialiasing on small grid (0 to 1)\n * - u_size (float): Size of the distortion shape grid (0 to 1)\n * - u_shape (float): Grid shape (1 = lines, 2 = linesIrregular, 3 = wave, 4 = zigzag, 5 = pattern)\n * - u_angle (float): Direction of the grid relative to the image in degrees (0 to 180)\n * - u_distortionShape (float): Shape of distortion (1 = prism, 2 = lens, 3 = contour, 4 = cascade, 5 = flat)\n * - u_distortion (float): Power of distortion applied within each stripe (0 to 1)\n * - u_shift (float): Texture shift in direction opposite to the grid, needs distortion > 0 (-1 to 1)\n * - u_stretch (float): Extra distortion along the grid lines (0 to 1)\n * - u_blur (float): One-directional blur over the image and extra blur around edges (0 to 1)\n * - u_edges (float): Glass distortion and softness on the image edges (0 to 1)\n * - u_marginLeft (float): Distance from the left edge to the effect (0 to 1)\n * - u_marginRight (float): Distance from the right edge to the effect (0 to 1)\n * - u_marginTop (float): Distance from the top edge to the effect (0 to 1)\n * - u_marginBottom (float): Distance from the bottom edge to the effect (0 to 1)\n * - u_grainMixer (float): Strength of grain distortion applied to shape edges, needs distortion > 0 (0 to 1)\n * - u_grainOverlay (float): Post-processing black/white grain overlay (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 effect is anchored (0 to 1)\n * - u_originY (float): Reference point for positioning world height in the canvas, over HTML where the effect 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 flutedGlassFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorShadow;\nuniform vec4 u_colorHighlight;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\nuniform float u_imageIsHtml;\nuniform float u_originX;\nuniform float u_originY;\n\nuniform float u_size;\nuniform float u_shadows;\nuniform float u_angle;\nuniform float u_stretch;\nuniform float u_shape;\nuniform float u_distortion;\nuniform float u_highlights;\nuniform float u_distortionShape;\nuniform float u_shift;\nuniform float u_blur;\nuniform float u_edges;\nuniform float u_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\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\n${ declarePI }\nfloat sizeToPx(float size) {\n return 1000. / mix(200., 5., size);\n}\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 getUvFrame(vec2 uv, float softness) {\n float aax = 2. * fwidth(uv.x);\n float aay = 2. * fwidth(uv.y);\n float left = smoothstep(0., aax + softness, uv.x);\n float right = 1. - smoothstep(1. - softness - aax, 1., uv.x);\n float bottom = smoothstep(0., aay + softness, uv.y);\n float top = 1. - smoothstep(1. - softness - aay, 1., uv.y);\n return left * right * bottom * top;\n}\n\nconst int MAX_RADIUS = 50;\nvec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {\n if (sigma <= .5) return texture(tex, uv);\n int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));\n\n float twoSigma2 = 2.0 * sigma * sigma;\n float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);\n\n vec4 sum = texture(tex, uv) * gaussianNorm;\n float weightSum = gaussianNorm;\n\n for (int i = 1; i <= MAX_RADIUS; i++) {\n if (i > radius) break;\n\n float x = float(i);\n float w = exp(-(x * x) / twoSigma2) * gaussianNorm;\n\n vec2 offset = dir * texelSize * x;\n vec4 s1 = texture(tex, uv + offset);\n vec4 s2 = texture(tex, uv - offset);\n\n sum += (s1 + s2) * w;\n weightSum += 2.0 * w;\n }\n\n return sum / weightSum;\n}\n\nvec2 rotateAspect(vec2 p, float a, float aspect) {\n p.x *= aspect;\n p = rotate(p, a);\n p.x /= aspect;\n return p;\n}\n\nfloat smoothFract(float x) {\n float f = fract(x);\n float w = fwidth(x);\n\n float edge = abs(f - 0.5) - 0.5;\n float band = smoothstep(-w, w, edge);\n\n return mix(f, 1.0 - f, band);\n}\n\nvoid main() {\n\n float patternRotation = -u_angle * PI / 180.;\n float patternSize = mix(mix(200., 2., u_size), u_resolution.x / u_pixelRatio / sizeToPx(u_size), u_imageIsHtml);\n vec2 patternOrigin = mix(vec2(.5), vec2(u_originX, u_originY), u_imageIsHtml);\n\n vec2 uv = v_imageUV;\n\n vec2 uvMask = gl_FragCoord.xy / u_resolution.xy;\n vec2 sw = vec2(.005);\n vec4 margins = vec4(u_marginLeft, u_marginTop, u_marginRight, u_marginBottom);\n float mask =\n smoothstep(margins[0], margins[0] + sw.x, uvMask.x + sw.x) *\n smoothstep(margins[2], margins[2] + sw.x, 1.0 - uvMask.x + sw.x) *\n smoothstep(margins[1], margins[1] + sw.y, uvMask.y + sw.y) *\n smoothstep(margins[3], margins[3] + sw.y, 1.0 - uvMask.y + sw.y);\n float maskOuter =\n smoothstep(margins[0] - sw.x, margins[0], uvMask.x + sw.x) *\n smoothstep(margins[2] - sw.x, margins[2], 1.0 - uvMask.x + sw.x) *\n smoothstep(margins[1] - sw.y, margins[1], uvMask.y + sw.y) *\n smoothstep(margins[3] - sw.y, margins[3], 1.0 - uvMask.y + sw.y);\n float maskStroke = maskOuter - mask;\n float maskInner =\n smoothstep(margins[0] - 2. * sw.x, margins[0], uvMask.x) *\n smoothstep(margins[2] - 2. * sw.x, margins[2], 1.0 - uvMask.x) *\n smoothstep(margins[1] - 2. * sw.y, margins[1], uvMask.y) *\n smoothstep(margins[3] - 2. * sw.y, margins[3], 1.0 - uvMask.y);\n float maskStrokeInner = maskInner - mask;\n\n uv -= patternOrigin;\n uv *= patternSize;\n uv = rotateAspect(uv, patternRotation, getImageAspectRatio());\n\n float curve = 0.;\n float patternY = uv.y / getImageAspectRatio();\n if (u_shape > 4.5) {\n // pattern\n curve = .5 + .5 * sin(.5 * PI * uv.x) * cos(.5 * PI * patternY);\n } else if (u_shape > 3.5) {\n // zigzag\n curve = 10. * abs(fract(.1 * patternY) - .5);\n } else if (u_shape > 2.5) {\n // wave\n curve = 4. * sin(.23 * patternY);\n } else if (u_shape > 1.5) {\n // lines irregular\n curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);\n } else {\n // lines\n }\n\n vec2 UvToFract = uv + curve;\n vec2 fractOrigUV = fract(uv);\n vec2 floorOrigUV = floor(uv);\n\n float x = smoothFract(UvToFract.x);\n float xNonSmooth = fract(UvToFract.x) + .0001;\n\n float highlightsWidth = 2. * max(.001, fwidth(UvToFract.x));\n highlightsWidth += 2. * maskStrokeInner;\n float highlights = smoothstep(0., highlightsWidth, xNonSmooth);\n highlights *= smoothstep(1., 1. - highlightsWidth, xNonSmooth);\n highlights = 1. - highlights;\n highlights *= u_highlights;\n highlights = clamp(highlights, 0., 1.);\n highlights *= mask;\n\n float shadows = pow(x, 1.3);\n float distortion = 0.;\n float fadeX = 1.;\n float frameFade = 0.;\n\n float aa = fwidth(xNonSmooth);\n aa = max(aa, fwidth(uv.x));\n aa = max(aa, fwidth(UvToFract.x));\n aa = max(aa, .0001);\n\n if (u_distortionShape == 1.) {\n distortion = -pow(1.5 * x, 3.);\n distortion += (.5 - u_shift);\n\n frameFade = pow(1.5 * x, 3.);\n aa = max(.2, aa);\n aa += mix(.2, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion = mix(.5, distortion, fadeX);\n } else if (u_distortionShape == 2.) {\n distortion = 2. * pow(x, 2.);\n distortion -= (.5 + u_shift);\n\n frameFade = pow(abs(x - .5), 4.);\n aa = max(.2, aa);\n aa += mix(.2, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion = mix(.5, distortion, fadeX);\n frameFade = mix(1., frameFade, .5 * fadeX);\n } else if (u_distortionShape == 3.) {\n distortion = pow(2. * (xNonSmooth - .5), 6.);\n distortion -= .25;\n distortion -= u_shift;\n\n frameFade = 1. - 2. * pow(abs(x - .4), 2.);\n aa = .15;\n aa += mix(.1, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n frameFade = mix(1., frameFade, fadeX);\n\n } else if (u_distortionShape == 4.) {\n x = xNonSmooth;\n distortion = sin((x + .25) * TWO_PI);\n shadows = .5 + .5 * asin(distortion) / (.5 * PI);\n distortion *= .5;\n distortion -= u_shift;\n frameFade = .5 + .5 * sin(x * TWO_PI);\n } else if (u_distortionShape == 5.) {\n distortion -= pow(abs(x), .2) * x;\n distortion += .33;\n distortion -= 3. * u_shift;\n distortion *= .33;\n\n frameFade = .3 * (smoothstep(.0, 1., x));\n shadows = pow(x, 2.5);\n\n aa = max(.1, aa);\n aa += mix(.1, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion *= fadeX;\n }\n\n vec2 dudx = dFdx(v_imageUV);\n vec2 dudy = dFdy(v_imageUV);\n vec2 grainUV = v_imageUV - patternOrigin;\n grainUV *= (.8 / vec2(length(dudx), length(dudy)));\n grainUV += .5;\n if (u_grainMixer > 0.) {\n float grain = valueNoise(grainUV);\n grain = smoothstep(.4, .7, grain);\n grain *= u_grainMixer;\n distortion = mix(distortion, 0., grain);\n }\n\n shadows = min(shadows, 1.);\n shadows += maskStrokeInner;\n shadows *= mask;\n shadows = min(shadows, 1.);\n shadows *= pow(u_shadows, 2.);\n shadows = clamp(shadows, 0., 1.);\n\n distortion *= 3. * u_distortion;\n frameFade *= u_distortion;\n\n fractOrigUV.x += distortion;\n floorOrigUV = rotateAspect(floorOrigUV, -patternRotation, getImageAspectRatio());\n fractOrigUV = rotateAspect(fractOrigUV, -patternRotation, getImageAspectRatio());\n\n uv = (floorOrigUV + fractOrigUV) / patternSize;\n uv += pow(maskStroke, 4.);\n\n uv += patternOrigin;\n\n uv = mix(v_imageUV, uv, smoothstep(0., .7, mask));\n float blur = mix(0., 50., u_blur);\n blur = mix(0., blur, smoothstep(.5, 1., mask));\n\n float edgeDistortion = mix(.0, .04, u_edges);\n edgeDistortion += .06 * frameFade * u_edges;\n edgeDistortion *= mask;\n float frame = getUvFrame(uv, edgeDistortion);\n\n float stretch = 1. - smoothstep(0., .5, xNonSmooth) * smoothstep(1., 1. - .5, xNonSmooth);\n stretch = pow(stretch, 2.);\n stretch *= mask;\n stretch *= getUvFrame(uv, .1 + .05 * mask * frameFade);\n uv.y = mix(uv.y, .5, u_stretch * stretch);\n\n vec4 image = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);\n vec4 backColor = u_colorBack;\n backColor.rgb *= backColor.a;\n vec4 highlightColor = u_colorHighlight;\n highlightColor.rgb *= highlightColor.a;\n vec4 shadowColor = u_colorShadow;\n\n vec3 color = highlightColor.rgb * highlights;\n float opacity = highlightColor.a * highlights;\n\n shadows = mix(shadows * shadowColor.a, 0., highlights);\n color = mix(color, shadowColor.rgb * shadowColor.a, .5 * shadows);\n color += .5 * pow(shadows, .5) * shadowColor.rgb;\n opacity += shadows;\n color = clamp(color, vec3(0.), vec3(1.));\n opacity = clamp(opacity, 0., 1.);\n\n color += image.rgb * (1. - opacity) * frame;\n opacity += image.a * (1. - opacity) * frame;\n\n color += backColor.rgb * (1. - opacity);\n opacity += backColor.a * (1. - opacity);\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 grainOverlayStrength *= mask;\n color = mix(color, grainOverlayColor, .35 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n }\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface FlutedGlassUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_colorBack: [number, number, number, number];\n u_colorShadow: [number, number, number, number];\n u_colorHighlight: [number, number, number, number];\n u_shadows: number;\n u_size: number;\n u_angle: number;\n u_distortion: number;\n u_shift: number;\n u_blur: number;\n u_edges: number;\n u_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_stretch: number;\n u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];\n u_highlights: number;\n u_shape: (typeof GlassGridShapes)[GlassGridShape];\n u_grainMixer: number;\n u_grainOverlay: number;\n}\n\nexport interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string;\n colorBack?: string;\n colorShadow?: string;\n colorHighlight?: string;\n shadows?: number;\n size?: number;\n angle?: number;\n distortion?: number;\n shift?: number;\n blur?: number;\n edges?: number;\n margin?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n stretch?: number;\n distortionShape?: GlassDistortionShape;\n highlights?: number;\n shape?: GlassGridShape;\n grainMixer?: number;\n grainOverlay?: number;\n}\n\nexport const GlassGridShapes = {\n lines: 1,\n linesIrregular: 2,\n wave: 3,\n zigzag: 4,\n pattern: 5,\n} as const;\n\nexport const GlassDistortionShapes = {\n prism: 1,\n lens: 2,\n contour: 3,\n cascade: 4,\n flat: 5,\n} as const;\n\nexport type GlassDistortionShape = keyof typeof GlassDistortionShapes;\nexport type GlassGridShape = keyof typeof GlassGridShapes;\n"],
5
+ "mappings": ";;;;;AACA,eAAmE;AACnE,SAAS,WAAW,WAAW,wBAAwB;AAqDhD,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0C9C,SAAU;AAAA;AAAA;AAAA;AAAA,EAIV,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiVb,MAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,MAAM,wBAAwB;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;",
6
+ "names": []
7
+ }