egaki 0.6.0 → 0.7.0
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.
- package/CHANGELOG.md +140 -9
- package/dist/cli/cache-utils.d.ts +33 -0
- package/dist/cli/cache-utils.d.ts.map +1 -0
- package/dist/cli/cache-utils.js +157 -0
- package/dist/cli/cached-generate.d.ts +105 -0
- package/dist/cli/cached-generate.d.ts.map +1 -0
- package/dist/cli/cached-generate.js +208 -0
- package/dist/cli/cached-generate.test.d.ts +11 -0
- package/dist/cli/cached-generate.test.d.ts.map +1 -0
- package/dist/cli/cached-generate.test.js +431 -0
- package/dist/cli/cartesia-provider.d.ts +16 -0
- package/dist/cli/cartesia-provider.d.ts.map +1 -0
- package/dist/cli/cartesia-provider.js +184 -0
- package/dist/cli/chatgpt-auth.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/{cli.js → cli/cli.js} +626 -600
- package/dist/cli/clone-generate.d.ts +26 -0
- package/dist/cli/clone-generate.d.ts.map +1 -0
- package/dist/cli/clone-generate.js +148 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/{credentials.js → cli/credentials.js} +20 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
- package/dist/cli/elevenlabs-speech-provider.js +199 -0
- package/dist/cli/generate.d.ts +140 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +604 -0
- package/dist/cli/generate.test.d.ts +2 -0
- package/dist/cli/generate.test.d.ts.map +1 -0
- package/dist/cli/generate.test.js +131 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +7 -0
- package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
- package/dist/cli/model-catalog.d.ts.map +1 -0
- package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
- package/dist/{models.d.ts → cli/models.d.ts} +12 -5
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/{models.js → cli/models.js} +58 -57
- package/dist/cli/open-browser.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.d.ts +3 -0
- package/dist/cli/openai-speech-provider.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.js +28 -0
- package/dist/cli/separation-generate.d.ts +34 -0
- package/dist/cli/separation-generate.d.ts.map +1 -0
- package/dist/cli/separation-generate.js +117 -0
- package/dist/cli/speech-catalog.d.ts +35 -0
- package/dist/cli/speech-catalog.d.ts.map +1 -0
- package/dist/cli/speech-catalog.js +195 -0
- package/dist/cli/speech-generate.d.ts +86 -0
- package/dist/cli/speech-generate.d.ts.map +1 -0
- package/dist/cli/speech-generate.js +156 -0
- package/dist/cli/speech-models.d.ts +8 -0
- package/dist/cli/speech-models.d.ts.map +1 -0
- package/dist/cli/speech-models.js +109 -0
- package/dist/cli/speech-provider.test.d.ts +2 -0
- package/dist/cli/speech-provider.test.d.ts.map +1 -0
- package/dist/cli/speech-provider.test.js +197 -0
- package/dist/cli/subscription.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.d.ts +35 -0
- package/dist/cli/transcription-catalog.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.js +192 -0
- package/dist/cli/transcription-generate.d.ts +62 -0
- package/dist/cli/transcription-generate.d.ts.map +1 -0
- package/dist/cli/transcription-generate.js +144 -0
- package/dist/cli/transcription-models.d.ts +9 -0
- package/dist/cli/transcription-models.d.ts.map +1 -0
- package/dist/cli/transcription-models.js +100 -0
- package/dist/cli/transcription-providers.d.ts +22 -0
- package/dist/cli/transcription-providers.d.ts.map +1 -0
- package/dist/cli/transcription-providers.js +290 -0
- package/dist/cli/video-model-catalog.d.ts.map +1 -0
- package/dist/cli/xai-auth.d.ts.map +1 -0
- package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
- package/dist/vite/angled-screen.d.ts +57 -0
- package/dist/vite/angled-screen.d.ts.map +1 -0
- package/dist/vite/angled-screen.js +115 -0
- package/dist/vite/app.d.ts +51 -0
- package/dist/vite/app.d.ts.map +1 -0
- package/dist/vite/app.js +150 -0
- package/dist/vite/bands-shader.d.ts +47 -0
- package/dist/vite/bands-shader.d.ts.map +1 -0
- package/dist/vite/bands-shader.js +267 -0
- package/dist/vite/code-block.d.ts +107 -0
- package/dist/vite/code-block.d.ts.map +1 -0
- package/dist/vite/code-block.js +641 -0
- package/dist/vite/components.d.ts +36 -0
- package/dist/vite/components.d.ts.map +1 -0
- package/dist/vite/components.js +113 -0
- package/dist/vite/dispersion-rings-shader.d.ts +44 -0
- package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
- package/dist/vite/dispersion-rings-shader.js +282 -0
- package/dist/vite/easing-curves.d.ts +129 -0
- package/dist/vite/easing-curves.d.ts.map +1 -0
- package/dist/vite/easing-curves.js +584 -0
- package/dist/vite/easing-curves.test.d.ts +2 -0
- package/dist/vite/easing-curves.test.d.ts.map +1 -0
- package/dist/vite/easing-curves.test.js +200 -0
- package/dist/vite/generated-media-client.d.ts +35 -0
- package/dist/vite/generated-media-client.d.ts.map +1 -0
- package/dist/vite/generated-media-client.js +76 -0
- package/dist/vite/keyframes.d.ts +129 -0
- package/dist/vite/keyframes.d.ts.map +1 -0
- package/dist/vite/keyframes.js +194 -0
- package/dist/vite/layout-editor.d.ts +45 -0
- package/dist/vite/layout-editor.d.ts.map +1 -0
- package/dist/vite/layout-editor.js +587 -0
- package/dist/vite/layout-transition.d.ts +136 -0
- package/dist/vite/layout-transition.d.ts.map +1 -0
- package/dist/vite/layout-transition.js +581 -0
- package/dist/vite/liquid-gradient-shader.d.ts +62 -0
- package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
- package/dist/vite/liquid-gradient-shader.js +413 -0
- package/dist/vite/mdx-client.d.ts +15 -0
- package/dist/vite/mdx-client.d.ts.map +1 -0
- package/dist/vite/mdx-client.js +265 -0
- package/dist/vite/mdx-parse.d.ts +102 -0
- package/dist/vite/mdx-parse.d.ts.map +1 -0
- package/dist/vite/mdx-parse.js +251 -0
- package/dist/vite/mdx-provided-components.d.ts +18 -0
- package/dist/vite/mdx-provided-components.d.ts.map +1 -0
- package/dist/vite/mdx-provided-components.js +14 -0
- package/dist/vite/mdx-video.d.ts +327 -0
- package/dist/vite/mdx-video.d.ts.map +1 -0
- package/dist/vite/mdx-video.js +596 -0
- package/dist/vite/mdx-video.test.d.ts +9 -0
- package/dist/vite/mdx-video.test.d.ts.map +1 -0
- package/dist/vite/mdx-video.test.js +1945 -0
- package/dist/vite/media-components.d.ts +45 -0
- package/dist/vite/media-components.d.ts.map +1 -0
- package/dist/vite/media-components.js +355 -0
- package/dist/vite/media-duration-store.d.ts +66 -0
- package/dist/vite/media-duration-store.d.ts.map +1 -0
- package/dist/vite/media-duration-store.js +204 -0
- package/dist/vite/player-page.d.ts +35 -0
- package/dist/vite/player-page.d.ts.map +1 -0
- package/dist/vite/player-page.js +720 -0
- package/dist/vite/render-client.d.ts +18 -0
- package/dist/vite/render-client.d.ts.map +1 -0
- package/dist/vite/render-client.js +67 -0
- package/dist/vite/sdk.d.ts +221 -0
- package/dist/vite/sdk.d.ts.map +1 -0
- package/dist/vite/sdk.js +355 -0
- package/dist/vite/server-components.d.ts +55 -0
- package/dist/vite/server-components.d.ts.map +1 -0
- package/dist/vite/server-components.js +156 -0
- package/dist/vite/server-mdx.d.ts +74 -0
- package/dist/vite/server-mdx.d.ts.map +1 -0
- package/dist/vite/server-mdx.js +259 -0
- package/dist/vite/shader-renderer.d.ts +48 -0
- package/dist/vite/shader-renderer.d.ts.map +1 -0
- package/dist/vite/shader-renderer.js +411 -0
- package/dist/vite/store-hooks.d.ts +12 -0
- package/dist/vite/store-hooks.d.ts.map +1 -0
- package/dist/vite/store-hooks.js +93 -0
- package/dist/vite/store.d.ts +75 -0
- package/dist/vite/store.d.ts.map +1 -0
- package/dist/vite/store.js +52 -0
- package/dist/vite/store.test.d.ts +6 -0
- package/dist/vite/store.test.d.ts.map +1 -0
- package/dist/vite/store.test.js +172 -0
- package/dist/vite/tweakpane-hook.d.ts +94 -0
- package/dist/vite/tweakpane-hook.d.ts.map +1 -0
- package/dist/vite/tweakpane-hook.js +450 -0
- package/dist/vite/vite-plugin.d.ts +28 -0
- package/dist/vite/vite-plugin.d.ts.map +1 -0
- package/dist/vite/vite-plugin.js +538 -0
- package/dist/vite/wave-gradient-shader.d.ts +41 -0
- package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
- package/dist/vite/wave-gradient-shader.js +207 -0
- package/package.json +101 -24
- package/skills/egaki/SKILL.md +162 -1
- package/src/cli/cache-utils.ts +169 -0
- package/src/cli/cached-generate.test.ts +531 -0
- package/src/cli/cached-generate.ts +348 -0
- package/src/cli/cartesia-provider.ts +249 -0
- package/src/{cli.ts → cli/cli.ts} +836 -884
- package/src/cli/clone-generate.ts +202 -0
- package/src/{credentials.ts → cli/credentials.ts} +20 -0
- package/src/cli/elevenlabs-speech-provider.ts +243 -0
- package/src/cli/generate.test.ts +166 -0
- package/src/cli/generate.ts +912 -0
- package/src/cli/main.ts +8 -0
- package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
- package/src/{models.ts → cli/models.ts} +65 -86
- package/src/cli/openai-speech-provider.ts +34 -0
- package/src/cli/separation-generate.ts +187 -0
- package/src/cli/speech-catalog.ts +253 -0
- package/src/cli/speech-generate.ts +275 -0
- package/src/cli/speech-models.ts +146 -0
- package/src/cli/speech-provider.test.ts +226 -0
- package/src/cli/transcription-catalog.ts +250 -0
- package/src/cli/transcription-generate.ts +214 -0
- package/src/cli/transcription-models.ts +136 -0
- package/src/cli/transcription-providers.ts +427 -0
- package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
- package/src/vite/angled-screen.tsx +214 -0
- package/src/vite/app.tsx +197 -0
- package/src/vite/bands-shader.tsx +319 -0
- package/src/vite/code-block.tsx +939 -0
- package/src/vite/components.tsx +278 -0
- package/src/vite/dispersion-rings-shader.tsx +331 -0
- package/src/vite/easing-curves.test.ts +232 -0
- package/src/vite/easing-curves.ts +743 -0
- package/src/vite/generated-media-client.tsx +121 -0
- package/src/vite/keyframes.tsx +347 -0
- package/src/vite/layout-editor.tsx +709 -0
- package/src/vite/layout-transition.tsx +706 -0
- package/src/vite/liquid-gradient-shader.tsx +474 -0
- package/src/vite/mdx-client.tsx +420 -0
- package/src/vite/mdx-parse.ts +343 -0
- package/src/vite/mdx-provided-components.ts +19 -0
- package/src/vite/mdx-video.test.tsx +2219 -0
- package/src/vite/mdx-video.tsx +976 -0
- package/src/vite/media-components.tsx +473 -0
- package/src/vite/media-duration-store.ts +225 -0
- package/src/vite/motion-timing.ts +194 -0
- package/src/vite/player-page.tsx +1107 -0
- package/src/vite/render-client.ts +84 -0
- package/src/vite/sdk.ts +598 -0
- package/src/vite/server-components.tsx +241 -0
- package/src/vite/server-mdx.ts +285 -0
- package/src/vite/shader-renderer.tsx +535 -0
- package/src/vite/store-hooks.ts +117 -0
- package/src/vite/store.test.ts +202 -0
- package/src/vite/store.ts +115 -0
- package/src/vite/styles.css +21 -0
- package/src/vite/tweakpane-hook.tsx +593 -0
- package/src/vite/virtual-modules.d.ts +30 -0
- package/src/vite/vite-plugin.ts +584 -0
- package/src/vite/wave-gradient-shader.tsx +253 -0
- package/README.md +0 -370
- package/dist/antigravity-auth.d.ts +0 -15
- package/dist/antigravity-auth.d.ts.map +0 -1
- package/dist/antigravity-auth.js +0 -544
- package/dist/antigravity-image.d.ts +0 -11
- package/dist/antigravity-image.d.ts.map +0 -1
- package/dist/antigravity-image.js +0 -285
- package/dist/chatgpt-auth.d.ts.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.d.ts +0 -11
- package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.js +0 -64
- package/dist/login.d.ts.map +0 -1
- package/dist/model-catalog.d.ts.map +0 -1
- package/dist/models.d.ts.map +0 -1
- package/dist/open-browser.d.ts.map +0 -1
- package/dist/subscription.d.ts.map +0 -1
- package/dist/video-model-catalog.d.ts.map +0 -1
- package/dist/xai-auth.d.ts.map +0 -1
- /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
- /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
- /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
- /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
- /package/dist/{login.js → cli/login.js} +0 -0
- /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
- /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
- /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
- /package/dist/{subscription.js → cli/subscription.js} +0 -0
- /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
- /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
- /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
- /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
- /package/src/{login.ts → cli/login.ts} +0 -0
- /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
- /package/src/{subscription.ts → cli/subscription.ts} +0 -0
- /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LiquidGradientShader — animated liquid turbulence gradient with Oklab color mixing.
|
|
5
|
+
*
|
|
6
|
+
* Port of Framer's LiquidGradient shader module for Remotion/egaki.
|
|
7
|
+
* Original source:
|
|
8
|
+
* https://framerusercontent.com/modules/QEytd7xyjUsL7yuVUzSs/O7s2vxltmhiskELYwyrY/LiquidGradient.js
|
|
9
|
+
*
|
|
10
|
+
* A multi-color gradient is warped through seed-dependent turbulence with
|
|
11
|
+
* configurable amplitude, frequency, and iteration count. Colors are mixed
|
|
12
|
+
* in Oklab/LCH perceptual color space for smooth, natural transitions.
|
|
13
|
+
* Post-processing includes soft gamut mapping, exposure, contrast, and
|
|
14
|
+
* saturation controls. Optional dithering (IGN smooth or grain noise)
|
|
15
|
+
* reduces banding artifacts.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { CSSProperties } from 'react'
|
|
19
|
+
import { defineShader } from './shader-renderer.tsx'
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Props
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
export interface LiquidGradientShaderProps {
|
|
26
|
+
/** Color palette for the gradient (max 8). Hex strings like "#2962FF". */
|
|
27
|
+
colors?: string[]
|
|
28
|
+
/** Seed for turbulence variation. Different seeds = different flow patterns. */
|
|
29
|
+
seed?: number
|
|
30
|
+
/** Animation speed multiplier. 0 = frozen, 0.3 = default, 2 = fast. */
|
|
31
|
+
speed?: number
|
|
32
|
+
/** Loop duration in seconds. 0 = no loop, >0 = seamless loop over that many seconds. */
|
|
33
|
+
loop?: number
|
|
34
|
+
/** UV scale of the turbulence field. Higher = more zoomed in. */
|
|
35
|
+
scale?: number
|
|
36
|
+
/** Turbulence amplitude. Controls how far the flow displaces colors. */
|
|
37
|
+
turbAmp?: number
|
|
38
|
+
/** Turbulence frequency. Controls the spacing of turbulence waves. */
|
|
39
|
+
turbFreq?: number
|
|
40
|
+
/** Turbulence iteration count. Higher = more detail, more GPU cost. */
|
|
41
|
+
turbIter?: number
|
|
42
|
+
/** Wave frequency for the final color band mapping. */
|
|
43
|
+
waveFreq?: number
|
|
44
|
+
/** Distribution bias. Shifts where color bands fall in the gradient. */
|
|
45
|
+
distBias?: number
|
|
46
|
+
/** Jellify mode (0 or 1). Squashes one axis for a jelly-like feel. */
|
|
47
|
+
jellify?: number
|
|
48
|
+
/** Dither mode: 0 = Off, 1 = Smooth (IGN), 2 = Grain (quick noise). */
|
|
49
|
+
ditherMode?: number
|
|
50
|
+
/** Dither amount. Higher = more visible noise to fight banding. */
|
|
51
|
+
dither?: number
|
|
52
|
+
/** Exposure multiplier. Brightens or darkens the overall output. */
|
|
53
|
+
exposure?: number
|
|
54
|
+
/** Contrast adjustment applied in Oklab space. */
|
|
55
|
+
contrast?: number
|
|
56
|
+
/** Saturation adjustment applied in Oklab space. */
|
|
57
|
+
saturation?: number
|
|
58
|
+
style?: CSSProperties
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Fragment shader body
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Raw GLSL fragment body from LiquidGradient.js.
|
|
67
|
+
* The defineShader engine prepends #version, precision, v_uv, fragColor,
|
|
68
|
+
* uniform declarations, and built-in uniforms automatically.
|
|
69
|
+
*
|
|
70
|
+
* Algorithm overview:
|
|
71
|
+
* 1. PCG hash seeding: seed-derived offsets and rotation create a unique
|
|
72
|
+
* flow pattern per seed value
|
|
73
|
+
* 2. Turbulence: 4 ephemeral layers, each with up to 13 sine-wave
|
|
74
|
+
* iterations that warp UV coordinates through amplitude-modulated
|
|
75
|
+
* displacement. Optional jellify mode squashes one axis
|
|
76
|
+
* 3. Color mapping: turbulence value maps through paletteN() which
|
|
77
|
+
* interpolates user colors in Oklab LCH space for perceptually
|
|
78
|
+
* uniform, hue-preserving gradients
|
|
79
|
+
* 4. Dithering: IGN (smooth) or quick noise (grain) reduces banding
|
|
80
|
+
* 5. Post-processing: exposure, contrast/saturation in Oklab, and soft
|
|
81
|
+
* gamut mapping to clamp out-of-range colors gracefully
|
|
82
|
+
*/
|
|
83
|
+
const FRAGMENT_SOURCE = `
|
|
84
|
+
// === CONSTANTS ===
|
|
85
|
+
const float GOLDEN_ANGLE = 2.3999632;
|
|
86
|
+
const float TAU = 6.28318530;
|
|
87
|
+
|
|
88
|
+
// === PCG hash - https://www.jcgt.org/published/0009/03/02/
|
|
89
|
+
uvec3 hash3(uvec3 v) {
|
|
90
|
+
v = v * 1664525u + 1013904223u;
|
|
91
|
+
v.x += v.y * v.z;
|
|
92
|
+
v.y += v.z * v.x;
|
|
93
|
+
v.z += v.x * v.y;
|
|
94
|
+
v ^= v >> 16u;
|
|
95
|
+
v.x += v.y * v.z;
|
|
96
|
+
v.y += v.z * v.x;
|
|
97
|
+
v.z += v.x * v.y;
|
|
98
|
+
return v;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Seed
|
|
102
|
+
vec3 seedRandom(float seedVal) {
|
|
103
|
+
uvec3 s = uvec3(
|
|
104
|
+
floatBitsToUint(seedVal),
|
|
105
|
+
floatBitsToUint(seedVal * 1.5 + 7.31),
|
|
106
|
+
floatBitsToUint(seedVal * 2.7 + 13.37)
|
|
107
|
+
);
|
|
108
|
+
s = hash3(s);
|
|
109
|
+
return vec3(s) / float(0xFFFFFFFFu);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// === COLOR SPACE UTILITIES ===
|
|
113
|
+
vec3 toLinear(vec3 c) {
|
|
114
|
+
return pow(c, vec3(2.2));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
vec3 toSrgb(vec3 c) {
|
|
118
|
+
return pow(clamp(c, 0.0, 1.0), vec3(0.4545));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
vec3 linearToOklab(vec3 c) {
|
|
122
|
+
float l = 0.4122214708 * c.r + 0.5363325363 * c.g + 0.0514459929 * c.b;
|
|
123
|
+
float m = 0.2119034982 * c.r + 0.6806995451 * c.g + 0.1073969566 * c.b;
|
|
124
|
+
float s = 0.0883024619 * c.r + 0.2817188376 * c.g + 0.6299787005 * c.b;
|
|
125
|
+
|
|
126
|
+
l = pow(max(l, 0.0), 1.0/3.0);
|
|
127
|
+
m = pow(max(m, 0.0), 1.0/3.0);
|
|
128
|
+
s = pow(max(s, 0.0), 1.0/3.0);
|
|
129
|
+
|
|
130
|
+
return vec3(
|
|
131
|
+
0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,
|
|
132
|
+
1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,
|
|
133
|
+
0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
vec3 oklabToLinear(vec3 c) {
|
|
138
|
+
float l = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
|
|
139
|
+
float m = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
|
|
140
|
+
float s = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
|
|
141
|
+
|
|
142
|
+
l = l * l * l;
|
|
143
|
+
m = m * m * m;
|
|
144
|
+
s = s * s * s;
|
|
145
|
+
|
|
146
|
+
return vec3(
|
|
147
|
+
+4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
148
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
149
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
vec3 oklabToLch(vec3 lab) {
|
|
154
|
+
return vec3(lab.x, length(lab.yz), atan(lab.z, lab.y));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
vec3 lchToOklab(vec3 lch) {
|
|
158
|
+
return vec3(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
vec3 mixLch(vec3 lab0, vec3 lab1, float t) {
|
|
162
|
+
vec3 lch0 = oklabToLch(lab0);
|
|
163
|
+
vec3 lch1 = oklabToLch(lab1);
|
|
164
|
+
|
|
165
|
+
if (lch0.y < 0.05) lch0.z = lch1.z;
|
|
166
|
+
if (lch1.y < 0.05) lch1.z = lch0.z;
|
|
167
|
+
|
|
168
|
+
float dh = lch1.z - lch0.z;
|
|
169
|
+
if (dh > 3.14159265) dh -= 6.28318530;
|
|
170
|
+
if (dh < -3.14159265) dh += 6.28318530;
|
|
171
|
+
|
|
172
|
+
return lchToOklab(vec3(
|
|
173
|
+
mix(lch0.x, lch1.x, t),
|
|
174
|
+
mix(lch0.y, lch1.y, t),
|
|
175
|
+
lch0.z + dh * t
|
|
176
|
+
));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// === PALETTE SAMPLING ===
|
|
180
|
+
vec3 getColor(int idx) {
|
|
181
|
+
if (u_colors_length < 1) return vec3(0.0);
|
|
182
|
+
int safeIdx = clamp(idx, 0, u_colors_length - 1);
|
|
183
|
+
return u_colors[safeIdx].rgb;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
vec3 paletteN(float t, int count) {
|
|
187
|
+
if (count < 1) return vec3(0.0);
|
|
188
|
+
if (count < 2) return toLinear(getColor(0));
|
|
189
|
+
|
|
190
|
+
float segmentSize = 1.0 / float(count - 1);
|
|
191
|
+
t = clamp(t, 0.0, 1.0);
|
|
192
|
+
int idx = min(int(floor(t / segmentSize)), count - 2);
|
|
193
|
+
float localT = clamp((t - float(idx) * segmentSize) / segmentSize, 0.0, 1.0);
|
|
194
|
+
|
|
195
|
+
vec3 lab0 = linearToOklab(toLinear(getColor(idx)));
|
|
196
|
+
vec3 lab1 = linearToOklab(toLinear(getColor(idx + 1)));
|
|
197
|
+
|
|
198
|
+
return oklabToLinear(mixLch(lab0, lab1, localT));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// === DITHER ===
|
|
202
|
+
float IGN(vec2 uv) {
|
|
203
|
+
return fract(52.9829189 * fract(dot(uv, vec2(0.06711056, 0.00583715))));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
float quickNoise(vec2 I) {
|
|
207
|
+
return fract(sin(dot(I, vec2(12.9898, 78.233))) * 43758.5453);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Dither Mode: 0=Off, 1=IGN, 2=quickNoise
|
|
211
|
+
float getDither(vec2 I, float mode) {
|
|
212
|
+
if (mode < 0.5) return 0.5; // 0: Off
|
|
213
|
+
if (mode < 1.5) return IGN(I); // 1: Smooth
|
|
214
|
+
return quickNoise(I); // 2: Grain
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// === POST-PROCESS ===
|
|
218
|
+
vec3 softGamutMap(vec3 linearRgb) {
|
|
219
|
+
float maxC = max(linearRgb.r, max(linearRgb.g, linearRgb.b));
|
|
220
|
+
float minC = min(linearRgb.r, min(linearRgb.g, linearRgb.b));
|
|
221
|
+
|
|
222
|
+
if (minC >= 0.0 && maxC <= 1.0) return linearRgb;
|
|
223
|
+
|
|
224
|
+
vec3 lab = linearToOklab(max(linearRgb, 0.0));
|
|
225
|
+
float L = clamp(lab.x, 0.0, 1.0);
|
|
226
|
+
float C = length(lab.yz);
|
|
227
|
+
float h = atan(lab.z, lab.y);
|
|
228
|
+
|
|
229
|
+
float maxChroma = 0.4 * (1.0 - pow(abs(2.0 * L - 1.0), 2.0));
|
|
230
|
+
|
|
231
|
+
if (C > maxChroma * 0.7) {
|
|
232
|
+
float knee = maxChroma * 0.7;
|
|
233
|
+
C = knee + (maxChroma - knee) * tanh((C - knee) / (maxChroma - knee + 0.001));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return clamp(oklabToLinear(vec3(L, C * cos(h), C * sin(h))), 0.0, 1.0);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
vec3 applyContrastSaturation(vec3 linearRgb, float contrast, float saturation) {
|
|
240
|
+
vec3 lab = linearToOklab(linearRgb);
|
|
241
|
+
float C = length(lab.yz);
|
|
242
|
+
float h = atan(lab.z, lab.y);
|
|
243
|
+
|
|
244
|
+
lab.x = clamp((lab.x - 0.5) * contrast + 0.5, 0.0, 1.0);
|
|
245
|
+
C *= saturation;
|
|
246
|
+
lab.y = C * cos(h);
|
|
247
|
+
lab.z = C * sin(h);
|
|
248
|
+
|
|
249
|
+
return oklabToLinear(lab);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// === MAIN ===
|
|
253
|
+
void main() {
|
|
254
|
+
vec2 fragCoord = v_uv * u_resolution;
|
|
255
|
+
vec2 r = u_resolution;
|
|
256
|
+
vec2 p = (fragCoord * 2.0 - r) / r.y;
|
|
257
|
+
|
|
258
|
+
int colorCount = u_colors_length;
|
|
259
|
+
|
|
260
|
+
// Early out: no colors -> black
|
|
261
|
+
if (colorCount < 1) {
|
|
262
|
+
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
float t = u_time * 0.3;
|
|
267
|
+
|
|
268
|
+
// Map time onto a circle so animation seamlessly wraps.
|
|
269
|
+
float looping = step(0.5, u_loop);
|
|
270
|
+
float phase = TAU * u_time / max(u_loop, 0.01);
|
|
271
|
+
float radius = u_loop * u_speed * 0.3 / TAU;
|
|
272
|
+
float tA = sin(phase) * radius;
|
|
273
|
+
float tB = (1.0 - cos(phase)) * radius;
|
|
274
|
+
|
|
275
|
+
// Seed-based offsets
|
|
276
|
+
vec3 seedOffset = seedRandom(u_seed);
|
|
277
|
+
vec3 seedOffset2 = seedRandom(u_seed + 100.0);
|
|
278
|
+
|
|
279
|
+
// Golden angle rotation
|
|
280
|
+
float seedAngle = u_seed * GOLDEN_ANGLE;
|
|
281
|
+
vec2 seedPhase = (seedOffset2.xy - 0.5) * TAU;
|
|
282
|
+
|
|
283
|
+
// Seed-based rotation
|
|
284
|
+
float cs = cos(seedAngle);
|
|
285
|
+
float sn = sin(seedAngle);
|
|
286
|
+
p = mat2(cs, -sn, sn, cs) * p;
|
|
287
|
+
|
|
288
|
+
// Get dither value
|
|
289
|
+
float dither = getDither(floor(fragCoord / u_pixelRatio), u_ditherMode);
|
|
290
|
+
|
|
291
|
+
// === TURBULENCE ===
|
|
292
|
+
float totalVal = 0.0;
|
|
293
|
+
float totalWeight = 0.0;
|
|
294
|
+
int turbIter = int(u_turbIter);
|
|
295
|
+
|
|
296
|
+
float freq = 1.0 / max(u_turbFreq, 0.01);
|
|
297
|
+
|
|
298
|
+
for (float i = 0.0; i < 4.0; i++) {
|
|
299
|
+
float eph = i / 4.0;
|
|
300
|
+
|
|
301
|
+
vec2 q = p * u_scale;
|
|
302
|
+
float sq = eph * eph;
|
|
303
|
+
|
|
304
|
+
if (u_jellify > 0.5) {
|
|
305
|
+
q.yx *= mix(1.0, 0.5, 1.0 - exp(-sq));
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
float a = seedPhase.x;
|
|
309
|
+
float d = seedPhase.y;
|
|
310
|
+
|
|
311
|
+
for (int j = 2; j < 13; j++) {
|
|
312
|
+
if (j >= turbIter) break;
|
|
313
|
+
float fj = float(j);
|
|
314
|
+
// When looping, use circular time. Otherwise original t.
|
|
315
|
+
float t1 = mix(t * u_speed, tA, looping);
|
|
316
|
+
float t2 = mix(t * u_speed, tB, looping);
|
|
317
|
+
q += u_turbAmp * sin(q.yx / freq * fj + t1 + vec2(a, d) + seedOffset.xy * fj) / fj;
|
|
318
|
+
a += cos(fj + d * 1.2 + q.x * 2.0 - t1 + seedOffset2.z + t2 * 0.3 * looping);
|
|
319
|
+
d += sin(fj * q.y + a + seedOffset.z + t1 + seedOffset2.y + t2 * 0.3 * looping);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
float v = 0.5 + 0.5 * sin(length(q.yx + vec2(a, d) * 0.2) * u_waveFreq + i * i + seedOffset.x);
|
|
323
|
+
float weight = smoothstep(0.0, 0.5, eph) * smoothstep(1.0, 0.5, eph);
|
|
324
|
+
totalVal += v * weight;
|
|
325
|
+
totalWeight += weight;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
float val = totalVal / totalWeight;
|
|
329
|
+
val = clamp((val - 0.3) / 0.4, 0.0, 1.0);
|
|
330
|
+
val = pow(val, exp(-u_distBias));
|
|
331
|
+
val = clamp(val + (dither - 0.5) * u_dither, 0.0, 1.0);
|
|
332
|
+
|
|
333
|
+
vec3 col = paletteN(val, colorCount);
|
|
334
|
+
col *= u_exposure;
|
|
335
|
+
col = applyContrastSaturation(col, u_contrast, u_saturation);
|
|
336
|
+
col = softGamutMap(col);
|
|
337
|
+
col = toSrgb(col);
|
|
338
|
+
|
|
339
|
+
fragColor = vec4(col, 1.0);
|
|
340
|
+
}
|
|
341
|
+
`
|
|
342
|
+
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
// Component
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Property controls matching the original Framer LiquidGradient module.
|
|
349
|
+
* Ranges, defaults, and step sizes are preserved from the original.
|
|
350
|
+
*
|
|
351
|
+
* Notes on type mapping:
|
|
352
|
+
* - `jellify` is a Framer Boolean; mapped to a number 0/1 toggle since
|
|
353
|
+
* defineShader only supports number controls. The GLSL uses `> 0.5`.
|
|
354
|
+
* - `ditherMode` is a Framer Enum [0,1,2]; mapped to a number with step 1.
|
|
355
|
+
* - `loop` default 0 means no looping; values > 0 set the loop duration.
|
|
356
|
+
*/
|
|
357
|
+
export const LiquidGradientShader = defineShader({
|
|
358
|
+
title: 'LiquidGradientShader',
|
|
359
|
+
fragment: FRAGMENT_SOURCE,
|
|
360
|
+
propertyControls: {
|
|
361
|
+
colors: {
|
|
362
|
+
type: 'array',
|
|
363
|
+
control: { type: 'color' },
|
|
364
|
+
maxCount: 8,
|
|
365
|
+
maxVisible: 8,
|
|
366
|
+
defaultValue: ['#00001A', '#2962FF', '#40BCFF', '#FFB8B5', '#FFC14F'],
|
|
367
|
+
},
|
|
368
|
+
seed: {
|
|
369
|
+
type: 'number',
|
|
370
|
+
defaultValue: 648,
|
|
371
|
+
min: 0,
|
|
372
|
+
max: 1000,
|
|
373
|
+
step: 1,
|
|
374
|
+
},
|
|
375
|
+
speed: {
|
|
376
|
+
type: 'number',
|
|
377
|
+
defaultValue: 0.3,
|
|
378
|
+
min: 0,
|
|
379
|
+
max: 2,
|
|
380
|
+
step: 0.01,
|
|
381
|
+
},
|
|
382
|
+
loop: {
|
|
383
|
+
type: 'number',
|
|
384
|
+
defaultValue: 0,
|
|
385
|
+
min: 0,
|
|
386
|
+
max: 60,
|
|
387
|
+
step: 0.5,
|
|
388
|
+
},
|
|
389
|
+
scale: {
|
|
390
|
+
type: 'number',
|
|
391
|
+
defaultValue: 0.42,
|
|
392
|
+
min: 0.1,
|
|
393
|
+
max: 2,
|
|
394
|
+
step: 0.01,
|
|
395
|
+
},
|
|
396
|
+
turbAmp: {
|
|
397
|
+
type: 'number',
|
|
398
|
+
defaultValue: 0.6,
|
|
399
|
+
min: 0,
|
|
400
|
+
max: 1,
|
|
401
|
+
step: 0.01,
|
|
402
|
+
},
|
|
403
|
+
turbFreq: {
|
|
404
|
+
type: 'number',
|
|
405
|
+
defaultValue: 0.1,
|
|
406
|
+
min: 0.1,
|
|
407
|
+
max: 2,
|
|
408
|
+
step: 0.01,
|
|
409
|
+
},
|
|
410
|
+
turbIter: {
|
|
411
|
+
type: 'number',
|
|
412
|
+
defaultValue: 7,
|
|
413
|
+
min: 3,
|
|
414
|
+
max: 10,
|
|
415
|
+
step: 1,
|
|
416
|
+
},
|
|
417
|
+
waveFreq: {
|
|
418
|
+
type: 'number',
|
|
419
|
+
defaultValue: 3.8,
|
|
420
|
+
min: 0.1,
|
|
421
|
+
max: 5,
|
|
422
|
+
step: 0.1,
|
|
423
|
+
},
|
|
424
|
+
distBias: {
|
|
425
|
+
type: 'number',
|
|
426
|
+
defaultValue: 0,
|
|
427
|
+
min: -1,
|
|
428
|
+
max: 1,
|
|
429
|
+
step: 0.1,
|
|
430
|
+
},
|
|
431
|
+
jellify: {
|
|
432
|
+
type: 'number',
|
|
433
|
+
defaultValue: 0,
|
|
434
|
+
min: 0,
|
|
435
|
+
max: 1,
|
|
436
|
+
step: 1,
|
|
437
|
+
},
|
|
438
|
+
ditherMode: {
|
|
439
|
+
type: 'number',
|
|
440
|
+
defaultValue: 0,
|
|
441
|
+
min: 0,
|
|
442
|
+
max: 2,
|
|
443
|
+
step: 1,
|
|
444
|
+
},
|
|
445
|
+
dither: {
|
|
446
|
+
type: 'number',
|
|
447
|
+
defaultValue: 0.05,
|
|
448
|
+
min: 0,
|
|
449
|
+
max: 0.2,
|
|
450
|
+
step: 0.01,
|
|
451
|
+
},
|
|
452
|
+
exposure: {
|
|
453
|
+
type: 'number',
|
|
454
|
+
defaultValue: 1.1,
|
|
455
|
+
min: 0.5,
|
|
456
|
+
max: 2,
|
|
457
|
+
step: 0.1,
|
|
458
|
+
},
|
|
459
|
+
contrast: {
|
|
460
|
+
type: 'number',
|
|
461
|
+
defaultValue: 1.1,
|
|
462
|
+
min: 0.5,
|
|
463
|
+
max: 2,
|
|
464
|
+
step: 0.1,
|
|
465
|
+
},
|
|
466
|
+
saturation: {
|
|
467
|
+
type: 'number',
|
|
468
|
+
defaultValue: 1,
|
|
469
|
+
min: 0,
|
|
470
|
+
max: 2,
|
|
471
|
+
step: 0.1,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
}) as React.FC<LiquidGradientShaderProps>
|