@paper-design/shaders 0.0.31 → 0.0.33

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 (52) hide show
  1. package/dist/shader-utils.d.ts +1 -0
  2. package/dist/shader-utils.js +16 -1
  3. package/dist/shader-utils.js.map +2 -2
  4. package/dist/shaders/color-panels.d.ts +11 -12
  5. package/dist/shaders/color-panels.js +1 -4
  6. package/dist/shaders/color-panels.js.map +2 -2
  7. package/dist/shaders/dithering.d.ts +18 -23
  8. package/dist/shaders/dithering.js.map +2 -2
  9. package/dist/shaders/dot-grid.d.ts +15 -13
  10. package/dist/shaders/dot-grid.js +1 -0
  11. package/dist/shaders/dot-grid.js.map +2 -2
  12. package/dist/shaders/dot-orbit.d.ts +9 -11
  13. package/dist/shaders/dot-orbit.js.map +2 -2
  14. package/dist/shaders/god-rays.d.ts +11 -15
  15. package/dist/shaders/god-rays.js +11 -26
  16. package/dist/shaders/god-rays.js.map +2 -2
  17. package/dist/shaders/grain-gradient.d.ts +19 -1
  18. package/dist/shaders/grain-gradient.js +4 -21
  19. package/dist/shaders/grain-gradient.js.map +2 -2
  20. package/dist/shaders/liquid-metal.d.ts +17 -0
  21. package/dist/shaders/liquid-metal.js +2 -2
  22. package/dist/shaders/liquid-metal.js.map +2 -2
  23. package/dist/shaders/mesh-gradient.d.ts +7 -7
  24. package/dist/shaders/mesh-gradient.js.map +2 -2
  25. package/dist/shaders/metaballs.d.ts +8 -8
  26. package/dist/shaders/metaballs.js.map +2 -2
  27. package/dist/shaders/neuro-noise.d.ts +7 -9
  28. package/dist/shaders/neuro-noise.js.map +2 -2
  29. package/dist/shaders/perlin-noise.d.ts +9 -13
  30. package/dist/shaders/perlin-noise.js.map +2 -2
  31. package/dist/shaders/pulsing-border.d.ts +14 -15
  32. package/dist/shaders/pulsing-border.js +12 -19
  33. package/dist/shaders/pulsing-border.js.map +2 -2
  34. package/dist/shaders/simplex-noise.d.ts +7 -9
  35. package/dist/shaders/simplex-noise.js.map +2 -2
  36. package/dist/shaders/smoke-ring.d.ts +8 -11
  37. package/dist/shaders/smoke-ring.js +4 -21
  38. package/dist/shaders/smoke-ring.js.map +2 -2
  39. package/dist/shaders/spiral.d.ts +10 -16
  40. package/dist/shaders/spiral.js +1 -0
  41. package/dist/shaders/spiral.js.map +2 -2
  42. package/dist/shaders/swirl.d.ts +10 -0
  43. package/dist/shaders/swirl.js +14 -16
  44. package/dist/shaders/swirl.js.map +2 -2
  45. package/dist/shaders/voronoi.d.ts +13 -13
  46. package/dist/shaders/voronoi.js.map +2 -2
  47. package/dist/shaders/warp.d.ts +12 -14
  48. package/dist/shaders/warp.js +2 -22
  49. package/dist/shaders/warp.js.map +2 -2
  50. package/dist/shaders/waves.d.ts +13 -16
  51. package/dist/shaders/waves.js.map +2 -2
  52. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  export declare const declarePI = "\n#define TWO_PI 6.28318530718\n#define PI 3.14159265358979323846\n";
2
2
  export declare const declareRotate = "\nvec2 rotate(vec2 uv, float th) {\n return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;\n}\n";
3
3
  export declare const declareRandom = "\nfloat random(vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);\n}\n";
4
+ export declare const declareValueNoise = "\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 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";
4
5
  export declare const colorBandingFix = "\n color += 1. / 256. * (fract(sin(dot(.014 * gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453123) - .5);\n";
5
6
  export declare const declareSimplexNoise = "\nvec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n";
@@ -17,6 +17,20 @@ float random(vec2 st) {
17
17
  return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
18
18
  }
19
19
  `;
20
+ const declareValueNoise = `
21
+ float valueNoise(vec2 st) {
22
+ vec2 i = floor(st);
23
+ vec2 f = fract(st);
24
+ float a = random(i);
25
+ float b = random(i + vec2(1.0, 0.0));
26
+ float c = random(i + vec2(0.0, 1.0));
27
+ float d = random(i + vec2(1.0, 1.0));
28
+ vec2 u = f * f * (3.0 - 2.0 * f);
29
+ float x1 = mix(a, b, u.x);
30
+ float x2 = mix(c, d, u.x);
31
+ return mix(x1, x2, u.y);
32
+ }
33
+ `;
20
34
  const colorBandingFix = `
