@paper-design/shaders 0.0.30 → 0.0.31

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 (62) hide show
  1. package/README.md +7 -4
  2. package/dist/index.d.ts +25 -23
  3. package/dist/index.js +35 -22
  4. package/dist/index.js.map +2 -2
  5. package/dist/shaders/color-panels.d.ts +48 -0
  6. package/dist/shaders/color-panels.js +213 -0
  7. package/dist/shaders/color-panels.js.map +7 -0
  8. package/dist/shaders/dithering.d.ts +8 -8
  9. package/dist/shaders/dithering.js +15 -7
  10. package/dist/shaders/dithering.js.map +2 -2
  11. package/dist/shaders/dot-grid.d.ts +1 -1
  12. package/dist/shaders/dot-grid.js +4 -4
  13. package/dist/shaders/dot-grid.js.map +1 -1
  14. package/dist/shaders/dot-orbit.d.ts +6 -3
  15. package/dist/shaders/dot-orbit.js +14 -10
  16. package/dist/shaders/dot-orbit.js.map +2 -2
  17. package/dist/shaders/god-rays.d.ts +9 -6
  18. package/dist/shaders/god-rays.js +15 -16
  19. package/dist/shaders/god-rays.js.map +2 -2
  20. package/dist/shaders/grain-gradient.d.ts +5 -3
  21. package/dist/shaders/grain-gradient.js +50 -36
  22. package/dist/shaders/grain-gradient.js.map +2 -2
  23. package/dist/shaders/liquid-metal.d.ts +27 -12
  24. package/dist/shaders/liquid-metal.js +63 -66
  25. package/dist/shaders/liquid-metal.js.map +2 -2
  26. package/dist/shaders/mesh-gradient.d.ts +3 -3
  27. package/dist/shaders/mesh-gradient.js +6 -6
  28. package/dist/shaders/mesh-gradient.js.map +1 -1
  29. package/dist/shaders/metaballs.d.ts +6 -3
  30. package/dist/shaders/metaballs.js +11 -10
  31. package/dist/shaders/metaballs.js.map +2 -2
  32. package/dist/shaders/neuro-noise.d.ts +12 -6
  33. package/dist/shaders/neuro-noise.js +26 -11
  34. package/dist/shaders/neuro-noise.js.map +2 -2
  35. package/dist/shaders/perlin-noise.d.ts +10 -10
  36. package/dist/shaders/perlin-noise.js +29 -21
  37. package/dist/shaders/perlin-noise.js.map +2 -2
  38. package/dist/shaders/pulsing-border.d.ts +3 -3
  39. package/dist/shaders/pulsing-border.js +25 -25
  40. package/dist/shaders/pulsing-border.js.map +1 -1
  41. package/dist/shaders/simplex-noise.d.ts +3 -3
  42. package/dist/shaders/simplex-noise.js +12 -12
  43. package/dist/shaders/simplex-noise.js.map +1 -1
  44. package/dist/shaders/smoke-ring.d.ts +3 -3
  45. package/dist/shaders/smoke-ring.js +6 -6
  46. package/dist/shaders/smoke-ring.js.map +1 -1
  47. package/dist/shaders/spiral.d.ts +8 -8
  48. package/dist/shaders/spiral.js +15 -7
  49. package/dist/shaders/spiral.js.map +2 -2
  50. package/dist/shaders/swirl.d.ts +5 -3
  51. package/dist/shaders/swirl.js +29 -18
  52. package/dist/shaders/swirl.js.map +2 -2
  53. package/dist/shaders/voronoi.d.ts +8 -8
  54. package/dist/shaders/voronoi.js +11 -11
  55. package/dist/shaders/voronoi.js.map +1 -1
  56. package/dist/shaders/warp.d.ts +3 -3
  57. package/dist/shaders/warp.js +31 -27
  58. package/dist/shaders/warp.js.map +2 -2
  59. package/dist/shaders/waves.d.ts +7 -7
  60. package/dist/shaders/waves.js +16 -8
  61. package/dist/shaders/waves.js.map +2 -2
  62. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/smoke-ring.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types';\nimport type { ShaderMotionParams } from '../shader-mount';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';\nimport { declarePI, declareRandom, colorBandingFix } from '../shader-utils';\n\nexport const smokeRingMeta = {\n maxColorCount: 10,\n maxNoiseIterations: 8,\n} as const;\n\n/**\n * Smoke Ring by Ksenia Kondrashova\n * Renders a fractional Brownian motion (fBm) noise over the\n * polar coordinates masked with ring shape\n *\n * Uniforms include:\n * - u_colorBack: the background color of the scene\n * - uColors (vec4[]): Input RGBA colors\n * - uColorsCount (float): Number of active colors (`uColors` length) * u_noiseScale - the resolution of noise texture\n * - u_thickness (float): the thickness of the ring\n * - u_radius (float): the radius of the ring (u_radius = 0.5 to fit in contain mode)\n * - u_innerShape (float): if we fill the shape inside the radius (u_innerShape = 1 to render only the thickness)\n * - u_noiseIterations (float): how detailed is the noise (number of fbm layers)\n */\n\nexport const smokeRingFragmentShader: 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[${smokeRingMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_noiseScale;\nuniform float u_thickness;\nuniform float u_radius;\nuniform float u_innerShape;\nuniform float u_noiseIterations;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n//$ {declareRandom}\n\nfloat random(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).r;\n}\n\nfloat noise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smoothstep for interpolation\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n // Do the interpolation as two nested mix operations\n // If you try to do this in one big operation, there's enough precision loss to be off by 1px at cell boundaries\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 fbm(in vec2 n) {\n float total = 0.0, amplitude = .4;\n for (int i = 0; i < ${smokeRingMeta.maxNoiseIterations}; i++) {\n if (i >= int(u_noiseIterations)) break;\n total += noise(n) * amplitude;\n n *= 1.99;\n amplitude *= 0.65;\n }\n return total;\n}\n\nfloat getNoise(vec2 uv, vec2 pUv, float t) {\n float noiseLeft = fbm(pUv + .03 * t);\n pUv.x = mod(pUv.x, u_noiseScale * TWO_PI);\n float noiseRight = fbm(pUv + .03 * t);\n return mix(noiseRight, noiseLeft, smoothstep(-.25, .25, uv.x));\n}\n\nfloat getRingShape(vec2 uv) {\n float radius = u_radius;\n float thickness = u_thickness;\n\n float distance = length(uv);\n float ringValue = 1. - smoothstep(radius, radius + thickness, distance);\n ringValue *= smoothstep(radius - pow(u_innerShape, 3.) * thickness, radius, distance);\n\n return ringValue;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float t = u_time;\n\n float cycleDuration = 3.;\n float localTime1 = mod(.1 * t + cycleDuration, 2. * cycleDuration);\n float localTime2 = mod(.1 * t, 2. * cycleDuration);\n float timeBlend = .5 + .5 * sin(.1 * t * PI / cycleDuration - .5 * PI);\n\n float atg = atan(shape_uv.y, shape_uv.x) + .001;\n float l = length(shape_uv);\n vec2 polar_uv1 = vec2(atg, localTime1 - (.5 * l) + 1. / pow(l, .5));\n polar_uv1 *= u_noiseScale;\n float noise1 = getNoise(shape_uv, polar_uv1, t);\n\n vec2 polar_uv2 = vec2(atg, localTime2 - (.5 * l) + 1. / pow(l, .5));\n polar_uv2 *= u_noiseScale;\n float noise2 = getNoise(shape_uv, polar_uv2, t);\n\n float noise = mix(noise1, noise2, timeBlend);\n\n shape_uv *= (.8 + 1.2 * noise);\n\n float ringShape = getRingShape(shape_uv);\n\n float mixer = pow(ringShape, 3.) * (u_colorsCount - 1.);\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${smokeRingMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0., 1.);\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n float opacity = gradient.a * ringShape;\n opacity += u_colorBack.a;\n\n vec3 color = gradient.rgb * ringShape;\n color += u_colorBack.rgb * u_colorBack.a * (1. - ringShape);\n color += u_colorBack.rgb * u_colorBack.a * ringShape * (1. - gradient.a);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SmokeRingUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_noiseScale: number;\n u_thickness: number;\n u_radius: number;\n u_innerShape: number;\n u_noiseIterations: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface SmokeRingParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n noiseScale?: number;\n thickness?: number;\n radius?: number;\n innerShape?: number;\n noiseIterations?: number;\n}\n"],
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, declareRandom, colorBandingFix } from '../shader-utils.js';\n\nexport const smokeRingMeta = {\n maxColorCount: 10,\n maxNoiseIterations: 8,\n} as const;\n\n/**\n * Smoke Ring by Ksenia Kondrashova\n * Renders a fractional Brownian motion (fBm) noise over the\n * polar coordinates masked with ring shape\n *\n * Uniforms include:\n * - u_colorBack: the background color of the scene\n * - uColors (vec4[]): Input RGBA colors\n * - uColorsCount (float): Number of active colors (`uColors` length) * u_noiseScale - the resolution of noise texture\n * - u_thickness (float): the thickness of the ring\n * - u_radius (float): the radius of the ring (u_radius = 0.5 to fit in contain mode)\n * - u_innerShape (float): if we fill the shape inside the radius (u_innerShape = 1 to render only the thickness)\n * - u_noiseIterations (float): how detailed is the noise (number of fbm layers)\n */\n\nexport const smokeRingFragmentShader: 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[${smokeRingMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_noiseScale;\nuniform float u_thickness;\nuniform float u_radius;\nuniform float u_innerShape;\nuniform float u_noiseIterations;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n//$ {declareRandom}\n\nfloat random(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).r;\n}\n\nfloat noise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smoothstep for interpolation\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n // Do the interpolation as two nested mix operations\n // If you try to do this in one big operation, there's enough precision loss to be off by 1px at cell boundaries\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 fbm(in vec2 n) {\n float total = 0.0, amplitude = .4;\n for (int i = 0; i < ${smokeRingMeta.maxNoiseIterations}; i++) {\n if (i >= int(u_noiseIterations)) break;\n total += noise(n) * amplitude;\n n *= 1.99;\n amplitude *= 0.65;\n }\n return total;\n}\n\nfloat getNoise(vec2 uv, vec2 pUv, float t) {\n float noiseLeft = fbm(pUv + .03 * t);\n pUv.x = mod(pUv.x, u_noiseScale * TWO_PI);\n float noiseRight = fbm(pUv + .03 * t);\n return mix(noiseRight, noiseLeft, smoothstep(-.25, .25, uv.x));\n}\n\nfloat getRingShape(vec2 uv) {\n float radius = u_radius;\n float thickness = u_thickness;\n\n float distance = length(uv);\n float ringValue = 1. - smoothstep(radius, radius + thickness, distance);\n ringValue *= smoothstep(radius - pow(u_innerShape, 3.) * thickness, radius, distance);\n\n return ringValue;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float t = u_time;\n\n float cycleDuration = 3.;\n float localTime1 = mod(.1 * t + cycleDuration, 2. * cycleDuration);\n float localTime2 = mod(.1 * t, 2. * cycleDuration);\n float timeBlend = .5 + .5 * sin(.1 * t * PI / cycleDuration - .5 * PI);\n\n float atg = atan(shape_uv.y, shape_uv.x) + .001;\n float l = length(shape_uv);\n vec2 polar_uv1 = vec2(atg, localTime1 - (.5 * l) + 1. / pow(l, .5));\n polar_uv1 *= u_noiseScale;\n float noise1 = getNoise(shape_uv, polar_uv1, t);\n\n vec2 polar_uv2 = vec2(atg, localTime2 - (.5 * l) + 1. / pow(l, .5));\n polar_uv2 *= u_noiseScale;\n float noise2 = getNoise(shape_uv, polar_uv2, t);\n\n float noise = mix(noise1, noise2, timeBlend);\n\n shape_uv *= (.8 + 1.2 * noise);\n\n float ringShape = getRingShape(shape_uv);\n\n float mixer = pow(ringShape, 3.) * (u_colorsCount - 1.);\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${smokeRingMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0., 1.);\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n vec3 color = gradient.rgb * ringShape;\n float opacity = gradient.a * ringShape;\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 ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SmokeRingUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_noiseScale: number;\n u_thickness: number;\n u_radius: number;\n u_innerShape: number;\n u_noiseIterations: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface SmokeRingParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n noiseScale?: number;\n thickness?: number;\n radius?: number;\n innerShape?: number;\n noiseIterations?: number;\n}\n"],
5
5
  "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,uBAAuB;AAEnD,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,oBAAoB;AACtB;AAiBO,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQvB,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASjD,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA4Ba,cAAc,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAwDhC,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe/C,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
- import type { ShaderMotionParams } from '../shader-mount';
2
- import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';
1
+ import type { ShaderMotionParams } from '../shader-mount.js';
2
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
3
3
  /**
4
4
  * Spiral shape by Ksenia Kondrashova
5
5
  * Generates a dynamic spiral shape with configurable parameters
@@ -9,8 +9,8 @@ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-si
9
9
  * u_scale - controls the overall scale of the spiral (u_scale = 1 makes it fit the viewport height)
10
10
  * u_offsetX - left / right pan
11
11
  * u_offsetY - up / down pan
12
- * u_color1 - the first color used in the spiral (stroke)
13
- * u_color2 - the second color used in the spiral (back)
12
+ * u_colorBack - the first color used in the spiral (stroke)
13
+ * u_colorFront - the second color used in the spiral (back)
14
14
  * u_density (0 .. 1) - the spacing of the spiral arms
15
15
  * u_distortion (0 .. 1) - adds a wavy distortion effect to the spiral arms
16
16
  * u_strokeWidth (0 .. 1) - defines the thickness of the spiral lines.
@@ -22,8 +22,8 @@ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-si
22
22
  */
23
23
  export declare const spiralFragmentShader: string;
24
24
  export interface SpiralUniforms extends ShaderSizingUniforms {
25
- u_color1: [number, number, number, number];
26
- u_color2: [number, number, number, number];
25
+ u_colorBack: [number, number, number, number];
26
+ u_colorFront: [number, number, number, number];
27
27
  u_density: number;
28
28
  u_distortion: number;
29
29
  u_strokeWidth: number;
@@ -34,8 +34,8 @@ export interface SpiralUniforms extends ShaderSizingUniforms {
34
34
  u_softness: number;
35
35
  }
36
36
  export interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {
37
- color1?: string;
38
- color2?: string;
37
+ colorBack?: string;
38
+ colorFront?: string;
39
39
  density?: number;
40
40
  distortion?: number;
41
41
  strokeWidth?: number;
@@ -3,15 +3,15 @@
3
3
  * https://github.com/paper-design/shaders *
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
- import { sizingVariablesDeclaration } from "../shader-sizing";
7
- import { declareSimplexNoise, declarePI, colorBandingFix } from "../shader-utils";
6
+ import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
+ import { declareSimplexNoise, declarePI, colorBandingFix } from "../shader-utils.js";
8
8
  const spiralFragmentShader = `#version 300 es
9
9
  precision mediump float;
10
10
 
11
11
  uniform float u_time;
12
12
 
13
- uniform vec4 u_color1;
14
- uniform vec4 u_color2;
13
+ uniform vec4 u_colorBack;
14
+ uniform vec4 u_colorFront;
15
15
  uniform float u_density;
16
16
  uniform float u_distortion;
17
17
  uniform float u_strokeWidth;
@@ -59,10 +59,18 @@ void main() {
59
59
  mid = pow(mid, 2.);
60
60
  shape -= .5 * u_strokeCap * mid;
61
61
 
62
- shape = smoothstep(stroke_width - edge_width - u_softness, stroke_width + edge_width + u_softness, shape);
62
+ float res = smoothstep(stroke_width - edge_width - u_softness, stroke_width + edge_width + u_softness, shape);
63
63
 
64
- vec3 color = mix(u_color1.rgb * u_color1.a, u_color2.rgb * u_color2.a, shape);
65
- float opacity = mix(u_color1.a, u_color2.a, shape);
64
+ vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
65
+ float fgOpacity = u_colorFront.a;
66
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
67
+ float bgOpacity = u_colorBack.a;
68
+
69
+ vec3 color = bgColor * res;
70
+ float opacity = bgOpacity * res;
71
+
72
+ color += fgColor * (1. - opacity);
73
+ opacity += fgOpacity * (1. - opacity);
66
74
 
67
75
  ${colorBandingFix}
68
76
 
@@ -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';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';\nimport { declareSimplexNoise, declarePI, colorBandingFix } from '../shader-utils';\n\n/**\n * Spiral shape by Ksenia Kondrashova\n * Generates a dynamic spiral shape with configurable parameters\n *\n * Uniforms include:\n *\n * u_scale - controls the overall scale of the spiral (u_scale = 1 makes it fit the viewport height)\n * u_offsetX - left / right pan\n * u_offsetY - up / down pan\n * u_color1 - the first color used in the spiral (stroke)\n * u_color2 - the second color used in the spiral (back)\n * u_density (0 .. 1) - the spacing of the spiral arms\n * u_distortion (0 .. 1) - adds a wavy distortion effect to the spiral arms\n * u_strokeWidth (0 .. 1) - defines the thickness of the spiral lines.\n * u_strokeCap (0 .. 1) - adjusts the fading of the spiral edges.\n * u_strokeTaper (0 .. 1) - controls the tapering effect along the spiral arms.\n * u_noiseFrequency - frequency of the noise applied to the spiral.\n * u_noisePower (0 .. 1) - strength of the noise effect.\n * u_softness - softens the edges of the spiral for a smoother appearance.\n */\nexport const spiralFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_color1;\nuniform vec4 u_color2;\nuniform float u_density;\nuniform float u_distortion;\nuniform float u_strokeWidth;\nuniform float u_strokeCap;\nuniform float u_strokeTaper;\n\nuniform float u_noiseFrequency;\nuniform float u_noisePower;\nuniform float u_softness;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n\nvoid main() {\n vec2 shape_uv = v_patternUV * .02;\n\n float t = u_time;\n\n float l = length(shape_uv);\n float angle = atan(shape_uv.y, shape_uv.x) - 2. * t;\n float angle_norm = angle / TWO_PI;\n\n angle_norm += .125 * u_noisePower * snoise(.5 * u_noiseFrequency * shape_uv);\n\n float offset = pow(l, 1. - clamp(u_density, 0., 1.)) + angle_norm;\n\n float stripe_map = fract(offset);\n stripe_map -= .5 * u_strokeTaper * l;\n\n stripe_map += .25 * u_noisePower * snoise(u_noiseFrequency * shape_uv);\n\n float shape = 2. * abs(stripe_map - .5);\n\n shape *= (1. + u_distortion * sin(4. * l - t) * cos(PI + l + t));\n\n float stroke_width = clamp(u_strokeWidth, fwidth(l), 1. - fwidth(l));\n\n float edge_width = min(fwidth(l), fwidth(offset));\n\n float mid = 1. - smoothstep(.0, .9, l);\n mid = pow(mid, 2.);\n shape -= .5 * u_strokeCap * mid;\n\n shape = smoothstep(stroke_width - edge_width - u_softness, stroke_width + edge_width + u_softness, shape);\n\n vec3 color = mix(u_color1.rgb * u_color1.a, u_color2.rgb * u_color2.a, shape);\n float opacity = mix(u_color1.a, u_color2.a, shape);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SpiralUniforms extends ShaderSizingUniforms {\n u_color1: [number, number, number, number];\n u_color2: [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_noiseFrequency: number;\n u_noisePower: number;\n u_softness: number;\n}\n\nexport interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {\n color1?: string;\n color2?: string;\n density?: number;\n distortion?: number;\n strokeWidth?: number;\n strokeTaper?: number;\n strokeCap?: number;\n noiseFrequency?: number;\n noisePower?: number;\n softness?: number;\n}\n"],
5
- "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,WAAW,uBAAuB;AAsBzD,MAAM,uBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiB1C,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,IAqCjB,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 { declareSimplexNoise, declarePI, colorBandingFix } from '../shader-utils.js';\n\n/**\n * Spiral shape by Ksenia Kondrashova\n * Generates a dynamic spiral shape with configurable parameters\n *\n * Uniforms include:\n *\n * u_scale - controls the overall scale of the spiral (u_scale = 1 makes it fit the viewport height)\n * u_offsetX - left / right pan\n * u_offsetY - up / down pan\n * u_colorBack - the first color used in the spiral (stroke)\n * u_colorFront - the second color used in the spiral (back)\n * u_density (0 .. 1) - the spacing of the spiral arms\n * u_distortion (0 .. 1) - adds a wavy distortion effect to the spiral arms\n * u_strokeWidth (0 .. 1) - defines the thickness of the spiral lines.\n * u_strokeCap (0 .. 1) - adjusts the fading of the spiral edges.\n * u_strokeTaper (0 .. 1) - controls the tapering effect along the spiral arms.\n * u_noiseFrequency - frequency of the noise applied to the spiral.\n * u_noisePower (0 .. 1) - strength of the noise effect.\n * u_softness - softens the edges of the spiral for a smoother appearance.\n */\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;\n\nuniform float u_noiseFrequency;\nuniform float u_noisePower;\nuniform float u_softness;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n\nvoid main() {\n vec2 shape_uv = v_patternUV * .02;\n\n float t = u_time;\n\n float l = length(shape_uv);\n float angle = atan(shape_uv.y, shape_uv.x) - 2. * t;\n float angle_norm = angle / TWO_PI;\n\n angle_norm += .125 * u_noisePower * snoise(.5 * u_noiseFrequency * shape_uv);\n\n float offset = pow(l, 1. - clamp(u_density, 0., 1.)) + angle_norm;\n\n float stripe_map = fract(offset);\n stripe_map -= .5 * u_strokeTaper * l;\n\n stripe_map += .25 * u_noisePower * snoise(u_noiseFrequency * shape_uv);\n\n float shape = 2. * abs(stripe_map - .5);\n\n shape *= (1. + u_distortion * sin(4. * l - t) * cos(PI + l + t));\n\n float stroke_width = clamp(u_strokeWidth, fwidth(l), 1. - fwidth(l));\n\n float edge_width = min(fwidth(l), fwidth(offset));\n\n float mid = 1. - smoothstep(.0, .9, l);\n mid = pow(mid, 2.);\n shape -= .5 * u_strokeCap * mid;\n\n float res = smoothstep(stroke_width - edge_width - u_softness, stroke_width + edge_width + 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 = bgColor * res;\n float opacity = bgOpacity * res;\n\n color += fgColor * (1. - opacity);\n opacity += fgOpacity * (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_noiseFrequency: number;\n u_noisePower: 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 noiseFrequency?: number;\n noisePower?: number;\n softness?: number;\n}\n"],
5
+ "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,WAAW,uBAAuB;AAsBzD,MAAM,uBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiB1C,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,IA6CjB,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
- import type { vec4 } from '../types';
2
- import type { ShaderMotionParams } from '../shader-mount';
3
- import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';
1
+ import type { vec4 } from '../types.js';
2
+ import type { ShaderMotionParams } from '../shader-mount.js';
3
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
4
4
  export declare const swirlMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
@@ -8,6 +8,7 @@ export declare const swirlMeta: {
8
8
  */
9
9
  export declare const swirlFragmentShader: string;
10
10
  export interface SwirlUniforms extends ShaderSizingUniforms {
11
+ u_colorBack: [number, number, number, number];
11
12
  u_colors: vec4[];
12
13
  u_colorsCount: number;
13
14
  u_bandCount: number;
@@ -17,6 +18,7 @@ export interface SwirlUniforms extends ShaderSizingUniforms {
17
18
  u_noisePower: number;
18
19
  }
19
20
  export interface SwirlParams extends ShaderSizingParams, ShaderMotionParams {
21
+ colorBack?: string;
20
22
  colors?: string[];
21
23
  bandCount?: number;
22
24
  twist?: number;
@@ -3,8 +3,8 @@
3
3
  * https://github.com/paper-design/shaders *
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
- import { sizingVariablesDeclaration } from "../shader-sizing";
7
- import { declareSimplexNoise, declarePI, declareRotate, colorBandingFix } from "../shader-utils";
6
+ import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
+ import { declareSimplexNoise, declarePI, declareRotate, colorBandingFix } from "../shader-utils.js";
8
8
  const swirlMeta = {
9
9
  maxColorCount: 10
10
10
  };
@@ -13,6 +13,7 @@ precision mediump float;
13
13
 
14
14
  uniform float u_time;
15
15
 
16
+ uniform vec4 u_colorBack;
16
17
  uniform vec4 u_colors[${swirlMeta.maxColorCount}];
17
18
  uniform float u_colorsCount;
18
19
  uniform float u_bandCount;
@@ -31,45 +32,55 @@ ${declareRotate}
31
32
 
32
33
  void main() {
33
34
  vec2 shape_uv = v_objectUV;
34
-
35
+
35
36
  float l = length(shape_uv);
36
37
 
37
38
  float t = u_time;
38
39
 
39
40
  float angle = ceil(u_bandCount) * atan(shape_uv.y, shape_uv.x) + t;
40
- float angle_norm = angle / TWO_PI;
41
-
41
+ float angle_norm = angle / TWO_PI;
42
+
42
43
  float twist = 3. * clamp(u_twist, 0., 1.);
43
44
  float offset = pow(l, -twist) + angle_norm;
44
-
45
+
45
46
  float shape = fract(offset);
46
47
  shape = 1. - abs(2. * shape - 1.);
47
48
  shape += u_noisePower * snoise(pow(u_noiseFrequency, 2.) * shape_uv);
48
49
 
49
50
  float mid = smoothstep(.2, .4, pow(l, twist));
50
51
  shape = mix(0., shape, mid);
51
-
52
- float mixer = shape * (u_colorsCount - 1.);
53
- float softness = u_softness + (.1 + .012 * u_colorsCount) * smoothstep(.6, .2, pow(l, twist));
54
52
 
53
+ float edge_w = fwidth(shape);
54
+
55
+ float mixer = shape * (u_colorsCount + 1.) / u_colorsCount;
55
56
  vec4 gradient = u_colors[0];
56
57
  gradient.rgb *= gradient.a;
58
+
57
59
  for (int i = 1; i < ${swirlMeta.maxColorCount}; i++) {
58
- if (i >= int(u_colorsCount)) break;
59
-
60
- float localT = clamp(mixer - float(i - 1), 0., 1.);
61
- localT = smoothstep(.5 - .5 * u_softness, .5 + .5 * u_softness, localT);
60
+ if (i > int(u_colorsCount) - 1) break;
62
61
 
62
+ vec2 borders = vec2(float(i + 1) - u_softness - edge_w, float(i + 1) + u_softness + edge_w) / u_colorsCount;
63
+ float localT = smoothstep(borders[0], borders[1], mixer);
63
64
  vec4 c = u_colors[i];
64
65
  c.rgb *= c.a;
65
66
  gradient = mix(gradient, c, localT);
66
67
  }
67
-
68
- vec3 color = gradient.rgb;
69
- float opacity = gradient.a;
70
-
68
+
69
+ vec2 borders = vec2(2. / (u_colorsCount - 1.));
70
+ borders = vec2(borders[0] - u_softness - edge_w, borders[1] + u_softness + edge_w) / u_colorsCount;
71
+ borders[0] = max(0., borders[0]);
72
+ float gradientShape = smoothstep(borders[0], borders[1], mixer);
73
+
74
+ vec3 color = gradient.rgb * gradientShape;
75
+ float opacity = gradient.a * gradientShape;
76
+
77
+ vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
78
+ color = color + bgColor * (1.0 - opacity);
79
+ opacity = opacity + u_colorBack.a * (1.0 - opacity);
80
+
81
+
71
82
  ${colorBandingFix}
72
-
83
+
73
84
  fragColor = vec4(color, opacity);
74
85
  }
75
86
  `;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/swirl.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types';\nimport type { ShaderMotionParams } from '../shader-mount';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';\nimport { declareSimplexNoise, declarePI, declareRotate, colorBandingFix } from '../shader-utils';\n\nexport const swirlMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n */\nexport const swirlFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colors[${swirlMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_bandCount;\nuniform float u_twist;\nuniform float u_softness;\nuniform float u_noisePower;\nuniform float u_noiseFrequency;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n${declareRotate}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n \n float l = length(shape_uv);\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_noisePower * snoise(pow(u_noiseFrequency, 2.) * shape_uv);\n\n float mid = smoothstep(.2, .4, pow(l, twist));\n shape = mix(0., shape, mid);\n \n float mixer = shape * (u_colorsCount - 1.);\n float softness = u_softness + (.1 + .012 * u_colorsCount) * smoothstep(.6, .2, pow(l, twist));\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${swirlMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n \n float localT = clamp(mixer - float(i - 1), 0., 1.); \n localT = smoothstep(.5 - .5 * u_softness, .5 + .5 * u_softness, localT);\n\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n \n vec3 color = gradient.rgb;\n float opacity = gradient.a;\n \n ${colorBandingFix}\n \n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SwirlUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_bandCount: number;\n u_twist: number;\n u_softness: number;\n u_noiseFrequency: number;\n u_noisePower: number;\n}\n\nexport interface SwirlParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n bandCount?: number;\n twist?: number;\n softness?: number;\n noiseFrequency?: number;\n noisePower?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,WAAW,eAAe,uBAAuB;AAExE,MAAM,YAAY;AAAA,EACvB,eAAe;AACjB;AAIO,MAAM,sBAA8B;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKnB,UAAU,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ7C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA2BS,UAAU,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAc3C,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 { declareSimplexNoise, declarePI, declareRotate, colorBandingFix } from '../shader-utils.js';\n\nexport const swirlMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n */\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_softness;\nuniform float u_noisePower;\nuniform float u_noiseFrequency;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n${declareRotate}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float l = length(shape_uv);\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_noisePower * snoise(pow(u_noiseFrequency, 2.) * shape_uv);\n\n float mid = smoothstep(.2, .4, pow(l, twist));\n shape = mix(0., shape, mid);\n\n float edge_w = fwidth(shape);\n\n float mixer = shape * (u_colorsCount + 1.) / u_colorsCount;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n\n for (int i = 1; i < ${swirlMeta.maxColorCount}; i++) {\n if (i > int(u_colorsCount) - 1) break;\n\n vec2 borders = vec2(float(i + 1) - u_softness - edge_w, float(i + 1) + u_softness + edge_w) / u_colorsCount;\n float localT = smoothstep(borders[0], borders[1], mixer);\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n vec2 borders = vec2(2. / (u_colorsCount - 1.));\n borders = vec2(borders[0] - u_softness - edge_w, borders[1] + u_softness + edge_w) / u_colorsCount;\n borders[0] = max(0., borders[0]);\n float gradientShape = smoothstep(borders[0], borders[1], mixer);\n\n vec3 color = gradient.rgb * gradientShape;\n float opacity = gradient.a * gradientShape;\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\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_softness: number;\n u_noiseFrequency: number;\n u_noisePower: number;\n}\n\nexport interface SwirlParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n bandCount?: number;\n twist?: number;\n softness?: number;\n noiseFrequency?: number;\n noisePower?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,WAAW,eAAe,uBAAuB;AAExE,MAAM,YAAY;AAAA,EACvB,eAAe;AACjB;AAIO,MAAM,sBAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMnB,UAAU,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ7C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA4BS,UAAU,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuB3C,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
- import type { vec4 } from '../types';
2
- import type { ShaderMotionParams } from '../shader-mount';
3
- import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';
1
+ import type { vec4 } from '../types.js';
2
+ import type { ShaderMotionParams } from '../shader-mount.js';
3
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
4
4
  export declare const voronoiMeta: {
5
5
  readonly maxColorCount: 5;
6
6
  };
@@ -17,7 +17,7 @@ export declare const voronoiMeta: {
17
17
  * - `u_colorGlow` (`vec4`): RGBA color for the radial shape on the cell edges
18
18
  * - `u_distortion` (`float`, 0 – 0.5): Controls how far cell centers can be displaced from the regular grid
19
19
  * - `u_gap` (`float`): Width of the gaps between cells (gaps can't be removed completely due to artifacts of Voronoi cells)
20
- * - `u_innerGlow` (`float`): Controls the size of the radial glow inside each cell
20
+ * - `u_glow` (`float`): Controls the size of the radial glow inside each cell
21
21
  * - `u_stepsPerColor` (`float`): Discretization of the color transition
22
22
  * - `u_noiseTexture` (`sampler2D`): Replacement of standard hash function, added for better performance
23
23
  */
@@ -26,19 +26,19 @@ export interface VoronoiUniforms extends ShaderSizingUniforms {
26
26
  u_colors: vec4[];
27
27
  u_colorsCount: number;
28
28
  u_stepsPerColor: number;
29
- u_colorBack: [number, number, number, number];
29
+ u_colorGap: [number, number, number, number];
30
30
  u_colorGlow: [number, number, number, number];
31
31
  u_distortion: number;
32
32
  u_gap: number;
33
- u_innerGlow: number;
33
+ u_glow: number;
34
34
  u_noiseTexture?: HTMLImageElement;
35
35
  }
36
36
  export interface VoronoiParams extends ShaderSizingParams, ShaderMotionParams {
37
37
  colors?: string[];
38
38
  stepsPerColor?: number;
39
- colorBack?: string;
39
+ colorGap?: string;
40
40
  colorGlow?: string;
41
41
  distortion?: number;
42
42
  gap?: number;
43
- innerGlow?: number;
43
+ glow?: number;
44
44
  }
@@ -3,8 +3,8 @@
3
3
  * https://github.com/paper-design/shaders *
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
- import { sizingVariablesDeclaration } from "../shader-sizing";
7
- import { declarePI } from "../shader-utils";
6
+ import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
+ import { declarePI } from "../shader-utils.js";
8
8
  const voronoiMeta = {
9
9
  maxColorCount: 5
10
10
  };
@@ -22,10 +22,10 @@ uniform float u_colorsCount;
22
22
 
23
23
  uniform float u_stepsPerColor;
24
24
  uniform vec4 u_colorGlow;
25
- uniform vec4 u_colorBack;
25
+ uniform vec4 u_colorGap;
26
26
  uniform float u_distortion;
27
27
  uniform float u_gap;
28
- uniform float u_innerGlow;
28
+ uniform float u_glow;
29
29
 
30
30
  ${sizingVariablesDeclaration}
31
31
 
@@ -120,20 +120,20 @@ void main() {
120
120
  vec3 cellColor = gradient.rgb;
121
121
  float cellOpacity = gradient.a;
122
122
 
123
- float innerGlows = length(voronoiRes.yz * u_innerGlow + .1);
124
- innerGlows = pow(innerGlows, 1.5);
123
+ float glows = length(voronoiRes.yz * u_glow + .1);
124
+ glows = pow(glows, 1.5);
125
125
 
126
- vec3 color = mix(cellColor, u_colorGlow.rgb * u_colorGlow.a, u_colorGlow.a * innerGlows);
127
- float opacity = cellOpacity + u_colorGlow.a * innerGlows;
126
+ vec3 color = mix(cellColor, u_colorGlow.rgb * u_colorGlow.a, u_colorGlow.a * glows);
127
+ float opacity = cellOpacity + u_colorGlow.a * glows;
128
128
 
129
129
  float edge = voronoiRes.x;
130
130
  float smoothEdge = .02 / (2. * u_scale) * (1. + .5 * u_gap);
131
131
  edge = smoothstep(u_gap - smoothEdge, u_gap + smoothEdge, edge);
132
132
 
133
- color = mix(u_colorBack.rgb * u_colorBack.a, color, edge);
134
- opacity = mix(u_colorBack.a, opacity, edge);
133
+ color = mix(u_colorGap.rgb * u_colorGap.a, color, edge);
134
+ opacity = mix(u_colorGap.a, opacity, edge);
135
135
 
136
- fragColor = vec4(color, opacity);
136
+ fragColor = vec4(color, opacity);
137
137
  }
138
138
  `;
139
139
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/voronoi.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types';\nimport type { ShaderMotionParams } from '../shader-mount';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';\nimport { declarePI } from '../shader-utils';\n\nexport const voronoiMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Voronoi pattern by Ksenia Kondrashova\n * The variation of Voronoi pattern with cell edges. Big thanks to Inigo Quilez\n * https://www.shadertoy.com/view/ldl3W8\n *\n * Uniforms include:\n *\n * - `u_colors` (`vec4[]`): Array of RGBA colors used for cell filling\n * - `u_colorsCount` (`float`): Number of active colors in `u_colors`\n * - `u_colorBack` (`vec4`): RGBA color for the gaps between cells\n * - `u_colorGlow` (`vec4`): RGBA color for the radial shape on the cell edges\n * - `u_distortion` (`float`, 0 \u2013 0.5): Controls how far cell centers can be displaced from the regular grid\n * - `u_gap` (`float`): Width of the gaps between cells (gaps can't be removed completely due to artifacts of Voronoi cells)\n * - `u_innerGlow` (`float`): Controls the size of the radial glow inside each cell\n * - `u_stepsPerColor` (`float`): Discretization of the color transition\n * - `u_noiseTexture` (`sampler2D`): Replacement of standard hash function, added for better performance\n */\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_colorBack;\nuniform float u_distortion;\nuniform float u_gap;\nuniform float u_innerGlow;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nvec2 hash(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).gb;\n}\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 raw_hash = hash(ip + g);\n vec2 o = hash(ip + g);\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.x;\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 = hash(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 *= .0125;\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 innerGlows = length(voronoiRes.yz * u_innerGlow + .1);\n innerGlows = pow(innerGlows, 1.5);\n\n vec3 color = mix(cellColor, u_colorGlow.rgb * u_colorGlow.a, u_colorGlow.a * innerGlows);\n float opacity = cellOpacity + u_colorGlow.a * innerGlows;\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_colorBack.rgb * u_colorBack.a, color, edge);\n opacity = mix(u_colorBack.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_colorBack: [number, number, number, number];\n u_colorGlow: [number, number, number, number];\n u_distortion: number;\n u_gap: number;\n u_innerGlow: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface VoronoiParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n stepsPerColor?: number;\n colorBack?: string;\n colorGlow?: string;\n distortion?: number;\n gap?: number;\n innerGlow?: number;\n}\n"],
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 } from '../shader-utils.js';\n\nexport const voronoiMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Voronoi pattern by Ksenia Kondrashova\n * The variation of Voronoi pattern with cell edges. Big thanks to Inigo Quilez\n * https://www.shadertoy.com/view/ldl3W8\n *\n * Uniforms include:\n *\n * - `u_colors` (`vec4[]`): Array of RGBA colors used for cell filling\n * - `u_colorsCount` (`float`): Number of active colors in `u_colors`\n * - `u_colorBack` (`vec4`): RGBA color for the gaps between cells\n * - `u_colorGlow` (`vec4`): RGBA color for the radial shape on the cell edges\n * - `u_distortion` (`float`, 0 \u2013 0.5): Controls how far cell centers can be displaced from the regular grid\n * - `u_gap` (`float`): Width of the gaps between cells (gaps can't be removed completely due to artifacts of Voronoi cells)\n * - `u_glow` (`float`): Controls the size of the radial glow inside each cell\n * - `u_stepsPerColor` (`float`): Discretization of the color transition\n * - `u_noiseTexture` (`sampler2D`): Replacement of standard hash function, added for better performance\n */\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\nvec2 hash(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).gb;\n}\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 raw_hash = hash(ip + g);\n vec2 o = hash(ip + g);\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.x;\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 = hash(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 *= .0125;\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 + .1);\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
5
  "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,iBAAiB;AAEnB,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAmBO,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAgEa,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;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
- import type { vec4 } from '../types';
2
- import type { ShaderMotionParams } from '../shader-mount';
3
- import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';
1
+ import type { vec4 } from '../types.js';
2
+ import type { ShaderMotionParams } from '../shader-mount.js';
3
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
4
4
  export declare const warpMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
@@ -3,8 +3,8 @@
3
3
  * https://github.com/paper-design/shaders *
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
- import { sizingVariablesDeclaration } from "../shader-sizing";
7
- import { declarePI, declareRandom, declareRotate, colorBandingFix } from "../shader-utils";
6
+ import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
+ import { declarePI, declareRandom, declareRotate, colorBandingFix } from "../shader-utils.js";
8
8
  const warpMeta = {
9
9
  maxColorCount: 10
10
10
  };
@@ -33,7 +33,7 @@ ${declarePI}
33
33
  ${declareRandom}
34
34
  ${declareRotate}
35
35
 
36
- float noise(vec2 st) {
36
+ float valueNoise(vec2 st) {
37
37
  vec2 i = floor(st);
38
38
  vec2 f = fract(st);
39
39
  float a = random(i);
@@ -53,54 +53,58 @@ float noise(vec2 st) {
53
53
  }
54
54
 
55
55
  void main() {
56
- vec2 shape_uv = v_patternUV;
57
- shape_uv *= .005;
56
+ vec2 uv = v_patternUV;
57
+ uv *= .005;
58
58
 
59
59
  float t = .01 * u_time;
60
60
 
61
61
  float noise_scale = .0005 + .006 * u_scale;
62
62
 
63
- float n1 = noise(shape_uv * 1. + t);
64
- float n2 = noise(shape_uv * 2. - t);
63
+ float n1 = valueNoise(uv * 1. + t);
64
+ float n2 = valueNoise(uv * 2. - t);
65
65
  float angle = n1 * TWO_PI;
66
- shape_uv.x += 4. * u_distortion * n2 * cos(angle);
67
- shape_uv.y += 4. * u_distortion * n2 * sin(angle);
66
+ uv.x += 4. * u_distortion * n2 * cos(angle);
67
+ uv.y += 4. * u_distortion * n2 * sin(angle);
68
68
 
69
- float iterations_number = ceil(clamp(u_swirlIterations, 1., 30.));
70
- for (float i = 1.; i <= iterations_number; i++) {
71
- shape_uv.x += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1.5 * shape_uv.y);
72
- shape_uv.y += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1. * shape_uv.x);
69
+ float iterationsNumber = ceil(clamp(u_swirlIterations, 1., 30.));
70
+ for (float i = 1.; i <= iterationsNumber; i++) {
71
+ uv.x += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1.5 * uv.y);
72
+ uv.y += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1. * uv.x);
73
73
  }
74
74
 
75
75
  float proportion = clamp(u_proportion, 0., 1.);
76
76
 
77
77
  float shape = 0.;
78
78
  if (u_shape < .5) {
79
- vec2 checks_shape_uv = shape_uv * (.5 + 3.5 * u_shapeScale);
80
- shape = .5 + .5 * sin(checks_shape_uv.x) * cos(checks_shape_uv.y);
79
+ vec2 checksShape_uv = uv * (.5 + 3.5 * u_shapeScale);
80
+ shape = .5 + .5 * sin(checksShape_uv.x) * cos(checksShape_uv.y);
81
81
  shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);
82
82
  } else if (u_shape < 1.5) {
83
- vec2 stripes_shape_uv = shape_uv * (2. * u_shapeScale);
84
- float f = fract(stripes_shape_uv.y);
83
+ vec2 stripesShape_uv = uv * (2. * u_shapeScale);
84
+ float f = fract(stripesShape_uv.y);
85
85
  shape = smoothstep(.0, .55, f) * smoothstep(1., .45, f);
86
86
  shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);
87
87
  } else {
88
- float sh = 1. - shape_uv.y;
89
- float shape_scaling = 5. * (1. - u_shapeScale);
90
- shape = smoothstep(.45 - shape_scaling, .55 + shape_scaling, sh + .3 * (proportion - .5));
88
+ float shapeScaling = 5. * (1. - u_shapeScale);
89
+ shape = smoothstep(.45 - shapeScaling, .55 + shapeScaling, 1. - uv.y + .3 * (proportion - .5));
91
90
  }
92
91
 
93
92
  float mixer = shape * (u_colorsCount - 1.);
94
- mixer = (shape - .5 / u_colorsCount) * u_colorsCount;
95
93
  vec4 gradient = u_colors[0];
96
94
  gradient.rgb *= gradient.a;
97
95
  for (int i = 1; i < ${warpMeta.maxColorCount}; i++) {
98
- if (i >= int(u_colorsCount)) break;
99
- float localT = clamp(mixer - float(i - 1), 0.0, 1.0);
100
- localT = smoothstep(.5 - .5 * u_softness, .5 + .5 * u_softness, localT);
101
- vec4 c = u_colors[i];
102
- c.rgb *= c.a;
103
- gradient = mix(gradient, c, localT);
96
+ if (i >= int(u_colorsCount)) break;
97
+ float localMixer = clamp(mixer - float(i - 1), 0.0, 1.0);
98
+
99
+ float localMixerStart = floor(localMixer);
100
+ float smoothed = smoothstep(.5 - u_softness * .5, .5 + u_softness * .5, localMixer - localMixerStart);
101
+ float localTStepped = localMixerStart + smoothed;
102
+
103
+ localMixer = mix(localTStepped, localMixer, u_softness);
104
+
105
+ vec4 c = u_colors[i];
106
+ c.rgb *= c.a;
107
+ gradient = mix(gradient, c, localMixer);
104
108
  }
105
109
 
106
110
  vec3 color = gradient.rgb;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/warp.ts"],
4
- "sourcesContent": ["import type { vec4 } from '../types';\nimport type { ShaderMotionParams } from '../shader-mount';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';\nimport { declarePI, declareRandom, declareRotate, colorBandingFix } from '../shader-utils';\n\nexport const warpMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * 3d Perlin noise with exposed parameters\n *\n * Uniforms include:\n * - u_colors (vec4[]): Input RGBA colors\n * - u_colorsCount (float): Number of active colors (`u_colors` length)\n * - u_proportion (0 .. 1): the proportion between colors (on 0.5 colors are equally distributed)\n * - u_softness (0 .. 1): the color blur (0 for pronounced edges, 1 for gradient)\n * - u_shape (0 ... 2): the color pattern to be distorted with noise & swirl\n * - u_shape = 0 is checks\n * - u_shape = 1 is stripes\n * - u_shape = 2 is 2 halves of canvas (mapping the canvas height regardless of resolution)\n * - u_shapeScale: the scale of color pattern (appies over the global scaling)\n * - u_distortion: the noisy distortion over the UV coordinate (applied before the overlapping swirl)\n * - u_swirl: the power of swirly distortion\n * - u_swirlIterations: the number of swirl iterations (layering curves effect)\n *\n */\nexport const warpFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform float u_scale;\nuniform vec2 u_resolution;\n\nuniform vec4 u_colors[${warpMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_shape;\nuniform float u_shapeScale;\nuniform float u_distortion;\nuniform float u_swirl;\nuniform float u_swirlIterations;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n\nfloat noise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smoothstep for interpolation\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n // Do the interpolation as two nested mix operations\n // If you try to do this in one big operation, there's enough precision loss to be off by 1px at cell boundaries\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}\n\nvoid main() {\n vec2 shape_uv = v_patternUV;\n shape_uv *= .005;\n\n float t = .01 * u_time;\n\n float noise_scale = .0005 + .006 * u_scale;\n\n float n1 = noise(shape_uv * 1. + t);\n float n2 = noise(shape_uv * 2. - t);\n float angle = n1 * TWO_PI;\n shape_uv.x += 4. * u_distortion * n2 * cos(angle);\n shape_uv.y += 4. * u_distortion * n2 * sin(angle);\n\n float iterations_number = ceil(clamp(u_swirlIterations, 1., 30.));\n for (float i = 1.; i <= iterations_number; i++) {\n shape_uv.x += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1.5 * shape_uv.y);\n shape_uv.y += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1. * shape_uv.x);\n }\n\n float proportion = clamp(u_proportion, 0., 1.);\n\n float shape = 0.;\n if (u_shape < .5) {\n vec2 checks_shape_uv = shape_uv * (.5 + 3.5 * u_shapeScale);\n shape = .5 + .5 * sin(checks_shape_uv.x) * cos(checks_shape_uv.y);\n shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);\n } else if (u_shape < 1.5) {\n vec2 stripes_shape_uv = shape_uv * (2. * u_shapeScale);\n float f = fract(stripes_shape_uv.y);\n shape = smoothstep(.0, .55, f) * smoothstep(1., .45, f);\n shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);\n } else {\n float sh = 1. - shape_uv.y;\n float shape_scaling = 5. * (1. - u_shapeScale);\n shape = smoothstep(.45 - shape_scaling, .55 + shape_scaling, sh + .3 * (proportion - .5));\n }\n\n float mixer = shape * (u_colorsCount - 1.);\n mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${warpMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0.0, 1.0);\n localT = smoothstep(.5 - .5 * u_softness, .5 + .5 * u_softness, localT);\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n vec3 color = gradient.rgb;\n float opacity = gradient.a;\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface WarpUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_proportion: number;\n u_softness: number;\n u_shape: (typeof WarpPatterns)[WarpPattern];\n u_shapeScale: number;\n u_distortion: number;\n u_swirl: number;\n u_swirlIterations: number;\n}\n\nexport interface WarpParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n rotation?: number;\n proportion?: number;\n softness?: number;\n shape?: WarpPattern;\n shapeScale?: number;\n distortion?: number;\n swirl?: number;\n swirlIterations?: number;\n}\n\nexport const WarpPatterns = {\n checks: 0,\n stripes: 1,\n edge: 2,\n} as const;\n\nexport type WarpPattern = keyof typeof WarpPatterns;\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,eAAe,uBAAuB;AAElE,MAAM,WAAW;AAAA,EACtB,eAAe;AACjB;AAoBO,MAAM,qBAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAOlB,SAAS,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU5C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA+DS,SAAS,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAY1C,eAAe;AAAA;AAAA;AAAA;AAAA;AA8BZ,MAAM,eAAe;AAAA,EAC1B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR;",
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, declareRandom, declareRotate, colorBandingFix } from '../shader-utils.js';\n\nexport const warpMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * 3d Perlin noise with exposed parameters\n *\n * Uniforms include:\n * - u_colors (vec4[]): Input RGBA colors\n * - u_colorsCount (float): Number of active colors (`u_colors` length)\n * - u_proportion (0 .. 1): the proportion between colors (on 0.5 colors are equally distributed)\n * - u_softness (0 .. 1): the color blur (0 for pronounced edges, 1 for gradient)\n * - u_shape (0 ... 2): the color pattern to be distorted with noise & swirl\n * - u_shape = 0 is checks\n * - u_shape = 1 is stripes\n * - u_shape = 2 is 2 halves of canvas (mapping the canvas height regardless of resolution)\n * - u_shapeScale: the scale of color pattern (appies over the global scaling)\n * - u_distortion: the noisy distortion over the UV coordinate (applied before the overlapping swirl)\n * - u_swirl: the power of swirly distortion\n * - u_swirlIterations: the number of swirl iterations (layering curves effect)\n *\n */\nexport const warpFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform float u_scale;\nuniform vec2 u_resolution;\n\nuniform vec4 u_colors[${warpMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_proportion;\nuniform float u_softness;\nuniform float u_shape;\nuniform float u_shapeScale;\nuniform float u_distortion;\nuniform float u_swirl;\nuniform float u_swirlIterations;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smoothstep for interpolation\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n // Do the interpolation as two nested mix operations\n // If you try to do this in one big operation, there's enough precision loss to be off by 1px at cell boundaries\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}\n\nvoid main() {\n vec2 uv = v_patternUV;\n uv *= .005;\n\n float t = .01 * u_time;\n\n float noise_scale = .0005 + .006 * u_scale;\n\n float n1 = valueNoise(uv * 1. + t);\n float n2 = valueNoise(uv * 2. - t);\n float angle = n1 * TWO_PI;\n uv.x += 4. * u_distortion * n2 * cos(angle);\n uv.y += 4. * u_distortion * n2 * sin(angle);\n\n float iterationsNumber = ceil(clamp(u_swirlIterations, 1., 30.));\n for (float i = 1.; i <= iterationsNumber; i++) {\n uv.x += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1.5 * uv.y);\n uv.y += clamp(u_swirl, 0., 2.) / i * cos(t + i * 1. * uv.x);\n }\n\n float proportion = clamp(u_proportion, 0., 1.);\n\n float shape = 0.;\n if (u_shape < .5) {\n vec2 checksShape_uv = uv * (.5 + 3.5 * u_shapeScale);\n shape = .5 + .5 * sin(checksShape_uv.x) * cos(checksShape_uv.y);\n shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);\n } else if (u_shape < 1.5) {\n vec2 stripesShape_uv = uv * (2. * u_shapeScale);\n float f = fract(stripesShape_uv.y);\n shape = smoothstep(.0, .55, f) * smoothstep(1., .45, f);\n shape += .48 * sign(proportion - .5) * pow(abs(proportion - .5), .5);\n } else {\n float shapeScaling = 5. * (1. - u_shapeScale);\n shape = smoothstep(.45 - shapeScaling, .55 + shapeScaling, 1. - uv.y + .3 * (proportion - .5));\n }\n\n float mixer = shape * (u_colorsCount - 1.);\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${warpMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localMixer = clamp(mixer - float(i - 1), 0.0, 1.0);\n\n float localMixerStart = floor(localMixer);\n float smoothed = smoothstep(.5 - u_softness * .5, .5 + u_softness * .5, localMixer - localMixerStart);\n float localTStepped = localMixerStart + smoothed;\n\n localMixer = mix(localTStepped, localMixer, u_softness);\n\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localMixer);\n }\n\n vec3 color = gradient.rgb;\n float opacity = gradient.a;\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface WarpUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_proportion: number;\n u_softness: number;\n u_shape: (typeof WarpPatterns)[WarpPattern];\n u_shapeScale: number;\n u_distortion: number;\n u_swirl: number;\n u_swirlIterations: number;\n}\n\nexport interface WarpParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n rotation?: number;\n proportion?: number;\n softness?: number;\n shape?: WarpPattern;\n shapeScale?: number;\n distortion?: number;\n swirl?: number;\n swirlIterations?: number;\n}\n\nexport const WarpPatterns = {\n checks: 0,\n stripes: 1,\n edge: 2,\n} as const;\n\nexport type WarpPattern = keyof typeof WarpPatterns;\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,eAAe,uBAAuB;AAElE,MAAM,WAAW;AAAA,EACtB,eAAe;AACjB;AAoBO,MAAM,qBAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAOlB,SAAS,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU5C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA6DS,SAAS,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkB1C,eAAe;AAAA;AAAA;AAAA;AAAA;AA8BZ,MAAM,eAAe;AAAA,EAC1B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,10 +1,10 @@
1
- import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing';
1
+ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
2
2
  /**
3
3
  * Waves static pattern on the transparent background
4
4
  *
5
5
  * Uniforms include:
6
- * u_color1 - the first color
7
- * u_color2 - the second color
6
+ * u_colorFront - the first color
7
+ * u_colorBack - the second color
8
8
  * u_shape (0 ... 3) - the line shaping coefficient, non-integer
9
9
  values allowed and produce mixed shapes
10
10
  - u_shape = 0 is zigzag
@@ -19,8 +19,8 @@ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-si
19
19
  */
20
20
  export declare const wavesFragmentShader: string;
21
21
  export interface WavesUniforms extends ShaderSizingUniforms {
22
- u_color1: [number, number, number, number];
23
- u_color2: [number, number, number, number];
22
+ u_colorFront: [number, number, number, number];
23
+ u_colorBack: [number, number, number, number];
24
24
  u_shape: number;
25
25
  u_frequency: number;
26
26
  u_amplitude: number;
@@ -29,8 +29,8 @@ export interface WavesUniforms extends ShaderSizingUniforms {
29
29
  u_softness: number;
30
30
  }
31
31
  export interface WavesParams extends ShaderSizingParams {
32
- color1?: string;
33
- color2?: string;
32
+ colorFront?: string;
33
+ colorBack?: string;
34
34
  rotation?: number;
35
35
  shape?: number;
36
36
  frequency?: number;