@paper-design/shaders 0.0.67 → 0.0.68

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 (79) hide show
  1. package/dist/index.d.ts +27 -18
  2. package/dist/index.js.map +2 -2
  3. package/dist/shader-sizing.d.ts +0 -2
  4. package/dist/shader-sizing.js +0 -165
  5. package/dist/shader-sizing.js.map +2 -2
  6. package/dist/shaders/color-panels.d.ts +32 -12
  7. package/dist/shaders/color-panels.js +3 -3
  8. package/dist/shaders/color-panels.js.map +2 -2
  9. package/dist/shaders/dithering.d.ts +14 -19
  10. package/dist/shaders/dithering.js +105 -64
  11. package/dist/shaders/dithering.js.map +2 -2
  12. package/dist/shaders/dot-grid.d.ts +28 -14
  13. package/dist/shaders/dot-grid.js.map +2 -2
  14. package/dist/shaders/dot-orbit.d.ts +27 -9
  15. package/dist/shaders/dot-orbit.js +6 -6
  16. package/dist/shaders/dot-orbit.js.map +2 -2
  17. package/dist/shaders/fluted-glass.d.ts +36 -18
  18. package/dist/shaders/fluted-glass.js +9 -9
  19. package/dist/shaders/fluted-glass.js.map +2 -2
  20. package/dist/shaders/god-rays.d.ts +32 -10
  21. package/dist/shaders/god-rays.js.map +2 -2
  22. package/dist/shaders/grain-gradient.d.ts +41 -17
  23. package/dist/shaders/grain-gradient.js +44 -21
  24. package/dist/shaders/grain-gradient.js.map +2 -2
  25. package/dist/shaders/halftone-dots.d.ts +30 -6
  26. package/dist/shaders/halftone-dots.js +11 -11
  27. package/dist/shaders/halftone-dots.js.map +2 -2
  28. package/dist/shaders/heatmap.d.ts +36 -0
  29. package/dist/shaders/heatmap.js +98 -16
  30. package/dist/shaders/heatmap.js.map +2 -2
  31. package/dist/shaders/image-dithering.d.ts +24 -15
  32. package/dist/shaders/image-dithering.js +68 -37
  33. package/dist/shaders/image-dithering.js.map +2 -2
  34. package/dist/shaders/liquid-metal.d.ts +38 -14
  35. package/dist/shaders/liquid-metal.js.map +2 -2
  36. package/dist/shaders/mesh-gradient.d.ts +27 -8
  37. package/dist/shaders/mesh-gradient.js.map +2 -2
  38. package/dist/shaders/metaballs.d.ts +24 -8
  39. package/dist/shaders/metaballs.js.map +2 -2
  40. package/dist/shaders/neuro-noise.d.ts +27 -5
  41. package/dist/shaders/neuro-noise.js.map +2 -2
  42. package/dist/shaders/paper-texture.d.ts +37 -12
  43. package/dist/shaders/paper-texture.js +18 -18
  44. package/dist/shaders/paper-texture.js.map +2 -2
  45. package/dist/shaders/perlin-noise.d.ts +27 -8
  46. package/dist/shaders/perlin-noise.js +5 -5
  47. package/dist/shaders/perlin-noise.js.map +2 -2
  48. package/dist/shaders/pulsing-border.d.ts +39 -13
  49. package/dist/shaders/pulsing-border.js +5 -5
  50. package/dist/shaders/pulsing-border.js.map +2 -2
  51. package/dist/shaders/simplex-noise.d.ts +25 -6
  52. package/dist/shaders/simplex-noise.js +19 -19
  53. package/dist/shaders/simplex-noise.js.map +2 -2
  54. package/dist/shaders/smoke-ring.d.ts +29 -7
  55. package/dist/shaders/smoke-ring.js.map +2 -2
  56. package/dist/shaders/spiral.d.ts +30 -10
  57. package/dist/shaders/spiral.js +2 -2
  58. package/dist/shaders/spiral.js.map +2 -2
  59. package/dist/shaders/static-mesh-gradient.d.ts +30 -9
  60. package/dist/shaders/static-mesh-gradient.js +3 -3
  61. package/dist/shaders/static-mesh-gradient.js.map +2 -2
  62. package/dist/shaders/static-radial-gradient.d.ts +33 -11
  63. package/dist/shaders/static-radial-gradient.js +8 -8
  64. package/dist/shaders/static-radial-gradient.js.map +2 -2
  65. package/dist/shaders/swirl.d.ts +29 -8
  66. package/dist/shaders/swirl.js +2 -2
  67. package/dist/shaders/swirl.js.map +2 -2
  68. package/dist/shaders/voronoi.d.ts +31 -10
  69. package/dist/shaders/voronoi.js +6 -6
  70. package/dist/shaders/voronoi.js.map +2 -2
  71. package/dist/shaders/warp.d.ts +31 -13
  72. package/dist/shaders/warp.js +1 -1
  73. package/dist/shaders/warp.js.map +2 -2
  74. package/dist/shaders/water.d.ts +30 -10
  75. package/dist/shaders/water.js.map +2 -2
  76. package/dist/shaders/waves.d.ts +27 -12
  77. package/dist/shaders/waves.js +1 -1
  78. package/dist/shaders/waves.js.map +2 -2
  79. package/package.json +1 -1
@@ -30,7 +30,7 @@ ${simplexNoise}
30
30
 
31
31
  void main() {
32
32
  vec2 uv = 2. * v_patternUV;
33
-
33
+
34
34
  float t = u_time;
35
35
  float l = length(uv);
36
36
  float density = clamp(u_density, 0., 1.);
@@ -43,7 +43,7 @@ void main() {
43
43
  float offset = l + angleNormalised;
44
44
  offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));
45
45
  float stripe = fract(offset);
46
-
46
+
47
47
  float shape = 2. * abs(stripe - .5);
48
48
  float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);
