egaki 0.6.0 → 0.7.1

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 (271) hide show
  1. package/CHANGELOG.md +145 -9
  2. package/dist/cli/cache-utils.d.ts +33 -0
  3. package/dist/cli/cache-utils.d.ts.map +1 -0
  4. package/dist/cli/cache-utils.js +157 -0
  5. package/dist/cli/cached-generate.d.ts +105 -0
  6. package/dist/cli/cached-generate.d.ts.map +1 -0
  7. package/dist/cli/cached-generate.js +208 -0
  8. package/dist/cli/cached-generate.test.d.ts +11 -0
  9. package/dist/cli/cached-generate.test.d.ts.map +1 -0
  10. package/dist/cli/cached-generate.test.js +431 -0
  11. package/dist/cli/cartesia-provider.d.ts +16 -0
  12. package/dist/cli/cartesia-provider.d.ts.map +1 -0
  13. package/dist/cli/cartesia-provider.js +184 -0
  14. package/dist/cli/chatgpt-auth.d.ts.map +1 -0
  15. package/dist/cli/cli.d.ts +4 -0
  16. package/dist/cli/cli.d.ts.map +1 -0
  17. package/dist/{cli.js → cli/cli.js} +626 -600
  18. package/dist/cli/clone-generate.d.ts +26 -0
  19. package/dist/cli/clone-generate.d.ts.map +1 -0
  20. package/dist/cli/clone-generate.js +148 -0
  21. package/dist/cli/credentials.d.ts.map +1 -0
  22. package/dist/{credentials.js → cli/credentials.js} +20 -0
  23. package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
  24. package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
  25. package/dist/cli/elevenlabs-speech-provider.js +199 -0
  26. package/dist/cli/generate.d.ts +140 -0
  27. package/dist/cli/generate.d.ts.map +1 -0
  28. package/dist/cli/generate.js +604 -0
  29. package/dist/cli/generate.test.d.ts +2 -0
  30. package/dist/cli/generate.test.d.ts.map +1 -0
  31. package/dist/cli/generate.test.js +131 -0
  32. package/dist/cli/login.d.ts.map +1 -0
  33. package/dist/cli/main.d.ts +3 -0
  34. package/dist/cli/main.d.ts.map +1 -0
  35. package/dist/cli/main.js +7 -0
  36. package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
  37. package/dist/cli/model-catalog.d.ts.map +1 -0
  38. package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
  39. package/dist/{models.d.ts → cli/models.d.ts} +12 -5
  40. package/dist/cli/models.d.ts.map +1 -0
  41. package/dist/{models.js → cli/models.js} +58 -57
  42. package/dist/cli/open-browser.d.ts.map +1 -0
  43. package/dist/cli/openai-speech-provider.d.ts +3 -0
  44. package/dist/cli/openai-speech-provider.d.ts.map +1 -0
  45. package/dist/cli/openai-speech-provider.js +28 -0
  46. package/dist/cli/separation-generate.d.ts +34 -0
  47. package/dist/cli/separation-generate.d.ts.map +1 -0
  48. package/dist/cli/separation-generate.js +117 -0
  49. package/dist/cli/speech-catalog.d.ts +35 -0
  50. package/dist/cli/speech-catalog.d.ts.map +1 -0
  51. package/dist/cli/speech-catalog.js +195 -0
  52. package/dist/cli/speech-generate.d.ts +86 -0
  53. package/dist/cli/speech-generate.d.ts.map +1 -0
  54. package/dist/cli/speech-generate.js +156 -0
  55. package/dist/cli/speech-models.d.ts +8 -0
  56. package/dist/cli/speech-models.d.ts.map +1 -0
  57. package/dist/cli/speech-models.js +109 -0
  58. package/dist/cli/speech-provider.test.d.ts +2 -0
  59. package/dist/cli/speech-provider.test.d.ts.map +1 -0
  60. package/dist/cli/speech-provider.test.js +197 -0
  61. package/dist/cli/subscription.d.ts.map +1 -0
  62. package/dist/cli/transcription-catalog.d.ts +35 -0
  63. package/dist/cli/transcription-catalog.d.ts.map +1 -0
  64. package/dist/cli/transcription-catalog.js +192 -0
  65. package/dist/cli/transcription-generate.d.ts +62 -0
  66. package/dist/cli/transcription-generate.d.ts.map +1 -0
  67. package/dist/cli/transcription-generate.js +144 -0
  68. package/dist/cli/transcription-models.d.ts +9 -0
  69. package/dist/cli/transcription-models.d.ts.map +1 -0
  70. package/dist/cli/transcription-models.js +100 -0
  71. package/dist/cli/transcription-providers.d.ts +22 -0
  72. package/dist/cli/transcription-providers.d.ts.map +1 -0
  73. package/dist/cli/transcription-providers.js +290 -0
  74. package/dist/cli/video-model-catalog.d.ts.map +1 -0
  75. package/dist/cli/xai-auth.d.ts.map +1 -0
  76. package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
  77. package/dist/vite/angled-screen.d.ts +57 -0
  78. package/dist/vite/angled-screen.d.ts.map +1 -0
  79. package/dist/vite/angled-screen.js +115 -0
  80. package/dist/vite/app.d.ts +51 -0
  81. package/dist/vite/app.d.ts.map +1 -0
  82. package/dist/vite/app.js +150 -0
  83. package/dist/vite/bands-shader.d.ts +47 -0
  84. package/dist/vite/bands-shader.d.ts.map +1 -0
  85. package/dist/vite/bands-shader.js +267 -0
  86. package/dist/vite/code-block.d.ts +107 -0
  87. package/dist/vite/code-block.d.ts.map +1 -0
  88. package/dist/vite/code-block.js +641 -0
  89. package/dist/vite/components.d.ts +36 -0
  90. package/dist/vite/components.d.ts.map +1 -0
  91. package/dist/vite/components.js +113 -0
  92. package/dist/vite/dispersion-rings-shader.d.ts +44 -0
  93. package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
  94. package/dist/vite/dispersion-rings-shader.js +282 -0
  95. package/dist/vite/easing-curves.d.ts +129 -0
  96. package/dist/vite/easing-curves.d.ts.map +1 -0
  97. package/dist/vite/easing-curves.js +584 -0
  98. package/dist/vite/easing-curves.test.d.ts +2 -0
  99. package/dist/vite/easing-curves.test.d.ts.map +1 -0
  100. package/dist/vite/easing-curves.test.js +200 -0
  101. package/dist/vite/generated-media-client.d.ts +35 -0
  102. package/dist/vite/generated-media-client.d.ts.map +1 -0
  103. package/dist/vite/generated-media-client.js +76 -0
  104. package/dist/vite/keyframes.d.ts +129 -0
  105. package/dist/vite/keyframes.d.ts.map +1 -0
  106. package/dist/vite/keyframes.js +194 -0
  107. package/dist/vite/layout-editor.d.ts +45 -0
  108. package/dist/vite/layout-editor.d.ts.map +1 -0
  109. package/dist/vite/layout-editor.js +587 -0
  110. package/dist/vite/layout-transition.d.ts +136 -0
  111. package/dist/vite/layout-transition.d.ts.map +1 -0
  112. package/dist/vite/layout-transition.js +581 -0
  113. package/dist/vite/liquid-gradient-shader.d.ts +62 -0
  114. package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
  115. package/dist/vite/liquid-gradient-shader.js +413 -0
  116. package/dist/vite/mdx-client.d.ts +15 -0
  117. package/dist/vite/mdx-client.d.ts.map +1 -0
  118. package/dist/vite/mdx-client.js +265 -0
  119. package/dist/vite/mdx-parse.d.ts +102 -0
  120. package/dist/vite/mdx-parse.d.ts.map +1 -0
  121. package/dist/vite/mdx-parse.js +251 -0
  122. package/dist/vite/mdx-provided-components.d.ts +18 -0
  123. package/dist/vite/mdx-provided-components.d.ts.map +1 -0
  124. package/dist/vite/mdx-provided-components.js +14 -0
  125. package/dist/vite/mdx-video.d.ts +327 -0
  126. package/dist/vite/mdx-video.d.ts.map +1 -0
  127. package/dist/vite/mdx-video.js +596 -0
  128. package/dist/vite/mdx-video.test.d.ts +9 -0
  129. package/dist/vite/mdx-video.test.d.ts.map +1 -0
  130. package/dist/vite/mdx-video.test.js +1945 -0
  131. package/dist/vite/media-components.d.ts +45 -0
  132. package/dist/vite/media-components.d.ts.map +1 -0
  133. package/dist/vite/media-components.js +355 -0
  134. package/dist/vite/media-duration-store.d.ts +66 -0
  135. package/dist/vite/media-duration-store.d.ts.map +1 -0
  136. package/dist/vite/media-duration-store.js +204 -0
  137. package/dist/vite/player-page.d.ts +35 -0
  138. package/dist/vite/player-page.d.ts.map +1 -0
  139. package/dist/vite/player-page.js +720 -0
  140. package/dist/vite/render-client.d.ts +18 -0
  141. package/dist/vite/render-client.d.ts.map +1 -0
  142. package/dist/vite/render-client.js +67 -0
  143. package/dist/vite/sdk.d.ts +221 -0
  144. package/dist/vite/sdk.d.ts.map +1 -0
  145. package/dist/vite/sdk.js +355 -0
  146. package/dist/vite/server-components.d.ts +55 -0
  147. package/dist/vite/server-components.d.ts.map +1 -0
  148. package/dist/vite/server-components.js +156 -0
  149. package/dist/vite/server-mdx.d.ts +74 -0
  150. package/dist/vite/server-mdx.d.ts.map +1 -0
  151. package/dist/vite/server-mdx.js +259 -0
  152. package/dist/vite/shader-renderer.d.ts +48 -0
  153. package/dist/vite/shader-renderer.d.ts.map +1 -0
  154. package/dist/vite/shader-renderer.js +411 -0
  155. package/dist/vite/store-hooks.d.ts +12 -0
  156. package/dist/vite/store-hooks.d.ts.map +1 -0
  157. package/dist/vite/store-hooks.js +93 -0
  158. package/dist/vite/store.d.ts +75 -0
  159. package/dist/vite/store.d.ts.map +1 -0
  160. package/dist/vite/store.js +52 -0
  161. package/dist/vite/store.test.d.ts +6 -0
  162. package/dist/vite/store.test.d.ts.map +1 -0
  163. package/dist/vite/store.test.js +172 -0
  164. package/dist/vite/tweakpane-hook.d.ts +94 -0
  165. package/dist/vite/tweakpane-hook.d.ts.map +1 -0
  166. package/dist/vite/tweakpane-hook.js +450 -0
  167. package/dist/vite/vite-plugin.d.ts +28 -0
  168. package/dist/vite/vite-plugin.d.ts.map +1 -0
  169. package/dist/vite/vite-plugin.js +539 -0
  170. package/dist/vite/wave-gradient-shader.d.ts +41 -0
  171. package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
  172. package/dist/vite/wave-gradient-shader.js +207 -0
  173. package/package.json +101 -24
  174. package/skills/egaki/SKILL.md +162 -1
  175. package/src/cli/cache-utils.ts +169 -0
  176. package/src/cli/cached-generate.test.ts +531 -0
  177. package/src/cli/cached-generate.ts +348 -0
  178. package/src/cli/cartesia-provider.ts +249 -0
  179. package/src/{cli.ts → cli/cli.ts} +836 -884
  180. package/src/cli/clone-generate.ts +202 -0
  181. package/src/{credentials.ts → cli/credentials.ts} +20 -0
  182. package/src/cli/elevenlabs-speech-provider.ts +243 -0
  183. package/src/cli/generate.test.ts +166 -0
  184. package/src/cli/generate.ts +912 -0
  185. package/src/cli/main.ts +8 -0
  186. package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
  187. package/src/{models.ts → cli/models.ts} +65 -86
  188. package/src/cli/openai-speech-provider.ts +34 -0
  189. package/src/cli/separation-generate.ts +187 -0
  190. package/src/cli/speech-catalog.ts +253 -0
  191. package/src/cli/speech-generate.ts +275 -0
  192. package/src/cli/speech-models.ts +146 -0
  193. package/src/cli/speech-provider.test.ts +226 -0
  194. package/src/cli/transcription-catalog.ts +250 -0
  195. package/src/cli/transcription-generate.ts +214 -0
  196. package/src/cli/transcription-models.ts +136 -0
  197. package/src/cli/transcription-providers.ts +427 -0
  198. package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
  199. package/src/vite/angled-screen.tsx +214 -0
  200. package/src/vite/app.tsx +197 -0
  201. package/src/vite/bands-shader.tsx +319 -0
  202. package/src/vite/code-block.tsx +939 -0
  203. package/src/vite/components.tsx +278 -0
  204. package/src/vite/dispersion-rings-shader.tsx +331 -0
  205. package/src/vite/easing-curves.test.ts +232 -0
  206. package/src/vite/easing-curves.ts +743 -0
  207. package/src/vite/generated-media-client.tsx +121 -0
  208. package/src/vite/keyframes.tsx +347 -0
  209. package/src/vite/layout-editor.tsx +709 -0
  210. package/src/vite/layout-transition.tsx +706 -0
  211. package/src/vite/liquid-gradient-shader.tsx +474 -0
  212. package/src/vite/mdx-client.tsx +420 -0
  213. package/src/vite/mdx-parse.ts +343 -0
  214. package/src/vite/mdx-provided-components.ts +19 -0
  215. package/src/vite/mdx-video.test.tsx +2219 -0
  216. package/src/vite/mdx-video.tsx +976 -0
  217. package/src/vite/media-components.tsx +473 -0
  218. package/src/vite/media-duration-store.ts +225 -0
  219. package/src/vite/motion-timing.ts +194 -0
  220. package/src/vite/player-page.tsx +1107 -0
  221. package/src/vite/render-client.ts +84 -0
  222. package/src/vite/sdk.ts +598 -0
  223. package/src/vite/server-components.tsx +241 -0
  224. package/src/vite/server-mdx.ts +285 -0
  225. package/src/vite/shader-renderer.tsx +535 -0
  226. package/src/vite/store-hooks.ts +117 -0
  227. package/src/vite/store.test.ts +202 -0
  228. package/src/vite/store.ts +115 -0
  229. package/src/vite/styles.css +21 -0
  230. package/src/vite/tweakpane-hook.tsx +593 -0
  231. package/src/vite/virtual-modules.d.ts +30 -0
  232. package/src/vite/vite-plugin.ts +585 -0
  233. package/src/vite/wave-gradient-shader.tsx +253 -0
  234. package/README.md +0 -370
  235. package/dist/antigravity-auth.d.ts +0 -15
  236. package/dist/antigravity-auth.d.ts.map +0 -1
  237. package/dist/antigravity-auth.js +0 -544
  238. package/dist/antigravity-image.d.ts +0 -11
  239. package/dist/antigravity-image.d.ts.map +0 -1
  240. package/dist/antigravity-image.js +0 -285
  241. package/dist/chatgpt-auth.d.ts.map +0 -1
  242. package/dist/cli.d.ts +0 -3
  243. package/dist/cli.d.ts.map +0 -1
  244. package/dist/credentials.d.ts.map +0 -1
  245. package/dist/gateway-model-candidates.generated.d.ts +0 -11
  246. package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
  247. package/dist/gateway-model-candidates.generated.js +0 -64
  248. package/dist/login.d.ts.map +0 -1
  249. package/dist/model-catalog.d.ts.map +0 -1
  250. package/dist/models.d.ts.map +0 -1
  251. package/dist/open-browser.d.ts.map +0 -1
  252. package/dist/subscription.d.ts.map +0 -1
  253. package/dist/video-model-catalog.d.ts.map +0 -1
  254. package/dist/xai-auth.d.ts.map +0 -1
  255. /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
  256. /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
  257. /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
  258. /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
  259. /package/dist/{login.js → cli/login.js} +0 -0
  260. /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
  261. /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
  262. /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
  263. /package/dist/{subscription.js → cli/subscription.js} +0 -0
  264. /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
  265. /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
  266. /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
  267. /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
  268. /package/src/{login.ts → cli/login.ts} +0 -0
  269. /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
  270. /package/src/{subscription.ts → cli/subscription.ts} +0 -0
  271. /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