21
35
  color += 1. / 256. * (fract(sin(dot(.014 * gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453123) - .5);
22
36
  `;
@@ -54,6 +68,7 @@ export {
54
68
  declarePI,
55
69
  declareRandom,
56
70
  declareRotate,
57
- declareSimplexNoise
71
+ declareSimplexNoise,
72
+ declareValueNoise
58
73
  };
59
74
  //# sourceMappingURL=shader-utils.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/shader-utils.ts"],
4
- "sourcesContent": ["export const declarePI = `\n#define TWO_PI 6.28318530718\n#define PI 3.14159265358979323846\n`;\n\nexport const declareRotate = `\nvec2 rotate(vec2 uv, float th) {\n return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;\n}\n`;\n\nexport const declareRandom = `\nfloat random(vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);\n}\n`;\n\n// It does use the standard random function but we don't call it to keep\n// colorBandingFix insertion independent from declareRandom\nexport const colorBandingFix = `\n color += 1. / 256. * (fract(sin(dot(.014 * gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453123) - .5);\n`;\n\nexport const declareSimplexNoise = `\nvec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n`;\n"],
5
- "mappings": ";;;;;AAAO,MAAM,YAAY;AAAA;AAAA;AAAA;AAKlB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAMtB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAQtB,MAAM,kBAAkB;AAAA;AAAA;AAIxB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;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": ["export const declarePI = `\n#define TWO_PI 6.28318530718\n#define PI 3.14159265358979323846\n`;\n\nexport const declareRotate = `\nvec2 rotate(vec2 uv, float th) {\n return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;\n}\n`;\n\nexport const declareRandom = `\nfloat random(vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);\n}\n`;\n\nexport const declareValueNoise = `\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 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`;\n\n// It does use the standard random function but we don't call it to keep\n// colorBandingFix insertion independent from declareRandom\nexport const colorBandingFix = `\n color += 1. / 256. * (fract(sin(dot(.014 * gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453123) - .5);\n`;\n\nexport const declareSimplexNoise = `\nvec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n`;\n"],
5
+ "mappings": ";;;;;AAAO,MAAM,YAAY;AAAA;AAAA;AAAA;AAKlB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAMtB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAMtB,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB1B,MAAM,kBAAkB;AAAA;AAAA;AAIxB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;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,20 +5,19 @@ export declare const colorPanelsMeta: {
5
5
  readonly maxColorCount: 7;
6
6
  };
7
7
  /**
8
- * Animated, pseudo-3D color panels with dynamic layering and directional blur
9
- * by Ksenia Kondrashova
8
+ * Pseudo-3D panels rotating around a central axis
10
9
  *
11
10
  * Uniforms include:
12
- * - u_colors (vec4[]): Input RGBA colors for panels
13
- * - u_colorsCount (float): Number of active colors (`u_colors` length)
14
- * - u_density (float): Panels to show
15
- * - u_colorBack (vec4): Background color to blend behind panels
16
- * - u_angle (float): Panel skew angle to morph rect to triangle panels
17
- * - u_length (float): Length of panels (relative to total height)
18
- * - u_blur (float): Horizontal blur amount along panel edges
19
- * - u_fadePosition (float): Controls transparency toward the center of panels
20
- * - u_colorShuffler (float): Affects how panel colors cycle
21
- * - u_singleColor (float): Controls blending of adjacent colors per panel
11
+ * - u_colorBack (RGBA)
12
+ * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
+ * - u_density: angle between every 2 panels
14
+ * - u_angle1, u_angle2: skew angle applied to all panes
15
+ * - u_length: panel length (relative to total height)
16
+ * - u_blur: side blur (0 for sharp edges)
17
+ * - u_fadeIn: transparency near central axis
18
+ * - u_fadeOut: transparency near viewer
19
+ * - u_gradient: color mixing within panes (0 = single color, 1 = two colors)
20
+ *
22
21
  */
23
22
  export declare const colorPanelsFragmentShader: string;
24
23
  export interface ColorPanelsUniforms extends ShaderSizingUniforms {
@@ -11,21 +11,18 @@ const colorPanelsMeta = {
11
11
  const colorPanelsFragmentShader = `#version 300 es
12
12
  precision lowp float;
13
13
 
14
- uniform vec2 u_resolution;
15
-
16
14
  uniform float u_time;
17
- uniform float u_scale;
18
15
 
19
16
  uniform vec4 u_colors[${colorPanelsMeta.maxColorCount}];
20
17
  uniform float u_colorsCount;
21
18
  uniform vec4 u_colorBack;
19
+ uniform float u_density;
22
20
  uniform float u_angle1;
23
21
  uniform float u_angle2;
24
22
  uniform float u_length;
25
23
  uniform float u_blur;
26
24
  uniform float u_fadeIn;
27
25
  uniform float u_fadeOut;
28
- uniform float u_density;
29
26
  uniform float u_gradient;
30
27
 
31
28
  ${sizingVariablesDeclaration}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/color-panels.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, colorBandingFix } from '../shader-utils.js';\n\nexport const colorPanelsMeta = {\n maxColorCount: 7,\n} as const;\n\n/**\n * Animated, pseudo-3D color panels with dynamic layering and directional blur\n * by Ksenia Kondrashova\n *\n * Uniforms include:\n * - u_colors (vec4[]): Input RGBA colors for panels\n * - u_colorsCount (float): Number of active colors (`u_colors` length)\n * - u_density (float): Panels to show\n * - u_colorBack (vec4): Background color to blend behind panels\n * - u_angle (float): Panel skew angle to morph rect to triangle panels\n * - u_length (float): Length of panels (relative to total height)\n * - u_blur (float): Horizontal blur amount along panel edges\n * - u_fadePosition (float): Controls transparency toward the center of panels\n * - u_colorShuffler (float): Affects how panel colors cycle\n * - u_singleColor (float): Controls blending of adjacent colors per panel\n */\n\nexport const colorPanelsFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform vec2 u_resolution;\n\nuniform float u_time;\nuniform float u_scale;\n\nuniform vec4 u_colors[${colorPanelsMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform vec4 u_colorBack;\nuniform float u_angle1;\nuniform float u_angle2;\nuniform float u_length;\nuniform float u_blur;\nuniform float u_fadeIn;\nuniform float u_fadeOut;\nuniform float u_density;\nuniform float u_gradient;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nvec2 getPanel(float angle, vec2 uv, float invLength) {\n float sinA = sin(angle);\n float cosA = cos(angle);\n\n float denom = sinA - uv.y * cosA;\n if (abs(denom) < 1e-5) return vec2(0.);\n\n float z = uv.y / denom;\n float zLimit = 0.5;\n\n if (z < 0. || z > zLimit) return vec2(0.);\n\n float zRatio = z / zLimit;\n float panelMap = 1.0 - zRatio;\n float x = uv.x * (cosA * z + 1.) * invLength;\n\n float zOffset = zRatio - .5;\n float left = -.5 + zOffset * u_angle1;\n float right = .5 - zOffset * u_angle2;\n\n float blurFactor = (1. - panelMap) * clamp((abs(angle / TWO_PI - .5) - .01) / (-.01), 0., 1.);;\n float blurX = .15 * blurFactor + panelMap * u_blur;\n\n float leftEdge1 = left - .5 * blurX;\n float leftEdge2 = left + blurX;\n float rightEdge1 = right - blurX;\n float rightEdge2 = right + .5 * blurX;\n\n float panel = smoothstep(leftEdge1, leftEdge2, x) * (1.0 - smoothstep(rightEdge1, rightEdge2, x));\n\n return vec2(panel, clamp(panelMap, 0., 1.));\n}\n\nvec4 blendColor(vec4 colorA, float panelMask, float panelMap) {\n float fade = smoothstep(-.2 * (1. - u_fadeOut), u_fadeOut, panelMap)\n * (1. - smoothstep(1. - u_fadeIn, 1., panelMap));\n\n vec3 blendedRGB = mix(vec3(0.), colorA.rgb, fade);\n float blendedAlpha = mix(0., colorA.a, fade);\n\n return vec4(blendedRGB, blendedAlpha) * panelMask;\n}\n\nvoid main() {\n vec2 uv = v_objectUV;\n uv *= 1.25;\n\n float t = .05 * u_time;\n t = fract(t);\n bool reverseTime = (t < 0.5);\n\n vec3 color = vec3(0.);\n float opacity = 0.;\n\n int colorsCount = int(u_colorsCount);\n\n vec4 premultipliedColors[${colorPanelsMeta.maxColorCount}];\n for (int i = 0; i < ${colorPanelsMeta.maxColorCount}; i++) {\n if (i >= colorsCount) break;\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n premultipliedColors[i] = c;\n }\n\n float invLength = 1.5 / (u_length + 0.001);\n\n float totalColorWeight = 0.;\n int panelsNumber = 12;\n\n float densityNormalizer = 1.;\n if (colorsCount == 4) {\n panelsNumber = 16;\n densityNormalizer = 1.34;\n } else if (colorsCount == 5) {\n panelsNumber = 20;\n densityNormalizer = 1.67;\n } else if (colorsCount == 7) {\n panelsNumber = 14;\n densityNormalizer = 1.17;\n }\n\n float fPanelsNumber = float(panelsNumber);\n\n float totalPanelsShape = 0.;\n float panelGrad = 1. - clamp(u_gradient, 0., 1.);\n\n for (int set = 0; set < 2; set++) {\n bool isForward = (set == 0 && !reverseTime) || (set == 1 && reverseTime);\n if (!isForward) continue;\n\n for (int i = 0; i <= 20; i++) {\n if (i >= panelsNumber) break;\n\n int idx = panelsNumber - 1 - i;\n\n float offset = float(idx) / fPanelsNumber;\n if (set == 1) {\n offset += .5;\n }\n\n float densityFract = densityNormalizer * fract(t + offset);\n float angleNorm = densityFract / u_density;\n if (densityFract >= .5 || angleNorm >= .3) continue;\n\n float smoothDensity = clamp((.5 - densityFract) / .1, 0., 1.) * clamp(densityFract / .01, 0., 1.);\n float smoothAngle = clamp((.3 - angleNorm) / .05, 0., 1.);\n if (smoothDensity * smoothAngle < .001) continue;\n\n vec2 panel = getPanel(angleNorm * TWO_PI + PI, uv, invLength);\n float panelMask = panel[0] * smoothDensity * smoothAngle;\n if (panelMask <= .001) continue;\n float panelMap = panel[1];\n\n int colorIdx = idx % colorsCount;\n int nextColorIdx = (idx + 1) % colorsCount;\n\n vec4 colorA = premultipliedColors[colorIdx];\n vec4 colorB = premultipliedColors[nextColorIdx];\n\n colorA = mix(colorA, colorB, max(0., smoothstep(.0, .45, panelMap) - panelGrad));\n vec4 blended = blendColor(colorA, panelMask, panelMap);\n color = blended.rgb + color * (1. - blended.a);\n opacity = blended.a + opacity * (1. - blended.a);\n }\n\n\n for (int i = 0; i <= 20; i++) {\n if (i >= panelsNumber) break;\n\n int idx = panelsNumber - 1 - i;\n\n float offset = float(idx) / fPanelsNumber;\n if (set == 0) {\n offset += .5;\n }\n\n float densityFract = densityNormalizer * fract(-t + offset);\n float angleNorm = -densityFract / u_density;\n if (densityFract >= .5 || angleNorm < -.3) continue;\n\n float smoothDensity = clamp((.5 - densityFract) / .1, 0., 1.) * clamp(densityFract / .01, 0., 1.);\n float smoothAngle = clamp((angleNorm + .3) / .05, 0., 1.);\n if (smoothDensity * smoothAngle < .001) continue;\n\n vec2 panel = getPanel(angleNorm * TWO_PI + PI, uv, invLength);\n float panelMask = panel[0] * smoothDensity * smoothAngle;\n if (panelMask <= .001) continue;\n float panelMap = panel[1];\n\n int colorIdx = (colorsCount - (idx % colorsCount)) % colorsCount;\n if (colorIdx < 0) colorIdx += colorsCount;\n int nextColorIdx = (colorIdx + 1) % colorsCount;\n\n vec4 colorA = premultipliedColors[colorIdx];\n vec4 colorB = premultipliedColors[nextColorIdx];\n\n colorA = mix(colorA, colorB, max(0., smoothstep(.0, .45, panelMap) - panelGrad));\n vec4 blended = blendColor(colorA, panelMask, panelMap);\n color = blended.rgb + color * (1. - blended.a);\n opacity = blended.a + opacity * (1. - blended.a);\n }\n }\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 ColorPanelsUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_colorBack: [number, number, number, number];\n u_angle1: number;\n u_angle2: number;\n u_length: number;\n u_blur: number;\n u_fadeIn: number;\n u_fadeOut: number;\n u_density: number;\n u_gradient: number;\n}\n\nexport interface ColorPanelsParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n colorBack?: string;\n angle1?: number;\n angle2?: number;\n length?: number;\n blur?: number;\n fadeIn?: number;\n fadeOut?: number;\n density?: number;\n gradient?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;AAEpC,MAAM,kBAAkB;AAAA,EAC7B,eAAe;AACjB;AAmBO,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQzB,gBAAgB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYnD,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,6BA0DkB,gBAAgB,aAAa;AAAA,wBAClC,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8GjD,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 { declarePI, colorBandingFix } from '../shader-utils.js';\n\nexport const colorPanelsMeta = {\n maxColorCount: 7,\n} as const;\n\n/**\n * Pseudo-3D panels rotating around a central axis\n *\n * Uniforms include:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_density: angle between every 2 panels\n * - u_angle1, u_angle2: skew angle applied to all panes\n * - u_length: panel length (relative to total height)\n * - u_blur: side blur (0 for sharp edges)\n * - u_fadeIn: transparency near central axis\n * - u_fadeOut: transparency near viewer\n * - u_gradient: color mixing within panes (0 = single color, 1 = two colors)\n *\n */\n\nexport const colorPanelsFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform float u_time;\n\nuniform vec4 u_colors[${colorPanelsMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform vec4 u_colorBack;\nuniform float u_density;\nuniform float u_angle1;\nuniform float u_angle2;\nuniform float u_length;\nuniform float u_blur;\nuniform float u_fadeIn;\nuniform float u_fadeOut;\nuniform float u_gradient;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nvec2 getPanel(float angle, vec2 uv, float invLength) {\n float sinA = sin(angle);\n float cosA = cos(angle);\n\n float denom = sinA - uv.y * cosA;\n if (abs(denom) < 1e-5) return vec2(0.);\n\n float z = uv.y / denom;\n float zLimit = 0.5;\n\n if (z < 0. || z > zLimit) return vec2(0.);\n\n float zRatio = z / zLimit;\n float panelMap = 1.0 - zRatio;\n float x = uv.x * (cosA * z + 1.) * invLength;\n\n float zOffset = zRatio - .5;\n float left = -.5 + zOffset * u_angle1;\n float right = .5 - zOffset * u_angle2;\n\n float blurFactor = (1. - panelMap) * clamp((abs(angle / TWO_PI - .5) - .01) / (-.01), 0., 1.);;\n float blurX = .15 * blurFactor + panelMap * u_blur;\n\n float leftEdge1 = left - .5 * blurX;\n float leftEdge2 = left + blurX;\n float rightEdge1 = right - blurX;\n float rightEdge2 = right + .5 * blurX;\n\n float panel = smoothstep(leftEdge1, leftEdge2, x) * (1.0 - smoothstep(rightEdge1, rightEdge2, x));\n\n return vec2(panel, clamp(panelMap, 0., 1.));\n}\n\nvec4 blendColor(vec4 colorA, float panelMask, float panelMap) {\n float fade = smoothstep(-.2 * (1. - u_fadeOut), u_fadeOut, panelMap)\n * (1. - smoothstep(1. - u_fadeIn, 1., panelMap));\n\n vec3 blendedRGB = mix(vec3(0.), colorA.rgb, fade);\n float blendedAlpha = mix(0., colorA.a, fade);\n\n return vec4(blendedRGB, blendedAlpha) * panelMask;\n}\n\nvoid main() {\n vec2 uv = v_objectUV;\n uv *= 1.25;\n\n float t = .05 * u_time;\n t = fract(t);\n bool reverseTime = (t < 0.5);\n\n vec3 color = vec3(0.);\n float opacity = 0.;\n\n int colorsCount = int(u_colorsCount);\n\n vec4 premultipliedColors[${colorPanelsMeta.maxColorCount}];\n for (int i = 0; i < ${colorPanelsMeta.maxColorCount}; i++) {\n if (i >= colorsCount) break;\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n premultipliedColors[i] = c;\n }\n\n float invLength = 1.5 / (u_length + 0.001);\n\n float totalColorWeight = 0.;\n int panelsNumber = 12;\n\n float densityNormalizer = 1.;\n if (colorsCount == 4) {\n panelsNumber = 16;\n densityNormalizer = 1.34;\n } else if (colorsCount == 5) {\n panelsNumber = 20;\n densityNormalizer = 1.67;\n } else if (colorsCount == 7) {\n panelsNumber = 14;\n densityNormalizer = 1.17;\n }\n\n float fPanelsNumber = float(panelsNumber);\n\n float totalPanelsShape = 0.;\n float panelGrad = 1. - clamp(u_gradient, 0., 1.);\n\n for (int set = 0; set < 2; set++) {\n bool isForward = (set == 0 && !reverseTime) || (set == 1 && reverseTime);\n if (!isForward) continue;\n\n for (int i = 0; i <= 20; i++) {\n if (i >= panelsNumber) break;\n\n int idx = panelsNumber - 1 - i;\n\n float offset = float(idx) / fPanelsNumber;\n if (set == 1) {\n offset += .5;\n }\n\n float densityFract = densityNormalizer * fract(t + offset);\n float angleNorm = densityFract / u_density;\n if (densityFract >= .5 || angleNorm >= .3) continue;\n\n float smoothDensity = clamp((.5 - densityFract) / .1, 0., 1.) * clamp(densityFract / .01, 0., 1.);\n float smoothAngle = clamp((.3 - angleNorm) / .05, 0., 1.);\n if (smoothDensity * smoothAngle < .001) continue;\n\n vec2 panel = getPanel(angleNorm * TWO_PI + PI, uv, invLength);\n float panelMask = panel[0] * smoothDensity * smoothAngle;\n if (panelMask <= .001) continue;\n float panelMap = panel[1];\n\n int colorIdx = idx % colorsCount;\n int nextColorIdx = (idx + 1) % colorsCount;\n\n vec4 colorA = premultipliedColors[colorIdx];\n vec4 colorB = premultipliedColors[nextColorIdx];\n\n colorA = mix(colorA, colorB, max(0., smoothstep(.0, .45, panelMap) - panelGrad));\n vec4 blended = blendColor(colorA, panelMask, panelMap);\n color = blended.rgb + color * (1. - blended.a);\n opacity = blended.a + opacity * (1. - blended.a);\n }\n\n\n for (int i = 0; i <= 20; i++) {\n if (i >= panelsNumber) break;\n\n int idx = panelsNumber - 1 - i;\n\n float offset = float(idx) / fPanelsNumber;\n if (set == 0) {\n offset += .5;\n }\n\n float densityFract = densityNormalizer * fract(-t + offset);\n float angleNorm = -densityFract / u_density;\n if (densityFract >= .5 || angleNorm < -.3) continue;\n\n float smoothDensity = clamp((.5 - densityFract) / .1, 0., 1.) * clamp(densityFract / .01, 0., 1.);\n float smoothAngle = clamp((angleNorm + .3) / .05, 0., 1.);\n if (smoothDensity * smoothAngle < .001) continue;\n\n vec2 panel = getPanel(angleNorm * TWO_PI + PI, uv, invLength);\n float panelMask = panel[0] * smoothDensity * smoothAngle;\n if (panelMask <= .001) continue;\n float panelMap = panel[1];\n\n int colorIdx = (colorsCount - (idx % colorsCount)) % colorsCount;\n if (colorIdx < 0) colorIdx += colorsCount;\n int nextColorIdx = (colorIdx + 1) % colorsCount;\n\n vec4 colorA = premultipliedColors[colorIdx];\n vec4 colorB = premultipliedColors[nextColorIdx];\n\n colorA = mix(colorA, colorB, max(0., smoothstep(.0, .45, panelMap) - panelGrad));\n vec4 blended = blendColor(colorA, panelMask, panelMap);\n color = blended.rgb + color * (1. - blended.a);\n opacity = blended.a + opacity * (1. - blended.a);\n }\n }\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 ColorPanelsUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_colorBack: [number, number, number, number];\n u_angle1: number;\n u_angle2: number;\n u_length: number;\n u_blur: number;\n u_fadeIn: number;\n u_fadeOut: number;\n u_density: number;\n u_gradient: number;\n}\n\nexport interface ColorPanelsParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n colorBack?: string;\n angle1?: number;\n angle2?: number;\n length?: number;\n blur?: number;\n fadeIn?: number;\n fadeOut?: number;\n density?: number;\n gradient?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;AAEpC,MAAM,kBAAkB;AAAA,EAC7B,eAAe;AACjB;AAkBO,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKzB,gBAAgB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYnD,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,6BA0DkB,gBAAgB,aAAa;AAAA,wBAClC,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8GjD,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,31 +1,26 @@
1
1
  import type { ShaderMotionParams } from '../shader-mount.js';
2
2
  import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
3
3
  /**
4
- * Dithering Fragment Shader by Ksenia Kondrashova
5
- * Applies dithering (4 dithering types available) over the
6
- * abstract shapes animation (7 animated shapes available)
4
+ * 2-color dithering effect over animated abstract shapes
7
5
  *
8
- * Uniforms include:
9
- * - u_colorBack: background color, RGBA
10
- * - u_colorFront: pixels color, RGBA
11
- *
12
- * - u_shape (float, used as int, 1 to 7):
13
- * --- shape = 1: Simplex noise pattern
14
- * --- shape = 2: Warp noise pattern
15
- * --- shape = 3: Columns if dots moving vertically
16
- * --- shape = 4: Sine wave
17
- * --- shape = 5: Ripple effect
18
- * --- shape = 6: Swirl animation
19
- * --- shape = 7: Rotating sphere
20
- *
21
- * - u_type (float, used as int, 1 to 4):
22
- * --- type = 1: Random dithering
23
- * --- type = 2: 2x2 Bayer matrix
24
- * --- type = 3: 4x4 Bayer matrix
25
- * --- type = 4: 8x8 Bayer matrix
26
- *
27
- * - pxSize (float), relative to canvas resolution
6
+ * Uniforms:
7
+ * - u_colorBack, u_colorFront (RGBA)
8
+ * - pxSize: px size relative to canvas resolution
9
+ * - u_shape (float used as integer):
10
+ * ---- 1: simplex noise pattern
11
+ * ---- 2: warp noise pattern
12
+ * ---- 3: columns if dots moving vertically
13
+ * ---- 4: sine wave
14
+ * ---- 5: ripple effect
15
+ * ---- 6: swirl animation
16
+ * ---- 7: rotating sphere
17
+ * - u_type (float used as integer)
18
+ * ---- 1: random dithering
19
+ * ---- 2: 2x2 Bayer matrix
20
+ * ---- 3: 4x4 Bayer matrix
21
+ * ---- 4: 8x8 Bayer matrix
28
22
  *
23
+ * Note: pixelization is applied to the shapes BEFORE dithering, meaning pixels don't react to scaling and fit
29
24
  */
30
25
  export declare const ditheringFragmentShader: string;
31
26
  export interface DitheringUniforms extends ShaderSizingUniforms {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/dithering.ts"],
4
- "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n sizingUV,\n drawSizingHelpers,\n} from '../shader-sizing.js';\nimport { declareSimplexNoise, declarePI, declareRandom } from '../shader-utils.js';\n\n/**\n * Dithering Fragment Shader by Ksenia Kondrashova\n * Applies dithering (4 dithering types available) over the\n * abstract shapes animation (7 animated shapes available)\n *\n * Uniforms include:\n * - u_colorBack: background color, RGBA\n * - u_colorFront: pixels color, RGBA\n *\n * - u_shape (float, used as int, 1 to 7):\n * --- shape = 1: Simplex noise pattern\n * --- shape = 2: Warp noise pattern\n * --- shape = 3: Columns if dots moving vertically\n * --- shape = 4: Sine wave\n * --- shape = 5: Ripple effect\n * --- shape = 6: Swirl animation\n * --- shape = 7: Rotating sphere\n *\n * - u_type (float, used as int, 1 to 4):\n * --- type = 1: Random dithering\n * --- type = 2: 2x2 Bayer matrix\n * --- type = 3: 4x4 Bayer matrix\n * --- type = 4: 8x8 Bayer matrix\n *\n * - pxSize (float), relative to canvas resolution\n *\n */\nexport const ditheringFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\n${sizingUniformsDeclaration}\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFront;\nuniform float u_shape;\nuniform float u_type;\nuniform float u_pxSize;\n\nout vec4 fragColor;\n\n${declareSimplexNoise}\n${declarePI}\n${declareRandom}\n\nfloat getSimplexNoise(vec2 uv, float t) {\n float noise = .5 * snoise(uv - vec2(0., .3 * t));\n noise += .5 * snoise(2. * uv + vec2(0., .32 * t));\n\n return noise;\n}\n\nconst int bayer2x2[4] = int[4](0, 2, 3, 1);\nconst int bayer4x4[16] = int[16](\n 0, 8, 2, 10,\n 12, 4, 14, 6,\n 3, 11, 1, 9,\n 15, 7, 13, 5\n);\n\nconst int bayer8x8[64] = int[64](\n 0, 32, 8, 40, 2, 34, 10, 42,\n 48, 16, 56, 24, 50, 18, 58, 26,\n 12, 44, 4, 36, 14, 46, 6, 38,\n 60, 28, 52, 20, 62, 30, 54, 22,\n 3, 35, 11, 43, 1, 33, 9, 41,\n 51, 19, 59, 27, 49, 17, 57, 25,\n 15, 47, 7, 39, 13, 45, 5, 37,\n 63, 31, 55, 23, 61, 29, 53, 21\n);\n\nfloat getBayerValue(vec2 uv, int size) {\n ivec2 pos = ivec2(mod(uv, float(size)));\n int index = pos.y * size + pos.x;\n\n if (size == 2) {\n return float(bayer2x2[index]) / 4.0;\n } else if (size == 4) {\n return float(bayer4x4[index]) / 16.0;\n } else if (size == 8) {\n return float(bayer8x8[index]) / 64.0;\n }\n return 0.0;\n}\n\n\nvoid main() {\n float t = .5 * u_time;\n\n #define USE_PATTERN_SIZING\n #define USE_OBJECT_SIZING\n #define USE_PIXELIZATION\n // #define ADD_HELPERS\n\n ${sizingUV}\n\n vec2 dithering_uv = pxSizeUv;\n vec2 ditheringNoise_uv = uv;\n vec2 shape_uv = objectUV;\n if (u_shape < 3.5) {\n shape_uv = patternUV;\n }\n\n float shape = 0.;\n if (u_shape < 1.5) {\n // Simplex noise\n shape_uv *= .001;\n\n shape = 0.5 + 0.5 * getSimplexNoise(shape_uv, t);\n shape = smoothstep(0.3, 0.9, shape);\n\n } else if (u_shape < 2.5) {\n // Warp\n shape_uv *= .003;\n\n for (float i = 1.0; i < 6.0; i++) {\n shape_uv.x += 0.6 / i * cos(i * 2.5 * shape_uv.y + t);\n shape_uv.y += 0.6 / i * cos(i * 1.5 * shape_uv.x + t);\n }\n\n shape = .15 / abs(sin(t - shape_uv.y - shape_uv.x));\n shape = smoothstep(0.02, 1., shape);\n\n } else if (u_shape < 3.5) {\n // Dots\n shape_uv *= .05;\n\n float stripeIdx = floor(2. * shape_uv.x / TWO_PI);\n float rand = fract(sin(stripeIdx * 12.9898) * 43758.5453);\n\n float speed = sign(rand - .5) * ceil(2. + rand);\n shape = sin(shape_uv.x) * cos(shape_uv.y + speed * t);\n shape = pow(shape, 6.);\n\n } else if (u_shape < 4.5) {\n // Sine wave\n shape_uv *= 4.;\n\n float wave = cos(.5 * shape_uv.x - 2. * t) * sin(1.5 * shape_uv.x + t) * (.75 + .25 * cos(3. * t));\n shape = 1. - smoothstep(-1., 1., shape_uv.y + wave);\n\n } else if (u_shape < 5.5) {\n // Ripple\n\n float dist = length(shape_uv);\n float waves = sin(pow(dist, 1.7) * 7. - 3. * t) * .5 + .5;\n shape = waves;\n\n } else if (u_shape < 6.5) {\n // Swirl\n\n float l = length(shape_uv);\n float angle = 6. * atan(shape_uv.y, shape_uv.x) + 4. * t;\n float twist = 1.2;\n float offset = pow(l, -twist) + angle / TWO_PI;\n float mid = smoothstep(0., 1., pow(l, twist));\n shape = mix(0., fract(offset), mid);\n\n } else {\n // Sphere\n shape_uv *= 2.;\n\n vec3 pos = vec3(shape_uv, sqrt(1. - pow(length(shape_uv), 2.)));\n vec3 lightPos = normalize(vec3(cos(1.5 * t), .8, sin(1.25 * t)));\n shape = .5 + .5 * dot(lightPos, pos);\n }\n\n\n int type = int(floor(u_type));\n float dithering = 0.0;\n\n switch (type) {\n case 1: {\n dithering = step(random(ditheringNoise_uv), shape);\n } break;\n case 2:\n dithering = getBayerValue(dithering_uv, 2);\n break;\n case 3:\n dithering = getBayerValue(dithering_uv, 4);\n break;\n default:\n dithering = getBayerValue(dithering_uv, 8);\n break;\n }\n\n dithering -= .5;\n float res = step(.5, shape + dithering);\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 #ifdef ADD_HELPERS\n vec2 helperBox = objectHelperBox;\n vec2 boxSize = objectBoxSize;\n if (u_shape < 3.5) {\n helperBox = patternHelperBox;\n boxSize = patternBoxSize;\n }\n ${drawSizingHelpers}\n #endif\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DitheringUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFront: [number, number, number, number];\n u_shape: (typeof DitheringShapes)[DitheringShape];\n u_type: (typeof DitheringTypes)[DitheringType];\n u_pxSize: number;\n}\n\nexport interface DitheringParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorFront?: string;\n shape?: DitheringShape;\n type?: DitheringType;\n pxSize?: number;\n}\n\nexport const DitheringShapes = {\n simplex: 1,\n warp: 2,\n dots: 3,\n wave: 4,\n ripple: 5,\n swirl: 6,\n sphere: 7,\n} as const;\n\nexport type DitheringShape = keyof typeof DitheringShapes;\n\nexport const DitheringTypes = {\n 'random': 1,\n '2x2': 2,\n '4x4': 3,\n '8x8': 4,\n} as const;\n\nexport type DitheringType = keyof typeof DitheringTypes;\n"],
5
- "mappings": ";;;;;AACA;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB,WAAW,qBAAqB;AA6BvD,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7C,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmDX,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiHN,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBhB,MAAM,kBAAkB;AAAA,EAC7B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACV;AAIO,MAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;",
4
+ "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingUniformsDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n sizingUV,\n drawSizingHelpers,\n} from '../shader-sizing.js';\nimport { declareSimplexNoise, declarePI, declareRandom } from '../shader-utils.js';\n\n/**\n * 2-color dithering effect over animated abstract shapes\n *\n * Uniforms:\n * - u_colorBack, u_colorFront (RGBA)\n * - pxSize: px size relative to canvas resolution\n * - u_shape (float used as integer):\n * ---- 1: simplex noise pattern\n * ---- 2: warp noise pattern\n * ---- 3: columns if dots moving vertically\n * ---- 4: sine wave\n * ---- 5: ripple effect\n * ---- 6: swirl animation\n * ---- 7: rotating sphere\n * - u_type (float used as integer)\n * ---- 1: random dithering\n * ---- 2: 2x2 Bayer matrix\n * ---- 3: 4x4 Bayer matrix\n * ---- 4: 8x8 Bayer matrix\n *\n * Note: pixelization is applied to the shapes BEFORE dithering, meaning pixels don't react to scaling and fit\n */\n\nexport const ditheringFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\n${sizingUniformsDeclaration}\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFront;\nuniform float u_shape;\nuniform float u_type;\nuniform float u_pxSize;\n\nout vec4 fragColor;\n\n${declareSimplexNoise}\n${declarePI}\n${declareRandom}\n\nfloat getSimplexNoise(vec2 uv, float t) {\n float noise = .5 * snoise(uv - vec2(0., .3 * t));\n noise += .5 * snoise(2. * uv + vec2(0., .32 * t));\n\n return noise;\n}\n\nconst int bayer2x2[4] = int[4](0, 2, 3, 1);\nconst int bayer4x4[16] = int[16](\n 0, 8, 2, 10,\n 12, 4, 14, 6,\n 3, 11, 1, 9,\n 15, 7, 13, 5\n);\n\nconst int bayer8x8[64] = int[64](\n 0, 32, 8, 40, 2, 34, 10, 42,\n 48, 16, 56, 24, 50, 18, 58, 26,\n 12, 44, 4, 36, 14, 46, 6, 38,\n 60, 28, 52, 20, 62, 30, 54, 22,\n 3, 35, 11, 43, 1, 33, 9, 41,\n 51, 19, 59, 27, 49, 17, 57, 25,\n 15, 47, 7, 39, 13, 45, 5, 37,\n 63, 31, 55, 23, 61, 29, 53, 21\n);\n\nfloat getBayerValue(vec2 uv, int size) {\n ivec2 pos = ivec2(mod(uv, float(size)));\n int index = pos.y * size + pos.x;\n\n if (size == 2) {\n return float(bayer2x2[index]) / 4.0;\n } else if (size == 4) {\n return float(bayer4x4[index]) / 16.0;\n } else if (size == 8) {\n return float(bayer8x8[index]) / 64.0;\n }\n return 0.0;\n}\n\n\nvoid main() {\n float t = .5 * u_time;\n\n #define USE_PATTERN_SIZING\n #define USE_OBJECT_SIZING\n #define USE_PIXELIZATION\n // #define ADD_HELPERS\n\n ${sizingUV}\n\n vec2 dithering_uv = pxSizeUv;\n vec2 ditheringNoise_uv = uv;\n vec2 shape_uv = objectUV;\n if (u_shape < 3.5) {\n shape_uv = patternUV;\n }\n\n float shape = 0.;\n if (u_shape < 1.5) {\n // Simplex noise\n shape_uv *= .001;\n\n shape = 0.5 + 0.5 * getSimplexNoise(shape_uv, t);\n shape = smoothstep(0.3, 0.9, shape);\n\n } else if (u_shape < 2.5) {\n // Warp\n shape_uv *= .003;\n\n for (float i = 1.0; i < 6.0; i++) {\n shape_uv.x += 0.6 / i * cos(i * 2.5 * shape_uv.y + t);\n shape_uv.y += 0.6 / i * cos(i * 1.5 * shape_uv.x + t);\n }\n\n shape = .15 / abs(sin(t - shape_uv.y - shape_uv.x));\n shape = smoothstep(0.02, 1., shape);\n\n } else if (u_shape < 3.5) {\n // Dots\n shape_uv *= .05;\n\n float stripeIdx = floor(2. * shape_uv.x / TWO_PI);\n float rand = fract(sin(stripeIdx * 12.9898) * 43758.5453);\n\n float speed = sign(rand - .5) * ceil(2. + rand);\n shape = sin(shape_uv.x) * cos(shape_uv.y + speed * t);\n shape = pow(shape, 6.);\n\n } else if (u_shape < 4.5) {\n // Sine wave\n shape_uv *= 4.;\n\n float wave = cos(.5 * shape_uv.x - 2. * t) * sin(1.5 * shape_uv.x + t) * (.75 + .25 * cos(3. * t));\n shape = 1. - smoothstep(-1., 1., shape_uv.y + wave);\n\n } else if (u_shape < 5.5) {\n // Ripple\n\n float dist = length(shape_uv);\n float waves = sin(pow(dist, 1.7) * 7. - 3. * t) * .5 + .5;\n shape = waves;\n\n } else if (u_shape < 6.5) {\n // Swirl\n\n float l = length(shape_uv);\n float angle = 6. * atan(shape_uv.y, shape_uv.x) + 4. * t;\n float twist = 1.2;\n float offset = pow(l, -twist) + angle / TWO_PI;\n float mid = smoothstep(0., 1., pow(l, twist));\n shape = mix(0., fract(offset), mid);\n\n } else {\n // Sphere\n shape_uv *= 2.;\n\n vec3 pos = vec3(shape_uv, sqrt(1. - pow(length(shape_uv), 2.)));\n vec3 lightPos = normalize(vec3(cos(1.5 * t), .8, sin(1.25 * t)));\n shape = .5 + .5 * dot(lightPos, pos);\n }\n\n\n int type = int(floor(u_type));\n float dithering = 0.0;\n\n switch (type) {\n case 1: {\n dithering = step(random(ditheringNoise_uv), shape);\n } break;\n case 2:\n dithering = getBayerValue(dithering_uv, 2);\n break;\n case 3:\n dithering = getBayerValue(dithering_uv, 4);\n break;\n default:\n dithering = getBayerValue(dithering_uv, 8);\n break;\n }\n\n dithering -= .5;\n float res = step(.5, shape + dithering);\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 #ifdef ADD_HELPERS\n vec2 helperBox = objectHelperBox;\n vec2 boxSize = objectBoxSize;\n if (u_shape < 3.5) {\n helperBox = patternHelperBox;\n boxSize = patternBoxSize;\n }\n ${drawSizingHelpers}\n #endif\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DitheringUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFront: [number, number, number, number];\n u_shape: (typeof DitheringShapes)[DitheringShape];\n u_type: (typeof DitheringTypes)[DitheringType];\n u_pxSize: number;\n}\n\nexport interface DitheringParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorFront?: string;\n shape?: DitheringShape;\n type?: DitheringType;\n pxSize?: number;\n}\n\nexport const DitheringShapes = {\n simplex: 1,\n warp: 2,\n dots: 3,\n wave: 4,\n ripple: 5,\n swirl: 6,\n sphere: 7,\n} as const;\n\nexport type DitheringShape = keyof typeof DitheringShapes;\n\nexport const DitheringTypes = {\n 'random': 1,\n '2x2': 2,\n '4x4': 3,\n '8x8': 4,\n} as const;\n\nexport type DitheringType = keyof typeof DitheringTypes;\n"],
5
+ "mappings": ";;;;;AACA;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB,WAAW,qBAAqB;AAyBvD,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7C,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmDX,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiHN,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBhB,MAAM,kBAAkB;AAAA,EAC7B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACV;AAIO,MAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -1,19 +1,21 @@
1
1
  import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
2
2
  /**
3
- * Dot Grid Pattern
4
- * (the size parameters are set in pixels)
3
+ * Static grid pattern
4
+ *
5
+ * Uniforms:
6
+ * - u_colorBack, u_colorFill, u_colorStroke (vec4 RGBA)
7
+ * - u_dotSize (px): base shape size
8
+ * - u_sizeRange (0..1): randomizes the size of shape between 0 and u_dotSize
9
+ * - u_strokeWidth (px): the stroke (to be added to u_dotSize)
10
+ * - u_gapX, u_gapY (px): pattern spacing
11
+ * - u_opacityRange (0..1): variety of shape opacity
12
+ * - u_shape (float used as integer):
13
+ * ---- 1: circle
14
+ * ---- 2: square
15
+ * ---- 3: triangle
16
+ * ---- 4: diamond
17
+ * ---- 5: cross
5
18
  *
6
- * Uniforms include:
7
- * u_colorBack - the background color
8
- * u_colorFill - the fill color
9
- * u_colorStroke - the stroke color
10
- * u_dotSize (px) - the base dot radius
11
- * u_strokeWidth (px) - the stroke (to be subtracted from u_dotSize)
12
- * u_gapX (px) - horizontal grid spacing
13
- * u_gapY (px) - vertical grid spacing
14
- * u_sizeRange (0 .. 1) - variety of dot size
15
- * u_opacityRange(0 .. 1) - variety of dot opacity to be applied equally to fill and stroke
16
- * u_shape - shape code (0 - circle, 1 - diamond, 2 - square, 3 - triangle)
17
19
  */
18
20
  export declare const dotGridFragmentShader: string;
19
21
  export interface DotGridUniforms extends ShaderSizingUniforms {
@@ -65,6 +65,7 @@ void main() {
65
65
  strokeWidth *= 1.5;
66
66
  p = p * 2. - 1.;
67
67
  p *= .9;
68
+ p.y = 1. - p.y;
68
69
  p.y -= .75 * baseSize;
69
70
  dist = polygon(p, 3., 1e-3);
70
71
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/dot-grid.ts"],
4
- "sourcesContent": ["import { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, declareSimplexNoise } from '../shader-utils.js';\n\n/**\n * Dot Grid Pattern\n * (the size parameters are set in pixels)\n *\n * Uniforms include:\n * u_colorBack - the background color\n * u_colorFill - the fill color\n * u_colorStroke - the stroke color\n * u_dotSize (px) - the base dot radius\n * u_strokeWidth (px) - the stroke (to be subtracted from u_dotSize)\n * u_gapX (px) - horizontal grid spacing\n * u_gapY (px) - vertical grid spacing\n * u_sizeRange (0 .. 1) - variety of dot size\n * u_opacityRange(0 .. 1) - variety of dot opacity to be applied equally to fill and stroke\n * u_shape - shape code (0 - circle, 1 - diamond, 2 - square, 3 - triangle)\n */\nexport const dotGridFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFill;\nuniform vec4 u_colorStroke;\nuniform float u_dotSize;\nuniform float u_gapX;\nuniform float u_gapY;\nuniform float u_strokeWidth;\nuniform float u_sizeRange;\nuniform float u_opacityRange;\nuniform float u_shape;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n\nfloat polygon(vec2 p, float N, float rot) {\n float a = atan(p.x, p.y) + rot;\n float r = TWO_PI / float(N);\n\n return cos(floor(.5 + a / r) * r - a) * length(p);\n}\n\nvoid main() {\n\n vec2 shape_uv = v_patternUV;\n shape_uv += .5;\n\n vec2 grid = fract(shape_uv / vec2(u_gapX, u_gapY)) + 1e-4;\n vec2 grid_idx = floor(shape_uv / vec2(u_gapX, u_gapY));\n float sizeRandomizer = .5 + .8 * snoise(2. * vec2(grid_idx.x * 100., grid_idx.y));\n float opacity_randomizer = .5 + .7 * snoise(2. * vec2(grid_idx.y, grid_idx.x));\n\n vec2 center = vec2(0.5) - 1e-3;\n vec2 p = (grid - center) * vec2(u_gapX, u_gapY);\n\n float baseSize = u_dotSize * (1. - sizeRandomizer * u_sizeRange);\n float strokeWidth = u_strokeWidth * (1. - sizeRandomizer * u_sizeRange);\n\n float dist;\n if (u_shape < 0.5) {\n // Circle\n dist = length(p);\n } else if (u_shape < 1.5) {\n // Diamond\n strokeWidth *= 1.5;\n dist = polygon(1.5 * p, 4., .25 * PI);\n } else if (u_shape < 2.5) {\n // Square\n dist = polygon(1.03 * p, 4., 1e-3);\n } else {\n // Triangle\n strokeWidth *= 1.5;\n p = p * 2. - 1.;\n p *= .9;\n p.y -= .75 * baseSize;\n dist = polygon(p, 3., 1e-3);\n }\n\n float edgeWidth = fwidth(dist);\n float shapeOuter = smoothstep(baseSize + edgeWidth, baseSize - edgeWidth, dist - strokeWidth);\n float shapeInner = smoothstep(baseSize + edgeWidth, baseSize - edgeWidth, dist);\n float stroke = shapeOuter - shapeInner;\n\n float dotOpacity = max(0., 1. - opacity_randomizer * u_opacityRange);\n stroke *= dotOpacity;\n shapeInner *= dotOpacity;\n\n stroke *= u_colorStroke.a;\n shapeInner *= u_colorFill.a;\n\n vec3 color = vec3(0.);\n color += stroke * u_colorStroke.rgb;\n color += shapeInner * u_colorFill.rgb;\n color += (1. - shapeInner - stroke) * u_colorBack.rgb * u_colorBack.a;\n\n float opacity = 0.;\n opacity += stroke;\n opacity += shapeInner;\n opacity += (1. - opacity) * u_colorBack.a;\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DotGridUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFill: [number, number, number, number];\n u_colorStroke: [number, number, number, number];\n u_dotSize: number;\n u_gapX: number;\n u_gapY: number;\n u_strokeWidth: number;\n u_sizeRange: number;\n u_opacityRange: number;\n u_shape: (typeof DotGridShapes)[DotGridShape];\n}\n\nexport interface DotGridParams extends ShaderSizingParams {\n colorBack?: string;\n colorFill?: string;\n colorStroke?: string;\n size?: number;\n gapX?: number;\n gapY?: number;\n strokeWidth?: number;\n sizeRange?: number;\n opacityRange?: number;\n shape?: DotGridShape;\n}\n\nexport const DotGridShapes = {\n circle: 0,\n diamond: 1,\n square: 2,\n triangle: 3,\n} as const;\n\nexport type DotGridShape = keyof typeof DotGridShapes;\n"],
5
- "mappings": ";;;;;AAAA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,2BAA2B;AAkBxC,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc3C,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiGd,MAAM,gBAAgB;AAAA,EAC3B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AACZ;",
4
+ "sourcesContent": ["import { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, declareSimplexNoise } from '../shader-utils.js';\n\n/**\n * Static grid pattern\n *\n * Uniforms:\n * - u_colorBack, u_colorFill, u_colorStroke (vec4 RGBA)\n * - u_dotSize (px): base shape size\n * - u_sizeRange (0..1): randomizes the size of shape between 0 and u_dotSize\n * - u_strokeWidth (px): the stroke (to be added to u_dotSize)\n * - u_gapX, u_gapY (px): pattern spacing\n * - u_opacityRange (0..1): variety of shape opacity\n * - u_shape (float used as integer):\n * ---- 1: circle\n * ---- 2: square\n * ---- 3: triangle\n * ---- 4: diamond\n * ---- 5: cross\n *\n */\n\nexport const dotGridFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorFill;\nuniform vec4 u_colorStroke;\nuniform float u_dotSize;\nuniform float u_gapX;\nuniform float u_gapY;\nuniform float u_strokeWidth;\nuniform float u_sizeRange;\nuniform float u_opacityRange;\nuniform float u_shape;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareSimplexNoise}\n\nfloat polygon(vec2 p, float N, float rot) {\n float a = atan(p.x, p.y) + rot;\n float r = TWO_PI / float(N);\n\n return cos(floor(.5 + a / r) * r - a) * length(p);\n}\n\nvoid main() {\n\n vec2 shape_uv = v_patternUV;\n shape_uv += .5;\n\n vec2 grid = fract(shape_uv / vec2(u_gapX, u_gapY)) + 1e-4;\n vec2 grid_idx = floor(shape_uv / vec2(u_gapX, u_gapY));\n float sizeRandomizer = .5 + .8 * snoise(2. * vec2(grid_idx.x * 100., grid_idx.y));\n float opacity_randomizer = .5 + .7 * snoise(2. * vec2(grid_idx.y, grid_idx.x));\n\n vec2 center = vec2(0.5) - 1e-3;\n vec2 p = (grid - center) * vec2(u_gapX, u_gapY);\n\n float baseSize = u_dotSize * (1. - sizeRandomizer * u_sizeRange);\n float strokeWidth = u_strokeWidth * (1. - sizeRandomizer * u_sizeRange);\n\n float dist;\n if (u_shape < 0.5) {\n // Circle\n dist = length(p);\n } else if (u_shape < 1.5) {\n // Diamond\n strokeWidth *= 1.5;\n dist = polygon(1.5 * p, 4., .25 * PI);\n } else if (u_shape < 2.5) {\n // Square\n dist = polygon(1.03 * p, 4., 1e-3);\n } else {\n // Triangle\n strokeWidth *= 1.5;\n p = p * 2. - 1.;\n p *= .9;\n p.y = 1. - p.y;\n p.y -= .75 * baseSize;\n dist = polygon(p, 3., 1e-3);\n }\n\n float edgeWidth = fwidth(dist);\n float shapeOuter = smoothstep(baseSize + edgeWidth, baseSize - edgeWidth, dist - strokeWidth);\n float shapeInner = smoothstep(baseSize + edgeWidth, baseSize - edgeWidth, dist);\n float stroke = shapeOuter - shapeInner;\n\n float dotOpacity = max(0., 1. - opacity_randomizer * u_opacityRange);\n stroke *= dotOpacity;\n shapeInner *= dotOpacity;\n\n stroke *= u_colorStroke.a;\n shapeInner *= u_colorFill.a;\n\n vec3 color = vec3(0.);\n color += stroke * u_colorStroke.rgb;\n color += shapeInner * u_colorFill.rgb;\n color += (1. - shapeInner - stroke) * u_colorBack.rgb * u_colorBack.a;\n\n float opacity = 0.;\n opacity += stroke;\n opacity += shapeInner;\n opacity += (1. - opacity) * u_colorBack.a;\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DotGridUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorFill: [number, number, number, number];\n u_colorStroke: [number, number, number, number];\n u_dotSize: number;\n u_gapX: number;\n u_gapY: number;\n u_strokeWidth: number;\n u_sizeRange: number;\n u_opacityRange: number;\n u_shape: (typeof DotGridShapes)[DotGridShape];\n}\n\nexport interface DotGridParams extends ShaderSizingParams {\n colorBack?: string;\n colorFill?: string;\n colorStroke?: string;\n size?: number;\n gapX?: number;\n gapY?: number;\n strokeWidth?: number;\n sizeRange?: number;\n opacityRange?: number;\n shape?: DotGridShape;\n}\n\nexport const DotGridShapes = {\n circle: 0,\n diamond: 1,\n square: 2,\n triangle: 3,\n} as const;\n\nexport type DotGridShape = keyof typeof DotGridShapes;\n"],
5
+ "mappings": ";;;;;AAAA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,2BAA2B;AAqBxC,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc3C,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkGd,MAAM,gBAAgB;AAAA,EAC3B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AACZ;",
6
6
  "names": []
7
7
  }
@@ -5,18 +5,16 @@ export declare const dotOrbitMeta: {
5
5
  readonly maxColorCount: 10;
6
6
  };
7
7
  /**
8
- * Dot Pattern with dot moving around their grid position
9
- * The artwork by Ksenia Kondrashova
10
- * Renders a dot pattern with dot placed in the center of each cell of animated Voronoi diagram
8
+ * Animated dot pattern with dots orbiting around their grid positions
9
+ *
10
+ * Uniforms:
11
+ * - u_colorBack (RGBA)
12
+ * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
+ * - u_stepsPerColor: discrete color steps between u_colors
14
+ * - u_size (0..1): dot radius (relative to cell size)
15
+ * - u_sizeRange (0..1): randomizes dot radius between 0 and u_size
16
+ * - u_spreading (0..1): max orbit distance of each dot around the cell center
11
17
  *
12
- * Uniforms include:
13
- * - u_colorBack (vec4): the background color of the scene
14
- * - u_colors (vec4[]): Input RGBA colors
15
- * - u_colorsCount (float): Number of active colors (`u_colors` length)
16
- * - u_stepsPerColor (float): Discretization of the color transition
17
- * - u_size (float, 0 .. 1): Base dot radius (relative to cell size)
18
- * - u_sizeRange (float, 0 .. 1): Dot radius to vary between the cells
19
- * - u_spreading (float, 0 .. 1): the distance each dot can move around the regular grid
20
18
  */
21
19
  export declare const dotOrbitFragmentShader: string;
22
20
  export interface DotOrbitUniforms extends ShaderSizingUniforms {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/dot-orbit.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, declareRandom, declareRotate } from '../shader-utils.js';\n\nexport const dotOrbitMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Dot Pattern with dot moving around their grid position\n * The artwork by Ksenia Kondrashova\n * Renders a dot pattern with dot placed in the center of each cell of animated Voronoi diagram\n *\n * Uniforms include:\n * - u_colorBack (vec4): the background color of the scene\n * - u_colors (vec4[]): Input RGBA colors\n * - u_colorsCount (float): Number of active colors (`u_colors` length)\n * - u_stepsPerColor (float): Discretization of the color transition\n * - u_size (float, 0 .. 1): Base dot radius (relative to cell size)\n * - u_sizeRange (float, 0 .. 1): Dot radius to vary between the cells\n * - u_spreading (float, 0 .. 1): the distance each dot can move around the regular grid\n */\nexport const dotOrbitFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${dotOrbitMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_stepsPerColor;\nuniform float u_size;\nuniform float u_sizeRange;\nuniform float u_spreading;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n\nvec2 random2(vec2 p) {\n return vec2(random(p), random(200. * p));\n}\n\nvec3 voronoiShape(vec2 uv, float time) {\n vec2 i_uv = floor(uv);\n vec2 f_uv = fract(uv);\n\n float spreading = .25 * clamp(u_spreading, 0., 1.);\n\n float minDist = 1.;\n vec2 randomizer = vec2(0.);\n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 tileOffset = vec2(float(x), float(y));\n vec2 rand = random2(i_uv + tileOffset);\n vec2 cellCenter = vec2(.5 + 1e-4);\n cellCenter += spreading * cos(time + TWO_PI * rand);\n cellCenter -= .5;\n cellCenter = rotate(cellCenter, random(vec2(rand.x, rand.y)) + .1 * time);\n cellCenter += .5;\n float dist = length(tileOffset + cellCenter - f_uv);\n if (dist < minDist) {\n minDist = dist;\n randomizer = rand;\n }\n minDist = min(minDist, dist);\n }\n }\n\n return vec3(minDist, randomizer);\n}\n\nvoid main() {\n\n vec2 shape_uv = v_patternUV;\n shape_uv += .5;\n shape_uv *= .015;\n\n float t = u_time;\n\n vec3 voronoi = voronoiShape(shape_uv, t) + 1e-4;\n\n float radius = .25 * clamp(u_size, 0., 1.) - .5 * clamp(u_sizeRange, 0., 1.) * voronoi[2];\n float dist = voronoi[0];\n float edgeWidth = fwidth(dist);\n float dots = smoothstep(radius + edgeWidth, radius - edgeWidth, dist);\n\n float shape = voronoi[1];\n\n float mixer = shape * (u_colorsCount - 1.);\n mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\n float steps = max(1., u_stepsPerColor);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${dotOrbitMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0.0, 1.0);\n localT = round(localT * steps) / steps;\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {\n float localT = mixer + 1.;\n if (mixer > (u_colorsCount - 1.)) {\n localT = mixer - (u_colorsCount - 1.);\n }\n localT = round(localT * steps) / steps;\n vec4 cFst = u_colors[0];\n cFst.rgb *= cFst.a;\n vec4 cLast = u_colors[int(u_colorsCount - 1.)];\n cLast.rgb *= cLast.a;\n gradient = mix(cLast, cFst, localT);\n }\n\n vec3 color = gradient.rgb * dots;\n float opacity = gradient.a * dots;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DotOrbitUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_size: number;\n u_sizeRange: number;\n u_spreading: number;\n u_stepsPerColor: number;\n}\n\nexport interface DotOrbitParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n size?: number;\n sizeRange?: number;\n spreading?: number;\n stepsPerColor?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,qBAAqB;AAEjD,MAAM,eAAe;AAAA,EAC1B,eAAe;AACjB;AAgBO,MAAM,yBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMtB,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,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,wBA0DS,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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, declareRandom, declareRotate } from '../shader-utils.js';\n\nexport const dotOrbitMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Animated dot pattern with dots orbiting around their grid positions\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_stepsPerColor: discrete color steps between u_colors\n * - u_size (0..1): dot radius (relative to cell size)\n * - u_sizeRange (0..1): randomizes dot radius between 0 and u_size\n * - u_spreading (0..1): max orbit distance of each dot around the cell center\n *\n */\n\nexport const dotOrbitFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${dotOrbitMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_stepsPerColor;\nuniform float u_size;\nuniform float u_sizeRange;\nuniform float u_spreading;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n\nvec2 random2(vec2 p) {\n return vec2(random(p), random(200. * p));\n}\n\nvec3 voronoiShape(vec2 uv, float time) {\n vec2 i_uv = floor(uv);\n vec2 f_uv = fract(uv);\n\n float spreading = .25 * clamp(u_spreading, 0., 1.);\n\n float minDist = 1.;\n vec2 randomizer = vec2(0.);\n for (int y = -1; y <= 1; y++) {\n for (int x = -1; x <= 1; x++) {\n vec2 tileOffset = vec2(float(x), float(y));\n vec2 rand = random2(i_uv + tileOffset);\n vec2 cellCenter = vec2(.5 + 1e-4);\n cellCenter += spreading * cos(time + TWO_PI * rand);\n cellCenter -= .5;\n cellCenter = rotate(cellCenter, random(vec2(rand.x, rand.y)) + .1 * time);\n cellCenter += .5;\n float dist = length(tileOffset + cellCenter - f_uv);\n if (dist < minDist) {\n minDist = dist;\n randomizer = rand;\n }\n minDist = min(minDist, dist);\n }\n }\n\n return vec3(minDist, randomizer);\n}\n\nvoid main() {\n\n vec2 shape_uv = v_patternUV;\n shape_uv += .5;\n shape_uv *= .015;\n\n float t = u_time;\n\n vec3 voronoi = voronoiShape(shape_uv, t) + 1e-4;\n\n float radius = .25 * clamp(u_size, 0., 1.) - .5 * clamp(u_sizeRange, 0., 1.) * voronoi[2];\n float dist = voronoi[0];\n float edgeWidth = fwidth(dist);\n float dots = smoothstep(radius + edgeWidth, radius - edgeWidth, dist);\n\n float shape = voronoi[1];\n\n float mixer = shape * (u_colorsCount - 1.);\n mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\n float steps = max(1., u_stepsPerColor);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${dotOrbitMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n float localT = clamp(mixer - float(i - 1), 0.0, 1.0);\n localT = round(localT * steps) / steps;\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {\n float localT = mixer + 1.;\n if (mixer > (u_colorsCount - 1.)) {\n localT = mixer - (u_colorsCount - 1.);\n }\n localT = round(localT * steps) / steps;\n vec4 cFst = u_colors[0];\n cFst.rgb *= cFst.a;\n vec4 cLast = u_colors[int(u_colorsCount - 1.)];\n cLast.rgb *= cLast.a;\n gradient = mix(cLast, cFst, localT);\n }\n\n vec3 color = gradient.rgb * dots;\n float opacity = gradient.a * dots;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface DotOrbitUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_size: number;\n u_sizeRange: number;\n u_spreading: number;\n u_stepsPerColor: number;\n}\n\nexport interface DotOrbitParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n size?: number;\n sizeRange?: number;\n spreading?: number;\n stepsPerColor?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,qBAAqB;AAEjD,MAAM,eAAe;AAAA,EAC1B,eAAe;AACjB;AAeO,MAAM,yBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAMtB,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhD,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,wBA0DS,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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,17 @@ export declare const godRaysMeta: {
5
5
  readonly maxColorCount: 5;
6
6
  };
7
7
  /**
8
- * GodRays pattern
9
- * The artwork by Ksenia Kondrashova
10
- * Renders a number of circular shapes with gooey effect applied
8
+ * Radial rays animated from center
11
9
  *
12
- * Uniforms include:
10
+ * Uniforms:
11
+ * - u_colorBack, u_colorBloom (RGBA)
12
+ * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
+ * - u_density: frequency of sector shapes
14
+ * - u_intensity: rays visibility within sectors
15
+ * - u_spotty: density of spots on the ray (higher = more spots)
16
+ * - u_midSize, u_midIntensity: central shape over the rays
17
+ * - u_bloom (0..1): normal to additive blending mix
13
18
  *
14
- * - u_colorBack: background RGBA color
15
- * - u_colorBloom:
16
- * - uColors (vec4[]): Input RGBA colors
17
- * - u_frequency: the frequency of rays (the number of sectors)
18
- * - u_spotty: the density of spots in the rings (higher = more spots)
19
- * - u_midSize: the size of the central shape within the rings
20
- * - u_midIntensity: the influence of the central shape on the rings
21
- * - u_density (0 .. 1): the number of visible rays
22
- * - u_bloom (0 .. 1): normal / additive bloom
23
19
  */
24
20
  export declare const godRaysFragmentShader: string;
25
21
  export interface GodRaysUniforms extends ShaderSizingUniforms {
@@ -30,8 +26,8 @@ export interface GodRaysUniforms extends ShaderSizingUniforms {
30
26
  u_spotty: number;
31
27
  u_midSize: number;
32
28
  u_midIntensity: number;
33
- u_frequency: number;
34
29
  u_density: number;
30
+ u_intensity: number;
35
31
  u_bloom: number;
36
32
  }
37
33
  export interface GodRaysParams extends ShaderSizingParams, ShaderMotionParams {
@@ -41,7 +37,7 @@ export interface GodRaysParams extends ShaderSizingParams, ShaderMotionParams {
41
37
  spotty?: number;
42
38
  midSize?: number;
43
39
  midIntensity?: number;
44
- frequency?: number;
45
40
  density?: number;
41
+ intensity?: number;
46
42
  bloom?: number;
47
43
  }
@@ -4,7 +4,7 @@
4
4
  * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5
5
 
6
6
  import { sizingVariablesDeclaration } from "../shader-sizing.js";
7
- import { declarePI, declareRandom, declareRotate, colorBandingFix } from "../shader-utils.js";
7
+ import { declarePI, declareRandom, declareRotate, declareValueNoise, colorBandingFix } from "../shader-utils.js";
8
8
  const godRaysMeta = {
9
9
  maxColorCount: 5
10
10
  };
@@ -18,11 +18,11 @@ uniform vec4 u_colorBloom;
18
18
  uniform vec4 u_colors[${godRaysMeta.maxColorCount}];
19
19
  uniform float u_colorsCount;
20
20
 
21
- uniform float u_frequency;
21
+ uniform float u_density;
22
22
  uniform float u_spotty;
23
23
  uniform float u_midSize;
24
24
  uniform float u_midIntensity;
25
- uniform float u_density;
25
+ uniform float u_intensity;
26
26
  uniform float u_bloom;
27
27
 
28
28
  ${sizingVariablesDeclaration}
@@ -32,33 +32,18 @@ out vec4 fragColor;
32
32
  ${declarePI}
33
33
  ${declareRandom}
34
34
  ${declareRotate}
35
+ ${declareValueNoise}
35
36
 
36
37
  float hash(float n) {
37
38
  return fract(sin(n * 43758.5453123) * 43758.5453123);
38
39
  }
39
40
 
40
- float valueNoise(vec2 uv) {
41
- vec2 i = floor(uv);
42
- vec2 f = fract(uv);
43
-
44
- float a = random(i);
45
- float b = random(i + vec2(1.0, 0.0));
46
- float c = random(i + vec2(0.0, 1.0));
47
- float d = random(i + vec2(1.0, 1.0));
48
-
49
- vec2 u = f * f * (3.0 - 2.0 * f);
50
-
51
- float x1 = mix(a, b, u.x);
52
- float x2 = mix(c, d, u.x);
53
- return mix(x1, x2, u.y);
54
- }
55
-
56
- float raysShape(vec2 uv, float r, float freq, float density, float radius) {
41
+ float raysShape(vec2 uv, float r, float freq, float intensity, float radius) {
57
42
  float a = atan(uv.y, uv.x);
58
43
  vec2 left = vec2(a * freq, r);
59
44
  vec2 right = vec2(mod(a, TWO_PI) * freq, r);
60
- float n_left = pow(valueNoise(left), density);
61
- float n_right = pow(valueNoise(right), density);
45
+ float n_left = pow(valueNoise(left), intensity);
46
+ float n_right = pow(valueNoise(right), intensity);
62
47
  float shape = mix(n_right, n_left, smoothstep(-.15, .15, uv.x));
63
48
  return shape;
64
49
  }
@@ -71,7 +56,7 @@ void main() {
71
56
  float radius = length(shape_uv);
72
57
  float spots = 5. * abs(u_spotty);
73
58
 
74
- float density = 4. - 3. * clamp(u_density, 0., 1.);
59
+ float intensity = 4. - 3. * clamp(u_intensity, 0., 1.);
75
60
 
76
61
  float delta = 1. - smoothstep(0., 1., radius);
77
62
 
@@ -88,10 +73,10 @@ void main() {
88
73
 
89
74
  float r1 = radius * (1.0 + 0.4 * float(i)) - 3.0 * t;
90
75
  float r2 = 0.5 * radius * (1.0 + spots) - 2.0 * t;
91
- float f = mix(1.0, 3.0 + 0.5 * float(i), hash(float(i) + 10.0)) * u_frequency;
76
+ float f = mix(1.0, 3.0 + 0.5 * float(i), hash(float(i) + 10.0)) * u_density;
92
77
 
93
- float ray = raysShape(rotatedUV, r1, 5.0 * f, density, radius);
94
- ray *= raysShape(rotatedUV, r2, 4.0 * f, density, radius);
78
+ float ray = raysShape(rotatedUV, r1, 5.0 * f, intensity, radius);
79
+ ray *= raysShape(rotatedUV, r2, 4.0 * f, intensity, radius);
95
80
  ray += (1. + 4. * ray) * middleShape;
96
81
  ray = clamp(ray, 0.0, 1.0);
97
82
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/god-rays.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, declareRandom, declareRotate, colorBandingFix } from '../shader-utils.js';\n\nexport const godRaysMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * GodRays pattern\n * The artwork by Ksenia Kondrashova\n * Renders a number of circular shapes with gooey effect applied\n *\n * Uniforms include:\n *\n * - u_colorBack: background RGBA color\n * - u_colorBloom:\n * - uColors (vec4[]): Input RGBA colors\n * - u_frequency: the frequency of rays (the number of sectors)\n * - u_spotty: the density of spots in the rings (higher = more spots)\n * - u_midSize: the size of the central shape within the rings\n * - u_midIntensity: the influence of the central shape on the rings\n * - u_density (0 .. 1): the number of visible rays\n * - u_bloom (0 .. 1): normal / additive bloom\n */\nexport const godRaysFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorBloom;\nuniform vec4 u_colors[${godRaysMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_frequency;\nuniform float u_spotty;\nuniform float u_midSize;\nuniform float u_midIntensity;\nuniform float u_density;\nuniform float u_bloom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n\nfloat hash(float n) {\n return fract(sin(n * 43758.5453123) * 43758.5453123);\n}\n\nfloat valueNoise(vec2 uv) {\n vec2 i = floor(uv);\n vec2 f = fract(uv);\n\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 vec2 u = f * f * (3.0 - 2.0 * f);\n\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 raysShape(vec2 uv, float r, float freq, float density, float radius) {\n float a = atan(uv.y, uv.x);\n vec2 left = vec2(a * freq, r);\n vec2 right = vec2(mod(a, TWO_PI) * freq, r);\n float n_left = pow(valueNoise(left), density);\n float n_right = pow(valueNoise(right), density);\n float shape = mix(n_right, n_left, smoothstep(-.15, .15, uv.x));\n return shape;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float t = .2 * u_time;\n\n float radius = length(shape_uv);\n float spots = 5. * abs(u_spotty);\n\n float density = 4. - 3. * clamp(u_density, 0., 1.);\n\n float delta = 1. - smoothstep(0., 1., radius);\n\n float middleShape = pow(u_midIntensity, .3) * smoothstep(abs(u_midSize), 0.02 * abs(u_midSize), 3.0 * radius);\n middleShape = pow(middleShape, 5.0);\n\n vec3 accumColor = vec3(0.0);\n float accumAlpha = 0.0;\n\n for (int i = 0; i < ${godRaysMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 rotatedUV = rotate(shape_uv, float(i) + 1.0);\n\n float r1 = radius * (1.0 + 0.4 * float(i)) - 3.0 * t;\n float r2 = 0.5 * radius * (1.0 + spots) - 2.0 * t;\n float f = mix(1.0, 3.0 + 0.5 * float(i), hash(float(i) + 10.0)) * u_frequency;\n\n float ray = raysShape(rotatedUV, r1, 5.0 * f, density, radius);\n ray *= raysShape(rotatedUV, r2, 4.0 * f, density, radius);\n ray += (1. + 4. * ray) * middleShape;\n ray = clamp(ray, 0.0, 1.0);\n\n float srcAlpha = u_colors[i].a * ray;\n vec3 srcColor = u_colors[i].rgb * srcAlpha;\n\n vec3 alphaBlendColor = accumColor + (1.0 - accumAlpha) * srcColor;\n float alphaBlendAlpha = accumAlpha + (1.0 - accumAlpha) * srcAlpha;\n\n vec3 addBlendColor = accumColor + srcColor;\n float addBlendAlpha = accumAlpha + srcAlpha;\n\n accumColor = mix(alphaBlendColor, addBlendColor, u_bloom);\n accumAlpha = mix(alphaBlendAlpha, addBlendAlpha, u_bloom);\n }\n\n float overlayAlpha = u_colorBloom.a;\n vec3 overlayColor = u_colorBloom.rgb * overlayAlpha;\n\n vec3 colorWithOverlay = accumColor + accumAlpha * overlayColor;\n accumColor = mix(accumColor, colorWithOverlay, u_bloom);\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n\n vec3 color = accumColor + (1. - accumAlpha) * bgColor;\n float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;\n color = clamp(color, 0., 1.);\n opacity = clamp(opacity, 0., 1.);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface GodRaysUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorBloom: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_spotty: number;\n u_midSize: number;\n u_midIntensity: number;\n u_frequency: number;\n u_density: number;\n u_bloom: number;\n}\n\nexport interface GodRaysParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorBloom?: string;\n colors?: string[];\n spotty?: number;\n midSize?: number;\n midIntensity?: number;\n frequency?: number;\n density?: number;\n bloom?: number;\n}\n"],
5
- "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,eAAe,uBAAuB;AAElE,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAmBO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAOrB,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,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,wBAkDS,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,IAwC7C,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 { declarePI, declareRandom, declareRotate, declareValueNoise, colorBandingFix } from '../shader-utils.js';\n\nexport const godRaysMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Radial rays animated from center\n *\n * Uniforms:\n * - u_colorBack, u_colorBloom (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_density: frequency of sector shapes\n * - u_intensity: rays visibility within sectors\n * - u_spotty: density of spots on the ray (higher = more spots)\n * - u_midSize, u_midIntensity: central shape over the rays\n * - u_bloom (0..1): normal to additive blending mix\n *\n */\n\nexport const godRaysFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorBloom;\nuniform vec4 u_colors[${godRaysMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_density;\nuniform float u_spotty;\nuniform float u_midSize;\nuniform float u_midIntensity;\nuniform float u_intensity;\nuniform float u_bloom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${declareRandom}\n${declareRotate}\n${declareValueNoise}\n\nfloat hash(float n) {\n return fract(sin(n * 43758.5453123) * 43758.5453123);\n}\n\nfloat raysShape(vec2 uv, float r, float freq, float intensity, float radius) {\n float a = atan(uv.y, uv.x);\n vec2 left = vec2(a * freq, r);\n vec2 right = vec2(mod(a, TWO_PI) * freq, r);\n float n_left = pow(valueNoise(left), intensity);\n float n_right = pow(valueNoise(right), intensity);\n float shape = mix(n_right, n_left, smoothstep(-.15, .15, uv.x));\n return shape;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float t = .2 * u_time;\n\n float radius = length(shape_uv);\n float spots = 5. * abs(u_spotty);\n\n float intensity = 4. - 3. * clamp(u_intensity, 0., 1.);\n\n float delta = 1. - smoothstep(0., 1., radius);\n\n float middleShape = pow(u_midIntensity, .3) * smoothstep(abs(u_midSize), 0.02 * abs(u_midSize), 3.0 * radius);\n middleShape = pow(middleShape, 5.0);\n\n vec3 accumColor = vec3(0.0);\n float accumAlpha = 0.0;\n\n for (int i = 0; i < ${godRaysMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 rotatedUV = rotate(shape_uv, float(i) + 1.0);\n\n float r1 = radius * (1.0 + 0.4 * float(i)) - 3.0 * t;\n float r2 = 0.5 * radius * (1.0 + spots) - 2.0 * t;\n float f = mix(1.0, 3.0 + 0.5 * float(i), hash(float(i) + 10.0)) * u_density;\n\n float ray = raysShape(rotatedUV, r1, 5.0 * f, intensity, radius);\n ray *= raysShape(rotatedUV, r2, 4.0 * f, intensity, radius);\n ray += (1. + 4. * ray) * middleShape;\n ray = clamp(ray, 0.0, 1.0);\n\n float srcAlpha = u_colors[i].a * ray;\n vec3 srcColor = u_colors[i].rgb * srcAlpha;\n\n vec3 alphaBlendColor = accumColor + (1.0 - accumAlpha) * srcColor;\n float alphaBlendAlpha = accumAlpha + (1.0 - accumAlpha) * srcAlpha;\n\n vec3 addBlendColor = accumColor + srcColor;\n float addBlendAlpha = accumAlpha + srcAlpha;\n\n accumColor = mix(alphaBlendColor, addBlendColor, u_bloom);\n accumAlpha = mix(alphaBlendAlpha, addBlendAlpha, u_bloom);\n }\n\n float overlayAlpha = u_colorBloom.a;\n vec3 overlayColor = u_colorBloom.rgb * overlayAlpha;\n\n vec3 colorWithOverlay = accumColor + accumAlpha * overlayColor;\n accumColor = mix(accumColor, colorWithOverlay, u_bloom);\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n\n vec3 color = accumColor + (1. - accumAlpha) * bgColor;\n float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;\n color = clamp(color, 0., 1.);\n opacity = clamp(opacity, 0., 1.);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface GodRaysUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorBloom: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_spotty: number;\n u_midSize: number;\n u_midIntensity: number;\n u_density: number;\n u_intensity: number;\n u_bloom: number;\n}\n\nexport interface GodRaysParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorBloom?: string;\n colors?: string[];\n spotty?: number;\n midSize?: number;\n midIntensity?: number;\n density?: number;\n intensity?: number;\n bloom?: number;\n}\n"],
5
+ "mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,eAAe,eAAe,mBAAmB,uBAAuB;AAErF,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAgBO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAOrB,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA,EACb,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAkCK,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,IAwC7C,eAAe;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,7 +5,25 @@ export declare const grainGradientMeta: {
5
5
  readonly maxColorCount: 7;
6
6
  };
7
7
  /**
8
- * Grainy Gradient Ksenia Kondrashova
8
+ * Multi-color gradient with noise & grain over animated abstract shapes
9
+ *
10
+ * Uniforms:
11
+ * - u_colorBack (RGBA)
12
+ * - u_colors (vec4[]), u_colorsCount (float used as integer)
13
+ * - u_softness (0..1): blur between color bands
14
+ * - u_intensity (0..1): distortion between color bands
15
+ * - u_noise (0..1): grainy noise independent of softness
16
+ * - u_shape (float used as integer):
17
+ * ---- 1: single sine wave
18
+ * ---- 2: dots pattern
19
+ * ---- 3: truchet pattern
20
+ * ---- 4: corners (2 rounded rectangles)
21
+ * ---- 5: ripple
22
+ * ---- 6: blob (metaballs)
23
+ * ---- 7: circle imitating 3d look
24
+ *
25
+ * Note: grains are calculated using gl_FragCoord & u_resolution, meaning grains don't react to scaling and fit
26
+ *
9
27
  */
10
28
  export declare const grainGradientFragmentShader: string;
11
29
  export interface GrainGradientUniforms extends ShaderSizingUniforms {