49
49
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/spiral.ts"],
4
- "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { simplexNoise, declarePI, colorBandingFix } from '../shader-utils.js';\n\n/**\n * 2-color spiral shape\n *\n * Uniforms:\n * - u_colorBack, u_colorFront (RGBA)\n * - u_density: spacing falloff to simulate radial perspective (0 = no perspective)\n * - u_strokeWidth: thickness of stroke\n * - u_strokeTaper: stroke loosing width further from center (0 for full visibility)\n * - u_distortion: per-arch shift\n * - u_strokeCap: extra width at the center (no effect on u_strokeWidth = 0.5)\n * - u_noiseFrequency, u_noise: simplex noise distortion over the shape\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n *\n */\n\n// language=GLSL\nexport const spiralFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFront;\nuniform float u_density;\nuniform float u_distortion;\nuniform float u_strokeWidth;\nuniform float u_strokeCap;\nuniform float u_strokeTaper;\nuniform float u_noise;\nuniform float u_noiseFrequency;\nuniform float u_softness;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${simplexNoise}\n\nvoid main() {\n vec2 uv = 2. * v_patternUV;\n \n float t = u_time;\n float l = length(uv);\n float density = clamp(u_density, 0., 1.);\n l = pow(max(l, 1e-6), density);\n float angle = atan(uv.y, uv.x) - t;\n float angleNormalised = angle / TWO_PI;\n\n angleNormalised += .125 * u_noise * snoise(16. * pow(u_noiseFrequency, 3.) * uv);\n\n float offset = l + angleNormalised;\n offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));\n float stripe = fract(offset);\n \n float shape = 2. * abs(stripe - .5);\n float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);\n\n\n float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.)));\n width = mix(width, wCap, u_strokeCap);\n width *= (1. - clamp(u_strokeTaper, 0., 1.) * l);\n\n float fw = fwidth(offset);\n float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth)));\n float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.));\n pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.)));\n\n float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape);\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 SpiralUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFront: [number, number, number, number];\n u_density: number;\n u_distortion: number;\n u_strokeWidth: number;\n u_strokeTaper: number;\n u_strokeCap: number;\n u_noise: number;\n u_noiseFrequency: number;\n u_softness: number;\n}\n\nexport interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorFront?: string;\n density?: number;\n distortion?: number;\n strokeWidth?: number;\n strokeTaper?: number;\n strokeCap?: number;\n noise?: number;\n noiseFrequency?: number;\n softness?: number;\n}\n"],
5
- "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,cAAc,WAAW,uBAAuB;AAkBlD,MAAM,uBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB1C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA4CV,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 { simplexNoise, declarePI, colorBandingFix } from '../shader-utils.js';\n\n/**\n * A single-colored animated spiral that morphs across a wide range of shapes -\n * from crisp, thin-lined geometry to flowing whirlpool forms and wavy, abstract rings.\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 * 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 * Fragment shader uniforms:\n * - u_time (float): Animation time\n * - u_colorBack (vec4): Background color in RGBA\n * - u_colorFront (vec4): Foreground (ink) color in RGBA\n * - u_density (float): Spacing falloff simulating perspective, 0 = flat spiral (0 to 1)\n * - u_distortion (float): Power of shape distortion applied along the spiral (0 to 1)\n * - u_strokeWidth (float): Thickness of spiral curve (0 to 1)\n * - u_strokeTaper (float): How much stroke loses width away from center, 0 = full visibility (0 to 1)\n * - u_strokeCap (float): Extra stroke width at the center, no effect with strokeWidth = 0.5 (0 to 1)\n * - u_noise (float): Noise distortion applied over the canvas, no effect with noiseFrequency = 0 (0 to 1)\n * - u_noiseFrequency (float): Noise frequency, no effect with noise = 0 (0 to 1)\n * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)\n *\n */\n\n// language=GLSL\nexport const spiralFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFront;\nuniform float u_density;\nuniform float u_distortion;\nuniform float u_strokeWidth;\nuniform float u_strokeCap;\nuniform float u_strokeTaper;\nuniform float u_noise;\nuniform float u_noiseFrequency;\nuniform float u_softness;\n\n${ sizingVariablesDeclaration }\n\nout vec4 fragColor;\n\n${ declarePI }\n${ simplexNoise }\n\nvoid main() {\n vec2 uv = 2. * v_patternUV;\n\n float t = u_time;\n float l = length(uv);\n float density = clamp(u_density, 0., 1.);\n l = pow(max(l, 1e-6), density);\n float angle = atan(uv.y, uv.x) - t;\n float angleNormalised = angle / TWO_PI;\n\n angleNormalised += .125 * u_noise * snoise(16. * pow(u_noiseFrequency, 3.) * uv);\n\n float offset = l + angleNormalised;\n offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));\n float stripe = fract(offset);\n\n float shape = 2. * abs(stripe - .5);\n float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);\n\n\n float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.)));\n width = mix(width, wCap, u_strokeCap);\n width *= (1. - clamp(u_strokeTaper, 0., 1.) * l);\n\n float fw = fwidth(offset);\n float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth)));\n float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.));\n pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.)));\n\n float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape);\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 SpiralUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFront: [number, number, number, number];\n u_density: number;\n u_distortion: number;\n u_strokeWidth: number;\n u_strokeTaper: number;\n u_strokeCap: number;\n u_noise: number;\n u_noiseFrequency: number;\n u_softness: number;\n}\n\nexport interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorFront?: string;\n density?: number;\n distortion?: number;\n strokeWidth?: number;\n strokeTaper?: number;\n strokeCap?: number;\n noise?: number;\n noiseFrequency?: number;\n softness?: number;\n}\n"],
5
+ "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,cAAc,WAAW,uBAAuB;AAsClD,MAAM,uBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBzC,0BAA2B;AAAA;AAAA;AAAA;AAAA,EAI3B,SAAU;AAAA,EACV,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA4CX,eAAgB;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,16 +5,37 @@ export declare const staticMeshGradientMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
7
7
  /**
8
- * A composition of N color spots (one per color)
8
+ * Multi-point mesh gradient with up to 10 color spots, enhanced by two-direction warping,
9
+ * adjustable blend sharpness, and grain controls.
10
+ *
11
+ * Fragment shader uniforms:
12
+ * - u_colors (vec4[]): Up to 10 gradient colors in RGBA
13
+ * - u_colorsCount (float): Number of active colors
14
+ * - u_positions (float): Color spots placement seed (0 to 100)
15
+ * - u_waveX (float): Strength of sine wave distortion along X axis (0 to 1)
16
+ * - u_waveXShift (float): Phase offset applied to the X-axis wave (0 to 1)
17
+ * - u_waveY (float): Strength of sine wave distortion along Y axis (0 to 1)
18
+ * - u_waveYShift (float): Phase offset applied to the Y-axis wave (0 to 1)
19
+ * - u_mixing (float): Blending behavior, 0 = stepped, 0.5 = smooth, 1 = pronounced color points (0 to 1)
20
+ * - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)
21
+ * - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)
22
+ *
23
+ * Vertex shader outputs (used in fragment shader):
24
+ * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
25
+ *
26
+ * Vertex shader uniforms:
27
+ * - u_resolution (vec2): Canvas resolution in pixels
28
+ * - u_pixelRatio (float): Device pixel ratio
29
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
30
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
31
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
32
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
33
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
34
+ * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
35
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
36
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
37
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
9
38
  *
10
- * Uniforms:
11
- * - u_colorBack (RGBA)
12
- * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
- * - u_waveX, u_waveY - power of sine wave distortion along X and Y axes
14
- * - u_waveXShift, u_waveYShift - each wave phase offset
15
- * - u_mixing (0 .. 1, float) - 0 for stepped gradient, 0.5 for smooth transitions, 1 for pronounced color points
16
- * - u_grainMixer - shape distortion
17
- * - u_grainOverlay - post-processing blending
18
39
  */
19
40
  export declare const staticMeshGradientFragmentShader: string;
20
41
  export interface StaticMeshGradientUniforms extends ShaderSizingUniforms {
@@ -79,7 +79,7 @@ void main() {
79
79
  uv.x += u_waveX * center / i * cos(TWO_PI * u_waveXShift + i * 2. * smoothstep(.0, 1., uv.y));
80
80
  uv.y += u_waveY * center / i * cos(TWO_PI * u_waveYShift + i * 2. * smoothstep(.0, 1., uv.x));
81
81
  }
82
-
82
+
83
83
  vec3 color = vec3(0.);
84
84
  float opacity = 0.;
85
85
  float totalWeight = 0.;
@@ -112,7 +112,7 @@ void main() {
112
112
 
113
113
  color /= max(1e-4, totalWeight);
114
114
  opacity /= max(1e-4, totalWeight);
115
-
115
+
116
116
  float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));
117
117
  grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);
118
118
  grainOverlay = pow(grainOverlay, 1.3);
@@ -125,7 +125,7 @@ void main() {
125
125
 
126
126
  opacity += .5 * grainOverlayStrength;
127
127
  opacity = clamp(opacity, 0., 1.);
128
-
128
+
129
129
  fragColor = vec4(color, opacity);
130
130
  }