@@ -0,0 +1,319 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * BandsShader — chromatic dispersion through repeating lens bands.
5
+ *
6
+ * Port of Framer's DispersionBands shader module for Remotion/egaki.
7
+ * Original source:
8
+ * https://framerusercontent.com/modules/jVqOzZrK81udrIw4uWLw/cV6qlarOv1tGcvTbyZeC/DispersionBands.js
9
+ *
10
+ * An animated gradient of user-defined colors is distorted through a tiled
11
+ * grid of spherical lenses. Each lens splits light into RGB channels at its
12
+ * edges (chromatic dispersion), producing rainbow fringing similar to light
13
+ * passing through a prism. 8-sample temporal anti-aliasing with per-sample
14
+ * spectral weighting gives the effect a soft, photographic quality.
15
+ *
16
+ * With the default lensSpacingY=0.01, lenses are essentially horizontal bands
17
+ * spanning full height. Increasing lensSpacingY creates a 2D grid of individual
18
+ * spherical lenses.
19
+ */
20
+
21
+ import type { CSSProperties } from 'react'
22
+ import { defineShader } from './shader-renderer.tsx'
23
+
24
+ // ---------------------------------------------------------------------------
25
+ // Props
26
+ // ---------------------------------------------------------------------------
27
+
28
+ export interface BandsShaderProps {
29
+ /** Color palette for the gradient (max 8). Hex strings like "#4AB7FF". */
30
+ colors?: string[]
31
+ /** Seed for gradient flow directions and frequencies. Different seeds = different patterns. */
32
+ seed?: number
33
+ /** Animation speed multiplier. 0 = frozen, 0.3 = default, 2 = fast. */
34
+ speed?: number
35
+ /** Wavy spatial jitter per sample. 0 = clean, higher = dreamy/melting distortion. */
36
+ ephemeralAmp?: number
37
+ /** UV scale before the lens grid. Higher = more zoomed in, fewer visible lens cells. */
38
+ lensScale?: number
39
+ /** Horizontal spacing of the repeating lens cells. Smaller = more lens columns. */
40
+ lensSpacingX?: number
41
+ /** Vertical spacing of lens cells. At 0.01 (default) lenses are tall horizontal bands. */
42
+ lensSpacingY?: number
43
+ /** Radius of each lens sphere. Controls magnification area vs flat area. */
44
+ lensRadius?: number
45
+ /** How much R and B channels diverge from G at lens edges. 0 = none, 1 = maximum rainbow. */
46
+ dispersionStrength?: number
47
+ /** Extra rainbow tint multiplier at lens edges. Pushes edge colors toward prismatic look. */
48
+ edgeDisp?: number
49
+ style?: CSSProperties
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Fragment shader body
54
+ // ---------------------------------------------------------------------------
55
+
56
+ /**
57
+ * Raw GLSL fragment body from DispersionBands.js.
58
+ * The defineShader engine prepends #version, precision, v_uv, fragColor,
59
+ * uniform declarations, and built-in uniforms automatically.
60
+ *
61
+ * Algorithm overview:
62
+ * 1. Gradient flow: seed-derived sin/cos waves create an organic color field
63
+ * 2. Band lens: UV is tiled into repeating cells; each cell has a spherical
64
+ * lens that warps UVs outward (magnification at center, edge factor at rim)
65
+ * 3. Chromatic dispersion: lens applied 3× per sample (R, G, B) with different
66
+ * index-of-refraction offsets, splitting color channels at lens edges
67
+ * 4. 8-sample TAA: per-pixel random offset + spectral tint weights, averaged
68
+ */
69
+ const FRAGMENT_SOURCE = `
70
+ const int SAMPLES = 8;
71
+ const float EPHEMERAL_DRIP = 1.0;
72
+
73
+ // === PCG hash - https://www.jcgt.org/published/0009/03/02/
74
+ uvec3 hash3(uvec3 v) {
75
+ v = v * 1664525u + 1013904223u;
76
+ v.x += v.y * v.z;
77
+ v.y += v.z * v.x;
78
+ v.z += v.x * v.y;
79
+ v ^= v >> 16u;
80
+ v.x += v.y * v.z;
81
+ v.y += v.z * v.x;
82
+ v.z += v.x * v.y;
83
+ return v;
84
+ }
85
+ uvec3 seed;
86
+ vec3 random3f() {
87
+ seed = hash3(seed);
88
+ return vec3(seed) / float(-1u);
89
+ }
90
+
91
+ vec3 seedRandom(float seedVal) {
92
+ uvec3 s = uvec3(
93
+ floatBitsToUint(seedVal),
94
+ floatBitsToUint(seedVal * 1.5 + 7.31),
95
+ floatBitsToUint(seedVal * 2.7 + 13.37)
96
+ );
97
+ s = hash3(s);
98
+ return vec3(s) / float(0xFFFFFFFFu);
99
+ }
100
+
101
+ // === PALETTE SAMPLING ===
102
+ vec3 getColor(int idx) {
103
+ if (u_colors_length < 1) return vec3(0.0);
104
+ int safeIdx = clamp(idx, 0, u_colors_length - 1);
105
+ return u_colors[safeIdx].rgb;
106
+ }
107
+
108
+ vec3 paletteN(float t, int count) {
109
+ if (count < 1) return vec3(0.0);
110
+ if (count < 2) return getColor(0);
111
+ t = clamp(t, 0.0, 1.0) * float(count - 1);
112
+ int idx = min(int(floor(t)), count - 2);
113
+ float localT = fract(t);
114
+ localT = localT * localT * (3.0 - 2.0 * localT);
115
+ return mix(getColor(idx), getColor(idx + 1), localT);
116
+ }
117
+
118
+ // === Gradient Flow ===
119
+ float getGradientT(vec2 uv, float t, vec3 s1, vec3 s2) {
120
+ // Seed-derived flow directions
121
+ float angle1 = s1.x * 6.28;
122
+ float angle2 = s1.y * 6.28;
123
+ vec2 dir1 = vec2(cos(angle1), sin(angle1));
124
+ vec2 dir2 = vec2(cos(angle2), sin(angle2));
125
+
126
+ // Seed-derived frequencies
127
+ float freq1 = 1.0 + s1.z * 2.0;
128
+ float freq2 = 1.0 + s2.x * 1.5;
129
+ float freq3 = 1.5 + s2.y * 2.0;
130
+
131
+ float flow = dot(uv, dir1) + sin(dot(uv, dir2) * freq1 + t) * 0.3 + t * 0.2;
132
+ float flow2 = dot(uv, dir2.yx) + cos(dot(uv, dir1.yx) * freq2 - t * 0.8) * 0.25;
133
+
134
+ float gradT = sin(flow * 1.5) * 0.5 + 0.5;
135
+ gradT += cos(flow2 * 1.2) * 1.3;
136
+ gradT += sin(dot(uv, dir1 + dir2) * freq3 + t * 3.5) * 1.2;
137
+
138
+ return smoothstep(0.0, 4.12, gradT);
139
+ }
140
+
141
+ // === BAND LENS ===
142
+ void applyBandLens(vec2 pp, float radiusSq, float iorOffset, out vec2 warpedUV, out float edgeFactor) {
143
+ vec2 ppLens = pp;
144
+ float spacingX = max(u_lensSpacingX, 0.001);
145
+ float spacingY = max(u_lensSpacingY, 0.001);
146
+ ppLens.x = fract(pp.x / spacingX + 0.5) * spacingX - spacingX * 0.5;
147
+ ppLens.y = fract(pp.y / spacingY + 0.5) * spacingY - spacingY * 0.5;
148
+
149
+ float sp = radiusSq - ppLens.x * ppLens.x - ppLens.y * ppLens.y;
150
+
151
+ float lensAmount = smoothstep(-0.1, 0.05, sp);
152
+ float baseLens = sqrt(max(sp, -sp * 0.1) / 0.3);
153
+ edgeFactor = (1.0 - smoothstep(0.0, radiusSq, sp)) * lensAmount;
154
+
155
+ float warpAmount = mix(1.0, baseLens * (1.0 + iorOffset), lensAmount);
156
+
157
+ warpedUV = pp;
158
+ warpedUV.x += (ppLens.x * warpAmount - ppLens.x);
159
+ warpedUV.y *= warpAmount;
160
+ }
161
+
162
+ void main() {
163
+ vec2 fragCoord = v_uv * u_resolution;
164
+ seed = uvec3(uvec2(fragCoord), uint(fract(u_time) * 1000.0));
165
+
166
+ vec2 r = u_resolution;
167
+ vec2 p = (fragCoord * 2.0 - r) / r.y;
168
+ float t = u_time * u_speed;
169
+
170
+ int colorCount = u_colors_length;
171
+
172
+ // Early out: no colors -> black
173
+ if (colorCount < 1) {
174
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
175
+ return;
176
+ }
177
+
178
+ // Seed-based offsets for gradient flow
179
+ vec3 seedOff1 = seedRandom(u_seed);
180
+ vec3 seedOff2 = seedRandom(u_seed + 100.0);
181
+
182
+ float dice = random3f().x;
183
+
184
+ float radiusSq = u_lensRadius * u_lensRadius;
185
+ vec3 iorOffsets = vec3(-1.0, 0.0, 1.0) * u_dispersionStrength;
186
+
187
+ vec3 col = vec3(0.0);
188
+
189
+ for (int i = 0; i < SAMPLES; i++) {
190
+ float ephemeral = (float(i) + dice) / float(SAMPLES);
191
+ float sqEph = ephemeral * ephemeral;
192
+
193
+ vec2 pt = p;
194
+ pt.x += u_ephemeralAmp * sqEph * sin(p.y * 2.0 + t);
195
+ pt.y += u_ephemeralAmp * sqEph * cos(p.x * 1.5 - t) * 0.5;
196
+ pt.y -= (1.0 - exp(-EPHEMERAL_DRIP * sqEph)) * abs(pt.y) * sign(pt.y) * 0.3;
197
+
198
+ vec3 tint = smoothstep(1.0, 0.0, abs(3.0 * ephemeral - vec3(1.0, 1.5, 2.0)));
199
+
200
+ vec3 gradTs = vec3(0.0);
201
+ vec3 edgeFactors = vec3(0.0);
202
+
203
+ for (int c = 0; c < 3; c++) {
204
+ vec2 pp = pt * u_lensScale;
205
+ vec2 warpedUV;
206
+ float edgeFactor;
207
+ applyBandLens(pp, radiusSq, iorOffsets[c], warpedUV, edgeFactor);
208
+
209
+ vec2 gradUV = warpedUV / u_lensScale;
210
+ gradTs[c] = getGradientT(gradUV, t * 0.8, seedOff1, seedOff2);
211
+ edgeFactors[c] = edgeFactor;
212
+ }
213
+
214
+ vec3 convergentColor = paletteN(gradTs.g, colorCount);
215
+ float edgeMix = max(max(edgeFactors.r, edgeFactors.g), edgeFactors.b);
216
+
217
+ vec3 dispersedColor = vec3(
218
+ paletteN(gradTs.r, colorCount).r,
219
+ convergentColor.g,
220
+ paletteN(gradTs.b, colorCount).b
221
+ );
222
+
223
+ vec3 finalColor = mix(convergentColor, dispersedColor, edgeMix * 2.0);
224
+
225
+ vec3 rainbow = (gradTs - gradTs.g) * 3.0;
226
+ finalColor += rainbow * edgeMix * u_edgeDisp;
227
+
228
+ col += tint * finalColor * (3.0 / float(SAMPLES));
229
+ }
230
+
231
+ fragColor = vec4(col, 1.0);
232
+ }
233
+ `
234
+
235
+ // ---------------------------------------------------------------------------
236
+ // Component
237
+ // ---------------------------------------------------------------------------
238
+
239
+ /**
240
+ * Property controls matching the original Framer DispersionBands module.
241
+ * Ranges, defaults, and step sizes are preserved from the original.
242
+ */
243
+ export const BandsShader = defineShader({
244
+ title: 'BandsShader',
245
+ fragment: FRAGMENT_SOURCE,
246
+ propertyControls: {
247
+ colors: {
248
+ type: 'array',
249
+ control: { type: 'color' },
250
+ maxCount: 8,
251
+ maxVisible: 4,
252
+ defaultValue: ['#4AB7FF', '#000000', '#FF4040'],
253
+ },
254
+ seed: {
255
+ type: 'number',
256
+ defaultValue: 210,
257
+ min: 0,
258
+ max: 1000,
259
+ step: 1,
260
+ },
261
+ speed: {
262
+ type: 'number',
263
+ defaultValue: 0.3,
264
+ min: 0,
265
+ max: 2,
266
+ step: 0.01,
267
+ },
268
+ ephemeralAmp: {
269
+ type: 'number',
270
+ defaultValue: 0,
271
+ min: 0,
272
+ max: 0.5,
273
+ step: 0.01,
274
+ },
275
+ lensScale: {
276
+ type: 'number',
277
+ defaultValue: 3.7,
278
+ min: 0.1,
279
+ max: 10,
280
+ step: 0.1,
281
+ },
282
+ lensSpacingX: {
283
+ type: 'number',
284
+ defaultValue: 1,
285
+ min: 0.01,
286
+ max: 5,
287
+ step: 0.01,
288
+ },
289
+ lensSpacingY: {
290
+ type: 'number',
291
+ defaultValue: 0.01,
292
+ min: 0.01,
293
+ max: 5,
294
+ step: 0.01,
295
+ hidden: true,
296
+ },
297
+ lensRadius: {
298
+ type: 'number',
299
+ defaultValue: 0.58,
300
+ min: 0.1,
301
+ max: 2,
302
+ step: 0.01,
303
+ },
304
+ dispersionStrength: {
305
+ type: 'number',
306
+ defaultValue: 0.4,
307
+ min: 0,
308
+ max: 1,
309
+ step: 0.01,
310
+ },
311
+ edgeDisp: {
312
+ type: 'number',
313
+ defaultValue: 2,
314
+ min: 0,
315
+ max: 5,
316
+ step: 0.1,
317
+ },
318
+ },
319
+ }) as React.FC<BandsShaderProps>