131
131
  `;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/static-mesh-gradient.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingDebugVariablesDeclaration,\n sizingVariablesDeclaration,\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n} from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\nexport const staticMeshGradientMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * A composition of N color spots (one per color)\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_waveX, u_waveY - power of sine wave distortion along X and Y axes\n * - u_waveXShift, u_waveYShift - each wave phase offset\n * - u_mixing (0 .. 1, float) - 0 for stepped gradient, 0.5 for smooth transitions, 1 for pronounced color points\n * - u_grainMixer - shape distortion\n * - u_grainOverlay - post-processing blending\n */\n\n// language=GLSL\nexport const staticMeshGradientFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colors[${staticMeshGradientMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_positions;\nuniform float u_waveX;\nuniform float u_waveXShift;\nuniform float u_waveY;\nuniform float u_waveYShift;\nuniform float u_mixing;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\n\n${sizingVariablesDeclaration}\n${sizingDebugVariablesDeclaration}\n${sizingUniformsDeclaration}\n\nout vec4 fragColor;\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 noise(vec2 n, vec2 seedOffset) {\n return valueNoise(n + seedOffset);\n}\n\nvec2 getPosition(int i, float t) {\n float a = float(i) * .37;\n float b = .6 + mod(float(i), 3.) * .3;\n float c = .8 + mod(float(i + 1), 4.) * 0.25;\n\n float x = sin(t * b + a);\n float y = cos(t * c + a * 1.5);\n\n return .5 + .5 * vec2(x, y);\n}\n\nvoid main() {\n vec2 uv = v_objectUV;\n uv += .5;\n vec2 grainUV = uv * 1000.;\n\n float grain = noise(grainUV, vec2(0.));\n float mixerGrain = .4 * u_grainMixer * (grain - .5);\n\n float radius = smoothstep(0., 1., length(uv - .5));\n float center = 1. - radius;\n for (float i = 1.; i <= 2.; i++) {\n uv.x += u_waveX * center / i * cos(TWO_PI * u_waveXShift + i * 2. * smoothstep(.0, 1., uv.y));\n uv.y += u_waveY * center / i * cos(TWO_PI * u_waveYShift + i * 2. * smoothstep(.0, 1., uv.x));\n }\n \n vec3 color = vec3(0.);\n float opacity = 0.;\n float totalWeight = 0.;\n float positionSeed = 25. + .33 * u_positions;\n\n for (int i = 0; i < ${staticMeshGradientMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 pos = getPosition(i, positionSeed) + mixerGrain;\n float dist = length(uv - pos);\n dist = length(uv - pos);\n\n vec3 colorFraction = u_colors[i].rgb * u_colors[i].a;\n float opacityFraction = u_colors[i].a;\n\n float power = 4.;\n if (u_mixing > .5) {\n power = mix(power, .75, 2. * (u_mixing - .5));\n }\n dist = pow(dist, power);\n\n float w = 1. / (dist + 1e-3);\n if (u_mixing < .5) {\n w = pow(w, mix(mix(.01, 5., clamp(w, 0., 1.)), 1., 2. * u_mixing));\n }\n color += colorFraction * w;\n opacity += opacityFraction * w;\n totalWeight += w;\n }\n\n color /= max(1e-4, totalWeight);\n opacity /= max(1e-4, totalWeight);\n \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, .35 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n opacity = clamp(opacity, 0., 1.);\n \n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface StaticMeshGradientUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_positions: number;\n u_waveX: number;\n u_waveXShift: number;\n u_waveY: number;\n u_waveYShift: number;\n u_mixing: number;\n u_grainMixer: number;\n u_grainOverlay: number;\n}\n\nexport interface StaticMeshGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n positions?: number;\n waveX?: number;\n waveXShift?: number;\n waveY?: number;\n waveYShift?: number;\n mixing?: number;\n grainMixer?: number;\n grainOverlay?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,WAAW,WAAW,wBAAwB;AAEhD,MAAM,yBAAyB;AAAA,EACpC,eAAe;AACjB;AAgBO,MAAM,mCAA2C;AAAA;AAAA;AAAA,wBAGhC,uBAAuB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY1D,0BAA0B;AAAA,EAC1B,+BAA+B;AAAA,EAC/B,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAIzB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAkDM,uBAAuB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingDebugVariablesDeclaration,\n sizingVariablesDeclaration,\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n} from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\nexport const staticMeshGradientMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Multi-point mesh gradient with up to 10 color spots, enhanced by two-direction warping,\n * adjustable blend sharpness, and grain controls.\n *\n * Fragment shader uniforms:\n * - u_colors (vec4[]): Up to 10 gradient colors in RGBA\n * - u_colorsCount (float): Number of active colors\n * - u_positions (float): Color spots placement seed (0 to 100)\n * - u_waveX (float): Strength of sine wave distortion along X axis (0 to 1)\n * - u_waveXShift (float): Phase offset applied to the X-axis wave (0 to 1)\n * - u_waveY (float): Strength of sine wave distortion along Y axis (0 to 1)\n * - u_waveYShift (float): Phase offset applied to the Y-axis wave (0 to 1)\n * - u_mixing (float): Blending behavior, 0 = stepped, 0.5 = smooth, 1 = pronounced color points (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 *\n * Vertex shader outputs (used in fragment shader):\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, 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 (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 staticMeshGradientFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colors[${ staticMeshGradientMeta.maxColorCount }];\nuniform float u_colorsCount;\n\nuniform float u_positions;\nuniform float u_waveX;\nuniform float u_waveXShift;\nuniform float u_waveY;\nuniform float u_waveYShift;\nuniform float u_mixing;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\n\n${ sizingVariablesDeclaration }\n${ sizingDebugVariablesDeclaration }\n${ sizingUniformsDeclaration }\n\nout vec4 fragColor;\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 noise(vec2 n, vec2 seedOffset) {\n return valueNoise(n + seedOffset);\n}\n\nvec2 getPosition(int i, float t) {\n float a = float(i) * .37;\n float b = .6 + mod(float(i), 3.) * .3;\n float c = .8 + mod(float(i + 1), 4.) * 0.25;\n\n float x = sin(t * b + a);\n float y = cos(t * c + a * 1.5);\n\n return .5 + .5 * vec2(x, y);\n}\n\nvoid main() {\n vec2 uv = v_objectUV;\n uv += .5;\n vec2 grainUV = uv * 1000.;\n\n float grain = noise(grainUV, vec2(0.));\n float mixerGrain = .4 * u_grainMixer * (grain - .5);\n\n float radius = smoothstep(0., 1., length(uv - .5));\n float center = 1. - radius;\n for (float i = 1.; i <= 2.; i++) {\n uv.x += u_waveX * center / i * cos(TWO_PI * u_waveXShift + i * 2. * smoothstep(.0, 1., uv.y));\n uv.y += u_waveY * center / i * cos(TWO_PI * u_waveYShift + i * 2. * smoothstep(.0, 1., uv.x));\n }\n\n vec3 color = vec3(0.);\n float opacity = 0.;\n float totalWeight = 0.;\n float positionSeed = 25. + .33 * u_positions;\n\n for (int i = 0; i < ${ staticMeshGradientMeta.maxColorCount }; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 pos = getPosition(i, positionSeed) + mixerGrain;\n float dist = length(uv - pos);\n dist = length(uv - pos);\n\n vec3 colorFraction = u_colors[i].rgb * u_colors[i].a;\n float opacityFraction = u_colors[i].a;\n\n float power = 4.;\n if (u_mixing > .5) {\n power = mix(power, .75, 2. * (u_mixing - .5));\n }\n dist = pow(dist, power);\n\n float w = 1. / (dist + 1e-3);\n if (u_mixing < .5) {\n w = pow(w, mix(mix(.01, 5., clamp(w, 0., 1.)), 1., 2. * u_mixing));\n }\n color += colorFraction * w;\n opacity += opacityFraction * w;\n totalWeight += w;\n }\n\n color /= max(1e-4, totalWeight);\n opacity /= max(1e-4, totalWeight);\n\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, .35 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface StaticMeshGradientUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_positions: number;\n u_waveX: number;\n u_waveXShift: number;\n u_waveY: number;\n u_waveYShift: number;\n u_mixing: number;\n u_grainMixer: number;\n u_grainOverlay: number;\n}\n\nexport interface StaticMeshGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n positions?: number;\n waveX?: number;\n waveXShift?: number;\n waveY?: number;\n waveYShift?: number;\n mixing?: number;\n grainMixer?: number;\n grainOverlay?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,WAAW,WAAW,wBAAwB;AAEhD,MAAM,yBAAyB;AAAA,EACpC,eAAe;AACjB;AAqCO,MAAM,mCAA2C;AAAA;AAAA;AAAA,wBAG/B,uBAAuB,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY3D,0BAA2B;AAAA,EAC3B,+BAAgC;AAAA,EAChC,yBAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,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,wBAkDK,uBAAuB,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,18 +5,40 @@ export declare const staticRadialGradientMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
7
7
  /**
8
- * N-colors radial gradient
8
+ * Radial gradient with up to 10 blended colors, featuring advanced mixing modes, focal point controls,
9
+ * shape distortion, and grain effects.
10
+ *
11
+ * Fragment shader uniforms:
12
+ * - u_colorBack (vec4): Background color in RGBA
13
+ * - u_colors (vec4[]): Up to 10 gradient colors in RGBA
14
+ * - u_colorsCount (float): Number of active colors
15
+ * - u_radius (float): Size of the shape (0 to 3)
16
+ * - u_focalDistance (float): Distance of the focal point from center (0 to 3)
17
+ * - u_focalAngle (float): Angle of the focal point in degrees, effective with focalDistance > 0 (0 to 360)
18
+ * - u_falloff (float): Gradient decay, 0 = linear gradient (-1 to 1)
19
+ * - u_mixing (float): Blending behavior, 0 = stepped, 0.5 = smooth, 1 = pronounced color points (0 to 1)
20
+ * - u_distortion (float): Strength of radial distortion (0 to 1)
21
+ * - u_distortionShift (float): Radial distortion offset, effective with distortion > 0 (-1 to 1)
22
+ * - u_distortionFreq (float): Radial distortion frequency, effective with distortion > 0 (0 to 20)
23
+ * - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)
24
+ * - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)
25
+ *
26
+ * Vertex shader outputs (used in fragment shader):
27
+ * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
28
+ *
29
+ * Vertex shader uniforms:
30
+ * - u_resolution (vec2): Canvas resolution in pixels
31
+ * - u_pixelRatio (float): Device pixel ratio
32
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
33
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
34
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
35
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
36
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
37
+ * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
38
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
39
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
40
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
9
41
  *
10
- * Uniforms:
11
- * - u_colorBack (RGBA)
12
- * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
- * - u_radius - circle radius
14
- * - u_focalDistance, u_focalAngle (float) - gradient center offset to the circle center
15
- * - u_falloff (-1 .. 1, float) - color points distribution (0 for linear gradient)
16
- * - u_mixing (0 .. 1, float) - 0 for stepped gradient, 0.5 for smooth transitions, 1 for pronounced color points
17
- * - u_distortion, u_distortionShift, u_distortionFreq - radial distortion (effective with u_distortion > 0)
18
- * - u_grainMixer - shape distortion
19
- * - u_grainOverlay - post-processing blending
20
42
  */
21
43
  export declare const staticRadialGradientFragmentShader: string;
22
44
  export interface StaticRadialGradientUniforms extends ShaderSizingUniforms {
@@ -76,12 +76,12 @@ void main() {
76
76
  float angleRad = -radians(u_focalAngle + 90.);
77
77
  vec2 focalPoint = vec2(cos(angleRad), sin(angleRad)) * u_focalDistance;
78
78
  float radius = u_radius;
79
-
79
+
80
80
  vec2 c_to_uv = uv - center;
81
81
  vec2 f_to_uv = uv - focalPoint;
82
82
  vec2 f_to_c = center - focalPoint;
83
83
  float r = length(c_to_uv);
84
-
84
+
85
85
  float fragAngle = atan(c_to_uv.y, c_to_uv.x);
86
86
  float angleDiff = fract((fragAngle - angleRad + PI) / TWO_PI) * TWO_PI - PI;
87
87
 
@@ -90,7 +90,7 @@ void main() {
90
90
  float lo = min(e0, e1), hi = max(e0, e1);
91
91
  float s = smoothstep(lo, hi, abs(angleDiff));
92
92
  float isInSector = (e1 >= e0) ? (1.0 - s) : s;
93
-
93
+
94
94
  float a = dot(f_to_uv, f_to_uv);
95
95
  float b = -2.0 * dot(f_to_uv, f_to_c);
96
96
  float c = dot(f_to_c, f_to_c) - radius * radius;
@@ -112,7 +112,7 @@ void main() {
112
112
  float shape = clamp(normalized, 0.0, 1.0);
113
113
 
114
114
  float falloffMapped = mix(.2 + .8 * max(0., u_falloff + 1.), mix(1., 15., u_falloff * u_falloff), step(.0, u_falloff));
115
-
115
+
116
116
  float falloffExp = mix(falloffMapped, 1., shape);
117
117
  shape = pow(shape, falloffExp);
118
118
  shape = 1. - clamp(shape, 0., 1.);
@@ -121,7 +121,7 @@ void main() {
121
121
  float outerMask = .002;
122
122
  float outer = 1.0 - smoothstep(radius - outerMask, radius + outerMask, r);
123
123
  outer = mix(outer, 1., isInSector);
124
-
124
+
125
125
  shape = mix(0., shape, outer);
126
126
  shape *= 1. - smoothstep(radius - .01, radius, r);
127
127
 
@@ -134,12 +134,12 @@ void main() {
134
134
  float mixer = shape * u_colorsCount + mixerGrain;
135
135
  vec4 gradient = u_colors[0];
136
136
  gradient.rgb *= gradient.a;
137
-
137
+
138
138
  float outerShape = 0.;
139
139
  for (int i = 1; i < ${staticRadialGradientMeta.maxColorCount + 1}; i++) {
140
140
  if (i > int(u_colorsCount)) break;
141
141
  float mLinear = clamp(mixer - float(i - 1), 0.0, 1.0);
142
-
142
+
143
143
  float m = 0.;
144
144
  float mixing = u_mixing * 3.;
145
145
  if (mixing > 2.) {
@@ -151,7 +151,7 @@ void main() {
151
151
  float aa = fwidth(mLinear);
152
152
  m = smoothstep(.5 - .5 * mixing - aa, .5 + .5 * mixing + aa, mLinear);
153
153
  }
154
-
154
+
155
155
  if (i == 1) {
156
156
  outerShape = m;
157
157
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/static-radial-gradient.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingDebugVariablesDeclaration,\n sizingVariablesDeclaration,\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n} from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\nexport const staticRadialGradientMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * N-colors radial gradient\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_radius - circle radius\n * - u_focalDistance, u_focalAngle (float) - gradient center offset to the circle center\n * - u_falloff (-1 .. 1, float) - color points distribution (0 for linear gradient)\n * - u_mixing (0 .. 1, float) - 0 for stepped gradient, 0.5 for smooth transitions, 1 for pronounced color points\n * - u_distortion, u_distortionShift, u_distortionFreq - radial distortion (effective with u_distortion > 0)\n * - u_grainMixer - shape distortion\n * - u_grainOverlay - post-processing blending\n */\n\n// language=GLSL\nexport const staticRadialGradientFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${staticRadialGradientMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_radius;\nuniform float u_focalDistance;\nuniform float u_focalAngle;\nuniform float u_falloff;\nuniform float u_mixing;\nuniform float u_distortion;\nuniform float u_distortionShift;\nuniform float u_distortionFreq;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\n\n${sizingVariablesDeclaration}\n${sizingDebugVariablesDeclaration}\n${sizingUniformsDeclaration}\n\nout vec4 fragColor;\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 noise(vec2 n, vec2 seedOffset) {\n return valueNoise(n + seedOffset);\n}\n\nvec2 getPosition(int i, float t) {\n float a = float(i) * .37;\n float b = .6 + mod(float(i), 3.) * .3;\n float c = .8 + mod(float(i + 1), 4.) * 0.25;\n\n float x = sin(t * b + a);\n float y = cos(t * c + a * 1.5);\n\n return .5 + .5 * vec2(x, y);\n}\n\nvoid main() {\n vec2 uv = 2. * v_objectUV;\n vec2 grainUV = uv * 1000.;\n\n vec2 center = vec2(0.);\n float angleRad = -radians(u_focalAngle + 90.);\n vec2 focalPoint = vec2(cos(angleRad), sin(angleRad)) * u_focalDistance;\n float radius = u_radius;\n \n vec2 c_to_uv = uv - center;\n vec2 f_to_uv = uv - focalPoint;\n vec2 f_to_c = center - focalPoint;\n float r = length(c_to_uv);\n \n float fragAngle = atan(c_to_uv.y, c_to_uv.x);\n float angleDiff = fract((fragAngle - angleRad + PI) / TWO_PI) * TWO_PI - PI;\n\n float halfAngle = acos(clamp(radius / max(u_focalDistance, 1e-4), 0.0, 1.0));\n float e0 = 0.6 * PI, e1 = halfAngle;\n float lo = min(e0, e1), hi = max(e0, e1);\n float s = smoothstep(lo, hi, abs(angleDiff));\n float isInSector = (e1 >= e0) ? (1.0 - s) : s;\n \n float a = dot(f_to_uv, f_to_uv);\n float b = -2.0 * dot(f_to_uv, f_to_c);\n float c = dot(f_to_c, f_to_c) - radius * radius;\n\n float discriminant = b * b - 4.0 * a * c;\n float t = 1.0;\n\n if (discriminant >= 0.0) {\n float sqrtD = sqrt(discriminant);\n float div = max(1e-4, 2.0 * a);\n float t0 = (-b - sqrtD) / div;\n float t1 = (-b + sqrtD) / div;\n t = max(t0, t1);\n if (t < 0.0) t = 0.0;\n }\n\n float dist = length(f_to_uv);\n float normalized = dist / max(1e-4, length(f_to_uv * t));\n float shape = clamp(normalized, 0.0, 1.0);\n\n float falloffMapped = mix(.2 + .8 * max(0., u_falloff + 1.), mix(1., 15., u_falloff * u_falloff), step(.0, u_falloff));\n \n float falloffExp = mix(falloffMapped, 1., shape);\n shape = pow(shape, falloffExp);\n shape = 1. - clamp(shape, 0., 1.);\n\n\n float outerMask = .002;\n float outer = 1.0 - smoothstep(radius - outerMask, radius + outerMask, r);\n outer = mix(outer, 1., isInSector);\n \n shape = mix(0., shape, outer);\n shape *= 1. - smoothstep(radius - .01, radius, r);\n\n float angle = atan(f_to_uv.y, f_to_uv.x);\n shape -= pow(u_distortion, 2.) * shape * pow(abs(sin(PI * clamp(length(f_to_uv) - 0.2 + u_distortionShift, 0.0, 1.0))), 4.0) * (sin(u_distortionFreq * angle) + cos(floor(0.65 * u_distortionFreq) * angle));\n\n float grain = noise(grainUV, vec2(0.));\n float mixerGrain = .4 * u_grainMixer * (grain - .5);\n\n float mixer = shape * u_colorsCount + mixerGrain;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n \n float outerShape = 0.;\n for (int i = 1; i < ${staticRadialGradientMeta.maxColorCount + 1}; i++) {\n if (i > int(u_colorsCount)) break;\n float mLinear = clamp(mixer - float(i - 1), 0.0, 1.0);\n \n float m = 0.;\n float mixing = u_mixing * 3.;\n if (mixing > 2.) {\n float tt = mLinear * mLinear;\n m = mix(mLinear, tt, .5 * clamp((mixing - 2.), 0., 1.));\n } else if (mixing > 1.) {\n m = mix(smoothstep(0., 1., mLinear), mLinear, clamp((mixing - 1.), 0., 1.));\n } else {\n float aa = fwidth(mLinear);\n m = smoothstep(.5 - .5 * mixing - aa, .5 + .5 * mixing + aa, mLinear);\n }\n \n if (i == 1) {\n outerShape = m;\n }\n\n vec4 c = u_colors[i - 1];\n c.rgb *= c.a;\n gradient = mix(gradient, c, m);\n }\n\n vec3 color = gradient.rgb * outerShape;\n float opacity = gradient.a * outerShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\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, .35 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface StaticRadialGradientUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_radius: number;\n u_focalDistance: number;\n u_focalAngle: number;\n u_falloff: number;\n u_mixing: number;\n u_distortion: number;\n u_distortionShift: number;\n u_distortionFreq: number;\n u_grainMixer: number;\n u_grainOverlay: number;\n}\n\nexport interface StaticRadialGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n radius?: number;\n focalDistance?: number;\n focalAngle?: number;\n falloff?: number;\n mixing?: number;\n distortion?: number;\n distortionShift?: number;\n distortionFreq?: number;\n grainMixer?: number;\n grainOverlay?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,WAAW,WAAW,wBAAwB;AAEhD,MAAM,2BAA2B;AAAA,EACtC,eAAe;AACjB;AAkBO,MAAM,qCAA6C;AAAA;AAAA;AAAA;AAAA,wBAIlC,yBAAyB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc5D,0BAA0B;AAAA,EAC1B,+BAA+B;AAAA,EAC/B,yBAAyB;AAAA;AAAA;AAAA;AAAA,EAIzB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAkGM,yBAAyB,gBAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingDebugVariablesDeclaration,\n sizingVariablesDeclaration,\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n} from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\nexport const staticRadialGradientMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Radial gradient with up to 10 blended colors, featuring advanced mixing modes, focal point controls,\n * shape distortion, and grain effects.\n *\n * Fragment shader uniforms:\n * - u_colorBack (vec4): Background color in RGBA\n * - u_colors (vec4[]): Up to 10 gradient colors in RGBA\n * - u_colorsCount (float): Number of active colors\n * - u_radius (float): Size of the shape (0 to 3)\n * - u_focalDistance (float): Distance of the focal point from center (0 to 3)\n * - u_focalAngle (float): Angle of the focal point in degrees, effective with focalDistance > 0 (0 to 360)\n * - u_falloff (float): Gradient decay, 0 = linear gradient (-1 to 1)\n * - u_mixing (float): Blending behavior, 0 = stepped, 0.5 = smooth, 1 = pronounced color points (0 to 1)\n * - u_distortion (float): Strength of radial distortion (0 to 1)\n * - u_distortionShift (float): Radial distortion offset, effective with distortion > 0 (-1 to 1)\n * - u_distortionFreq (float): Radial distortion frequency, effective with distortion > 0 (0 to 20)\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 *\n * Vertex shader outputs (used in fragment shader):\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, 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 (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 staticRadialGradientFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${ staticRadialGradientMeta.maxColorCount }];\nuniform float u_colorsCount;\n\nuniform float u_radius;\nuniform float u_focalDistance;\nuniform float u_focalAngle;\nuniform float u_falloff;\nuniform float u_mixing;\nuniform float u_distortion;\nuniform float u_distortionShift;\nuniform float u_distortionFreq;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\n\n${ sizingVariablesDeclaration }\n${ sizingDebugVariablesDeclaration }\n${ sizingUniformsDeclaration }\n\nout vec4 fragColor;\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 noise(vec2 n, vec2 seedOffset) {\n return valueNoise(n + seedOffset);\n}\n\nvec2 getPosition(int i, float t) {\n float a = float(i) * .37;\n float b = .6 + mod(float(i), 3.) * .3;\n float c = .8 + mod(float(i + 1), 4.) * 0.25;\n\n float x = sin(t * b + a);\n float y = cos(t * c + a * 1.5);\n\n return .5 + .5 * vec2(x, y);\n}\n\nvoid main() {\n vec2 uv = 2. * v_objectUV;\n vec2 grainUV = uv * 1000.;\n\n vec2 center = vec2(0.);\n float angleRad = -radians(u_focalAngle + 90.);\n vec2 focalPoint = vec2(cos(angleRad), sin(angleRad)) * u_focalDistance;\n float radius = u_radius;\n\n vec2 c_to_uv = uv - center;\n vec2 f_to_uv = uv - focalPoint;\n vec2 f_to_c = center - focalPoint;\n float r = length(c_to_uv);\n\n float fragAngle = atan(c_to_uv.y, c_to_uv.x);\n float angleDiff = fract((fragAngle - angleRad + PI) / TWO_PI) * TWO_PI - PI;\n\n float halfAngle = acos(clamp(radius / max(u_focalDistance, 1e-4), 0.0, 1.0));\n float e0 = 0.6 * PI, e1 = halfAngle;\n float lo = min(e0, e1), hi = max(e0, e1);\n float s = smoothstep(lo, hi, abs(angleDiff));\n float isInSector = (e1 >= e0) ? (1.0 - s) : s;\n\n float a = dot(f_to_uv, f_to_uv);\n float b = -2.0 * dot(f_to_uv, f_to_c);\n float c = dot(f_to_c, f_to_c) - radius * radius;\n\n float discriminant = b * b - 4.0 * a * c;\n float t = 1.0;\n\n if (discriminant >= 0.0) {\n float sqrtD = sqrt(discriminant);\n float div = max(1e-4, 2.0 * a);\n float t0 = (-b - sqrtD) / div;\n float t1 = (-b + sqrtD) / div;\n t = max(t0, t1);\n if (t < 0.0) t = 0.0;\n }\n\n float dist = length(f_to_uv);\n float normalized = dist / max(1e-4, length(f_to_uv * t));\n float shape = clamp(normalized, 0.0, 1.0);\n\n float falloffMapped = mix(.2 + .8 * max(0., u_falloff + 1.), mix(1., 15., u_falloff * u_falloff), step(.0, u_falloff));\n\n float falloffExp = mix(falloffMapped, 1., shape);\n shape = pow(shape, falloffExp);\n shape = 1. - clamp(shape, 0., 1.);\n\n\n float outerMask = .002;\n float outer = 1.0 - smoothstep(radius - outerMask, radius + outerMask, r);\n outer = mix(outer, 1., isInSector);\n\n shape = mix(0., shape, outer);\n shape *= 1. - smoothstep(radius - .01, radius, r);\n\n float angle = atan(f_to_uv.y, f_to_uv.x);\n shape -= pow(u_distortion, 2.) * shape * pow(abs(sin(PI * clamp(length(f_to_uv) - 0.2 + u_distortionShift, 0.0, 1.0))), 4.0) * (sin(u_distortionFreq * angle) + cos(floor(0.65 * u_distortionFreq) * angle));\n\n float grain = noise(grainUV, vec2(0.));\n float mixerGrain = .4 * u_grainMixer * (grain - .5);\n\n float mixer = shape * u_colorsCount + mixerGrain;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n\n float outerShape = 0.;\n for (int i = 1; i < ${ staticRadialGradientMeta.maxColorCount + 1 }; i++) {\n if (i > int(u_colorsCount)) break;\n float mLinear = clamp(mixer - float(i - 1), 0.0, 1.0);\n\n float m = 0.;\n float mixing = u_mixing * 3.;\n if (mixing > 2.) {\n float tt = mLinear * mLinear;\n m = mix(mLinear, tt, .5 * clamp((mixing - 2.), 0., 1.));\n } else if (mixing > 1.) {\n m = mix(smoothstep(0., 1., mLinear), mLinear, clamp((mixing - 1.), 0., 1.));\n } else {\n float aa = fwidth(mLinear);\n m = smoothstep(.5 - .5 * mixing - aa, .5 + .5 * mixing + aa, mLinear);\n }\n\n if (i == 1) {\n outerShape = m;\n }\n\n vec4 c = u_colors[i - 1];\n c.rgb *= c.a;\n gradient = mix(gradient, c, m);\n }\n\n vec3 color = gradient.rgb * outerShape;\n float opacity = gradient.a * outerShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\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, .35 * grainOverlayStrength);\n\n opacity += .5 * grainOverlayStrength;\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface StaticRadialGradientUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_radius: number;\n u_focalDistance: number;\n u_focalAngle: number;\n u_falloff: number;\n u_mixing: number;\n u_distortion: number;\n u_distortionShift: number;\n u_distortionFreq: number;\n u_grainMixer: number;\n u_grainOverlay: number;\n}\n\nexport interface StaticRadialGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n radius?: number;\n focalDistance?: number;\n focalAngle?: number;\n falloff?: number;\n mixing?: number;\n distortion?: number;\n distortionShift?: number;\n distortionFreq?: number;\n grainMixer?: number;\n grainOverlay?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,WAAW,WAAW,wBAAwB;AAEhD,MAAM,2BAA2B;AAAA,EACtC,eAAe;AACjB;AAwCO,MAAM,qCAA6C;AAAA;AAAA;AAAA;AAAA,wBAIjC,yBAAyB,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc7D,0BAA2B;AAAA,EAC3B,+BAAgC;AAAA,EAChC,yBAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,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,wBAkGK,yBAAyB,gBAAgB,CAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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
6
  "names": []
7
7
  }
@@ -5,15 +5,36 @@ export declare const swirlMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
7
7
  /**
8
- * Twisting radial bands
8
+ * Animated bands of color twisting and bending, producing spirals, arcs, and flowing circular patterns.
9
9
  *
10
- * Uniforms:
11
- * - u_colorBack (RGBA)
12
- * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
- * - u_bandCount (float, used as int): number of sectors
14
- * - u_twist: sectors twist intensity (0 = linear)
15
- * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)
16
- * - u_noise, u_noiseFrequency: simplex noise distortion over the shape
10
+ * Fragment shader uniforms:
11
+ * - u_time (float): Animation time
12
+ * - u_colorBack (vec4): Background color in RGBA
13
+ * - u_colors (vec4[]): Up to 10 stripe colors in RGBA
14
+ * - u_colorsCount (float): Number of active colors
15
+ * - u_bandCount (float): Number of color bands, 0 = concentric ripples (0 to 15)
16
+ * - u_twist (float): Vortex power, 0 = straight sectoral shapes (0 to 1)
17
+ * - u_center (float): How far from the center the swirl colors begin to appear (0 to 1)
18
+ * - u_proportion (float): Blend point between colors, 0.5 = equal distribution (0 to 1)
19
+ * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)
20
+ * - u_noise (float): Strength of noise distortion, no effect with noiseFrequency = 0 (0 to 1)
21
+ * - u_noiseFrequency (float): Noise frequency, no effect with noise = 0 (0 to 1)
22
+ *
23
+ * Vertex shader outputs (used in fragment shader):
24
+ * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
25
+ *
26
+ * Vertex shader uniforms:
27
+ * - u_resolution (vec2): Canvas resolution in pixels
28
+ * - u_pixelRatio (float): Device pixel ratio
29
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
30
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
31
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
32
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
33
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
34
+ * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
35
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
36
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
37
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
17
38
  *
18
39
  */
19
40
  export declare const swirlFragmentShader: string;
@@ -37,7 +37,7 @@ void main() {
37
37
 
38
38
  float l = length(shape_uv);
39
39
  l = max(1e-4, l);
40
-
40
+
41
41
  float t = u_time;
42
42
 
43
43
  float angle = ceil(u_bandCount) * atan(shape_uv.y, shape_uv.x) + t;
@@ -61,7 +61,7 @@ void main() {
61
61
  float mixer = shape * u_colorsCount;
62
62
  vec4 gradient = u_colors[0];
63
63
  gradient.rgb *= gradient.a;
64
-
64
+
65
65
  float outerShape = 0.;
66
66
  for (int i = 1; i < ${swirlMeta.maxColorCount + 1}; i++) {
67
67
  if (i > int(u_colorsCount)) break;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/swirl.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { simplexNoise, declarePI, rotation2, colorBandingFix } from '../shader-utils.js';\n\nexport const swirlMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Twisting radial bands\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_bandCount (float, used as int): number of sectors\n * - u_twist: sectors twist intensity (0 = linear)\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n * - u_noise, u_noiseFrequency: simplex noise distortion over the shape\n *\n */\n\n// language=GLSL\nexport const swirlFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${swirlMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_bandCount;\nuniform float u_twist;\nuniform float u_center;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_noise;\nuniform float u_noiseFrequency;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${simplexNoise}\n${rotation2}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float l = length(shape_uv);\n l = max(1e-4, l);\n \n float t = u_time;\n\n float angle = ceil(u_bandCount) * atan(shape_uv.y, shape_uv.x) + t;\n float angle_norm = angle / TWO_PI;\n\n float twist = 3. * clamp(u_twist, 0., 1.);\n float offset = pow(l, -twist) + angle_norm;\n\n float shape = fract(offset);\n shape = 1. - abs(2. * shape - 1.);\n shape += u_noise * snoise(15. * pow(u_noiseFrequency, 2.) * shape_uv);\n\n float mid = smoothstep(.2, .2 + .8 * u_center, pow(l, twist));\n shape = mix(0., shape, mid);\n\n float proportion = clamp(u_proportion, 0., 1.);\n float exponent = mix(.25, 1., proportion * 2.);\n exponent = mix(exponent, 10., max(0., proportion * 2. - 1.));\n shape = pow(shape, exponent);\n\n float mixer = shape * u_colorsCount;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n \n float outerShape = 0.;\n for (int i = 1; i < ${swirlMeta.maxColorCount + 1}; i++) {\n if (i > int(u_colorsCount)) break;\n\n float m = clamp(mixer - float(i - 1), 0., 1.);\n float aa = fwidth(m);\n m = smoothstep(.5 - .5 * u_softness - aa, .5 + .5 * u_softness + aa, m);\n\n if (i == 1) {\n outerShape = m;\n }\n\n vec4 c = u_colors[i - 1];\n c.rgb *= c.a;\n gradient = mix(gradient, c, m);\n }\n\n float midAA = .1 * fwidth(pow(l, -twist));\n float outerMid = smoothstep(.2, .2 + midAA, pow(l, twist));\n outerShape = mix(0., outerShape, outerMid);\n\n vec3 color = gradient.rgb * outerShape;\n float opacity = gradient.a * outerShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SwirlUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_bandCount: number;\n u_twist: number;\n u_center: number;\n u_proportion: number;\n u_softness: number;\n u_noiseFrequency: number;\n u_noise: number;\n}\n\nexport interface SwirlParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n bandCount?: number;\n twist?: number;\n center?: number;\n proportion?: number;\n softness?: number;\n noiseFrequency?: number;\n noise?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,cAAc,WAAW,WAAW,uBAAuB;AAE7D,MAAM,YAAY;AAAA,EACvB,eAAe;AACjB;AAgBO,MAAM,sBAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMnB,UAAU,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,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,wBAiCa,UAAU,gBAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2B/C,eAAe;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { simplexNoise, declarePI, rotation2, colorBandingFix } from '../shader-utils.js';\n\nexport const swirlMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Animated bands of color twisting and bending, producing spirals, arcs, and flowing circular patterns.\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 stripe colors in RGBA\n * - u_colorsCount (float): Number of active colors\n * - u_bandCount (float): Number of color bands, 0 = concentric ripples (0 to 15)\n * - u_twist (float): Vortex power, 0 = straight sectoral shapes (0 to 1)\n * - u_center (float): How far from the center the swirl colors begin to appear (0 to 1)\n * - u_proportion (float): Blend point between colors, 0.5 = equal distribution (0 to 1)\n * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)\n * - u_noise (float): Strength of noise distortion, no effect with noiseFrequency = 0 (0 to 1)\n * - u_noiseFrequency (float): Noise frequency, no effect with noise = 0 (0 to 1)\n *\n * Vertex shader outputs (used in fragment shader):\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, 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 (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 swirlFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${ swirlMeta.maxColorCount }];\nuniform float u_colorsCount;\nuniform float u_bandCount;\nuniform float u_twist;\nuniform float u_center;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_noise;\nuniform float u_noiseFrequency;\n\n${ sizingVariablesDeclaration }\n\nout vec4 fragColor;\n\n${ declarePI }\n${ simplexNoise }\n${ rotation2 }\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float l = length(shape_uv);\n l = max(1e-4, l);\n\n float t = u_time;\n\n float angle = ceil(u_bandCount) * atan(shape_uv.y, shape_uv.x) + t;\n float angle_norm = angle / TWO_PI;\n\n float twist = 3. * clamp(u_twist, 0., 1.);\n float offset = pow(l, -twist) + angle_norm;\n\n float shape = fract(offset);\n shape = 1. - abs(2. * shape - 1.);\n shape += u_noise * snoise(15. * pow(u_noiseFrequency, 2.) * shape_uv);\n\n float mid = smoothstep(.2, .2 + .8 * u_center, pow(l, twist));\n shape = mix(0., shape, mid);\n\n float proportion = clamp(u_proportion, 0., 1.);\n float exponent = mix(.25, 1., proportion * 2.);\n exponent = mix(exponent, 10., max(0., proportion * 2. - 1.));\n shape = pow(shape, exponent);\n\n float mixer = shape * u_colorsCount;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n\n float outerShape = 0.;\n for (int i = 1; i < ${ swirlMeta.maxColorCount + 1 }; i++) {\n if (i > int(u_colorsCount)) break;\n\n float m = clamp(mixer - float(i - 1), 0., 1.);\n float aa = fwidth(m);\n m = smoothstep(.5 - .5 * u_softness - aa, .5 + .5 * u_softness + aa, m);\n\n if (i == 1) {\n outerShape = m;\n }\n\n vec4 c = u_colors[i - 1];\n c.rgb *= c.a;\n gradient = mix(gradient, c, m);\n }\n\n float midAA = .1 * fwidth(pow(l, -twist));\n float outerMid = smoothstep(.2, .2 + midAA, pow(l, twist));\n outerShape = mix(0., outerShape, outerMid);\n\n vec3 color = gradient.rgb * outerShape;\n float opacity = gradient.a * outerShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\n ${ colorBandingFix }\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SwirlUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_bandCount: number;\n u_twist: number;\n u_center: number;\n u_proportion: number;\n u_softness: number;\n u_noiseFrequency: number;\n u_noise: number;\n}\n\nexport interface SwirlParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n bandCount?: number;\n twist?: number;\n center?: number;\n proportion?: number;\n softness?: number;\n noiseFrequency?: number;\n noise?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,cAAc,WAAW,WAAW,uBAAuB;AAE7D,MAAM,YAAY;AAAA,EACvB,eAAe;AACjB;AAqCO,MAAM,sBAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMlB,UAAU,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU9C,0BAA2B;AAAA;AAAA;AAAA;AAAA,EAI3B,SAAU;AAAA,EACV,YAAa;AAAA,EACb,SAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAiCY,UAAU,gBAAgB,CAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2BhD,eAAgB;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,20 +5,41 @@ export declare const voronoiMeta: {
5
5
  readonly maxColorCount: 5;
6
6
  };
7
7
  /**
8
- * Double-pass Voronoi pattern cell edges
8
+ * Anti-aliased animated Voronoi pattern with smooth and customizable edges.
9
+ *
10
+ * Double-pass Voronoi pattern cell edges.
9
11
  * Original algorithm: https://www.shadertoy.com/view/ldl3W8
10
12
  *
11
- * Uniforms:
12
- * - u_colorBack, u_colorGlow (RGBA)
13
- * - u_colors (vec4[]), u_colorsCount (float used as integer)
14
- * - u_stepsPerColor: discrete color steps between u_colors
15
- * - u_distortion (0..0.5): max distance the cell center moves away from regular grid
16
- * - u_gap: width of the stroke between the cells
17
- * - u_glow: radial glow around each cell center
13
+ * Note: gaps can't be removed completely due to natural artifacts of Voronoi cells borders
14
+ *
15
+ * Fragment shader uniforms:
16
+ * - u_time (float): Animation time
17
+ * - u_scale (float): Overall zoom level, used for anti-aliasing calculations
18
+ * - u_colors (vec4[]): Up to 5 base cell colors in RGBA
19
+ * - u_colorsCount (float): Number of active colors
20
+ * - u_stepsPerColor (float): Number of extra colors between base colors, 1 = N colors, 2 = 2×N, etc. (1 to 3)
21
+ * - u_colorGlow (vec4): Color tint for radial inner shadow inside cells in RGBA, effective with glow > 0
22
+ * - u_colorGap (vec4): Color used for cell borders/gaps in RGBA
23
+ * - u_distortion (float): Strength of noise-driven displacement of cell centers (0 to 0.5)
24
+ * - u_gap (float): Width of the border/gap between cells (0 to 0.1)
25
+ * - u_glow (float): Strength of the radial inner shadow inside cells (0 to 1)
26
+ * - u_noiseTexture (sampler2D): Pre-computed randomizer source texture
18
27
  *
19
- * - u_noiseTexture (sampler2D): pre-computed randomizer source
28
+ * Vertex shader outputs (used in fragment shader):
29
+ * - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied
20
30
  *
21
- * Note: gaps can't be removed completely due to artifacts of Voronoi cells
31
+ * Vertex shader uniforms:
32
+ * - u_resolution (vec2): Canvas resolution in pixels
33
+ * - u_pixelRatio (float): Device pixel ratio
34
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
35
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
36
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
37
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
38
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
39
+ * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
40
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
41
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
42
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
22
43
  *
23
44
  */
24
45
  export declare const voronoiFragmentShader: string;
@@ -92,12 +92,12 @@ void main() {
92
92
  vec4 gradient = u_colors[0];
93
93
  gradient.rgb *= gradient.a;
94
94
  for (int i = 1; i < ${voronoiMeta.maxColorCount}; i++) {
95
- if (i >= int(u_colorsCount)) break;
96
- float localT = clamp(mixer - float(i - 1), 0.0, 1.0);
97
- localT = round(localT * steps) / steps;
98
- vec4 c = u_colors[i];
99
- c.rgb *= c.a;
100
- gradient = mix(gradient, c, localT);
95
+ if (i >= int(u_colorsCount)) break;
96
+ float localT = clamp(mixer - float(i - 1), 0.0, 1.0);
97
+ localT = round(localT * steps) / steps;
98
+ vec4 c = u_colors[i];
99
+ c.rgb *= c.a;
100
+ gradient = mix(gradient, c, localT);
101
101
  }
102
102
 
103
103
  if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/voronoi.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, textureRandomizerGB } from '../shader-utils.js';\n\nexport const voronoiMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Double-pass Voronoi pattern cell edges\n * Original algorithm: https://www.shadertoy.com/view/ldl3W8\n *\n * Uniforms:\n * - u_colorBack, u_colorGlow (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_stepsPerColor: discrete color steps between u_colors\n * - u_distortion (0..0.5): max distance the cell center moves away from regular grid\n * - u_gap: width of the stroke between the cells\n * - u_glow: radial glow around each cell center\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n * Note: gaps can't be removed completely due to artifacts of Voronoi cells\n *\n */\n\n// language=GLSL\nexport const voronoiFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform float u_scale;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colors[${voronoiMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_stepsPerColor;\nuniform vec4 u_colorGlow;\nuniform vec4 u_colorGap;\nuniform float u_distortion;\nuniform float u_gap;\nuniform float u_glow;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${textureRandomizerGB}\n\nvec4 voronoi(vec2 x, float t) {\n vec2 ip = floor(x);\n vec2 fp = fract(x);\n\n vec2 mg, mr;\n float md = 8.;\n float rand = 0.;\n\n for (int j = -1; j <= 1; j++) {\n for (int i = -1; i <= 1; i++) {\n vec2 g = vec2(float(i), float(j));\n vec2 o = randomGB(ip + g);\n float raw_hash = o.x;\n o = .5 + u_distortion * sin(t + TWO_PI * o);\n vec2 r = g + o - fp;\n float d = dot(r, r);\n\n if (d < md) {\n md = d;\n mr = r;\n mg = g;\n rand = raw_hash;\n }\n }\n }\n\n md = 8.;\n for (int j = -2; j <= 2; j++) {\n for (int i = -2; i <= 2; i++) {\n vec2 g = mg + vec2(float(i), float(j));\n vec2 o = randomGB(ip + g);\n o = .5 + u_distortion * sin(t + TWO_PI * o);\n vec2 r = g + o - fp;\n if (dot(mr - r, mr - r) > .00001) {\n md = min(md, dot(.5 * (mr + r), normalize(r - mr)));\n }\n }\n }\n\n return vec4(md, mr, rand);\n}\n\nvoid main() {\n vec2 shape_uv = v_patternUV;\n shape_uv *= 1.25;\n\n float t = u_time;\n\n vec4 voronoiRes = voronoi(shape_uv, t);\n\n float shape = clamp(voronoiRes.w, 0., 1.);\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 < ${voronoiMeta.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 cellColor = gradient.rgb;\n float cellOpacity = gradient.a;\n\n float glows = length(voronoiRes.yz * u_glow);\n glows = pow(glows, 1.5);\n\n vec3 color = mix(cellColor, u_colorGlow.rgb * u_colorGlow.a, u_colorGlow.a * glows);\n float opacity = cellOpacity + u_colorGlow.a * glows;\n\n float edge = voronoiRes.x;\n float smoothEdge = .02 / (2. * u_scale) * (1. + .5 * u_gap);\n edge = smoothstep(u_gap - smoothEdge, u_gap + smoothEdge, edge);\n\n color = mix(u_colorGap.rgb * u_colorGap.a, color, edge);\n opacity = mix(u_colorGap.a, opacity, edge);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface VoronoiUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_stepsPerColor: number;\n u_colorGap: [number, number, number, number];\n u_colorGlow: [number, number, number, number];\n u_distortion: number;\n u_gap: number;\n u_glow: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface VoronoiParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n stepsPerColor?: number;\n colorGap?: string;\n colorGlow?: string;\n distortion?: number;\n gap?: number;\n glow?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,2BAA2B;AAExC,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAqBO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBASrB,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA2DG,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, textureRandomizerGB } from '../shader-utils.js';\n\nexport const voronoiMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Anti-aliased animated Voronoi pattern with smooth and customizable edges.\n *\n * Double-pass Voronoi pattern cell edges.\n * Original algorithm: https://www.shadertoy.com/view/ldl3W8\n *\n * Note: gaps can't be removed completely due to natural artifacts of Voronoi cells borders\n *\n * Fragment shader uniforms:\n * - u_time (float): Animation time\n * - u_scale (float): Overall zoom level, used for anti-aliasing calculations\n * - u_colors (vec4[]): Up to 5 base cell 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. (1 to 3)\n * - u_colorGlow (vec4): Color tint for radial inner shadow inside cells in RGBA, effective with glow > 0\n * - u_colorGap (vec4): Color used for cell borders/gaps in RGBA\n * - u_distortion (float): Strength of noise-driven displacement of cell centers (0 to 0.5)\n * - u_gap (float): Width of the border/gap between cells (0 to 0.1)\n * - u_glow (float): Strength of the radial inner shadow inside cells (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 for pattern 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 (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 voronoiFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform float u_scale;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colors[${ voronoiMeta.maxColorCount }];\nuniform float u_colorsCount;\n\nuniform float u_stepsPerColor;\nuniform vec4 u_colorGlow;\nuniform vec4 u_colorGap;\nuniform float u_distortion;\nuniform float u_gap;\nuniform float u_glow;\n\n${ sizingVariablesDeclaration }\n\nout vec4 fragColor;\n\n${ declarePI }\n${ textureRandomizerGB }\n\nvec4 voronoi(vec2 x, float t) {\n vec2 ip = floor(x);\n vec2 fp = fract(x);\n\n vec2 mg, mr;\n float md = 8.;\n float rand = 0.;\n\n for (int j = -1; j <= 1; j++) {\n for (int i = -1; i <= 1; i++) {\n vec2 g = vec2(float(i), float(j));\n vec2 o = randomGB(ip + g);\n float raw_hash = o.x;\n o = .5 + u_distortion * sin(t + TWO_PI * o);\n vec2 r = g + o - fp;\n float d = dot(r, r);\n\n if (d < md) {\n md = d;\n mr = r;\n mg = g;\n rand = raw_hash;\n }\n }\n }\n\n md = 8.;\n for (int j = -2; j <= 2; j++) {\n for (int i = -2; i <= 2; i++) {\n vec2 g = mg + vec2(float(i), float(j));\n vec2 o = randomGB(ip + g);\n o = .5 + u_distortion * sin(t + TWO_PI * o);\n vec2 r = g + o - fp;\n if (dot(mr - r, mr - r) > .00001) {\n md = min(md, dot(.5 * (mr + r), normalize(r - mr)));\n }\n }\n }\n\n return vec4(md, mr, rand);\n}\n\nvoid main() {\n vec2 shape_uv = v_patternUV;\n shape_uv *= 1.25;\n\n float t = u_time;\n\n vec4 voronoiRes = voronoi(shape_uv, t);\n\n float shape = clamp(voronoiRes.w, 0., 1.);\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 < ${ voronoiMeta.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 cellColor = gradient.rgb;\n float cellOpacity = gradient.a;\n\n float glows = length(voronoiRes.yz * u_glow);\n glows = pow(glows, 1.5);\n\n vec3 color = mix(cellColor, u_colorGlow.rgb * u_colorGlow.a, u_colorGlow.a * glows);\n float opacity = cellOpacity + u_colorGlow.a * glows;\n\n float edge = voronoiRes.x;\n float smoothEdge = .02 / (2. * u_scale) * (1. + .5 * u_gap);\n edge = smoothstep(u_gap - smoothEdge, u_gap + smoothEdge, edge);\n\n color = mix(u_colorGap.rgb * u_colorGap.a, color, edge);\n opacity = mix(u_colorGap.a, opacity, edge);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface VoronoiUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_stepsPerColor: number;\n u_colorGap: [number, number, number, number];\n u_colorGlow: [number, number, number, number];\n u_distortion: number;\n u_gap: number;\n u_glow: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface VoronoiParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n stepsPerColor?: number;\n colorGap?: string;\n colorGlow?: string;\n distortion?: number;\n gap?: number;\n glow?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,2BAA2B;AAExC,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AA0CO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBASpB,YAAY,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhD,0BAA2B;AAAA;AAAA;AAAA;AAAA,EAI3B,SAAU;AAAA,EACV,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;AAAA;AAAA;AAAA;AAAA;AAAA,wBA2DE,YAAY,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,21 +5,39 @@ export declare const warpMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
7
7
  /**
8
- * Iterative layered + swirl-based distortion applied over different layouts (shapes)
8
+ * Animated color fields warped by noise and swirls, applied over base patterns
9
+ * (checks, stripes, or split edge). Blends up to 10 colors with adjustable distribution,
10
+ * softness, distortion, and swirl. Great for fluid, smoky, or marbled effects.
9
11
  *
10
- * Uniforms:
11
- * - u_colors (vec4[]), u_colorsCount (float used as integer)
12
- * - u_proportion: (0..1) blend point between 2 colors (0.5 = equal distribution)
13
- * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)
14
- * - u_shape (float used as integer):
15
- * ---- 0: checks
16
- * ---- 1: stripes
17
- * ---- 2: 2x halves of canvas (mapping the canvas height regardless of resolution)
18
- * - u_shapeScale: the scale of layouts (underlying shapes)
19
- * - u_distortion: value noise distortion over the UV coordinate
20
- * - u_swirl, u_swirlIterations: swirly distortion (layering curves effect)
12
+ * Fragment shader uniforms:
13
+ * - u_time (float): Animation time
14
+ * - u_scale (float): Overall zoom level, used for anti-aliasing calculations
15
+ * - u_colors (vec4[]): Up to 10 gradient colors in RGBA
16
+ * - u_colorsCount (float): Number of active colors
17
+ * - u_proportion (float): Blend point between colors, 0.5 = equal distribution (0 to 1)
18
+ * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)
19
+ * - u_shape (float): Base pattern type (0 = checks, 1 = stripes, 2 = edge)
20
+ * - u_shapeScale (float): Zoom level of the base pattern (0 to 1)
21
+ * - u_distortion (float): Strength of noise-based distortion (0 to 1)
22
+ * - u_swirl (float): Strength of the swirl distortion (0 to 1)
23
+ * - u_swirlIterations (float): Number of layered swirl passes, effective with swirl > 0 (0 to 20)
24
+ * - u_noiseTexture (sampler2D): Pre-computed randomizer source texture
21
25
  *
22
- * - u_noiseTexture (sampler2D): pre-computed randomizer source
26
+ * Vertex shader outputs (used in fragment shader):
27
+ * - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied
28
+ *
29
+ * Vertex shader uniforms:
30
+ * - u_resolution (vec2): Canvas resolution in pixels
31
+ * - u_pixelRatio (float): Device pixel ratio
32
+ * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
33
+ * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
34
+ * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
35
+ * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
36
+ * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
37
+ * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
38
+ * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
39
+ * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
40
+ * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
23
41
  *
24
42
  */
25
43
  export declare const warpFragmentShader: string;