shaders-oneshot 0.0.81-shared.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.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +7 -0
- package/dist/empty-pixel.d.ts +1 -0
- package/dist/empty-pixel.js +10 -0
- package/dist/empty-pixel.js.map +7 -0
- package/dist/get-shader-color-from-string.d.ts +3 -0
- package/dist/get-shader-color-from-string.js +101 -0
- package/dist/get-shader-color-from-string.js.map +7 -0
- package/dist/get-shader-color-from-string.test.d.ts +1 -0
- package/dist/get-shader-color-from-string.test.js +69 -0
- package/dist/get-shader-noise-texture.d.ts +1 -0
- package/dist/get-shader-noise-texture.js +18 -0
- package/dist/get-shader-noise-texture.js.map +7 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +194 -0
- package/dist/index.js.map +7 -0
- package/dist/shader-color-spaces.d.ts +6 -0
- package/dist/shader-color-spaces.js +96 -0
- package/dist/shader-color-spaces.js.map +7 -0
- package/dist/shader-mount.d.ts +199 -0
- package/dist/shader-mount.js +735 -0
- package/dist/shader-mount.js.map +7 -0
- package/dist/shader-sizing.d.ts +30 -0
- package/dist/shader-sizing.js +38 -0
- package/dist/shader-sizing.js.map +7 -0
- package/dist/shader-utils.d.ts +10 -0
- package/dist/shader-utils.js +131 -0
- package/dist/shader-utils.js.map +7 -0
- package/dist/shaders/color-panels.d.ts +70 -0
- package/dist/shaders/color-panels.js +224 -0
- package/dist/shaders/color-panels.js.map +7 -0
- package/dist/shaders/dithering.d.ts +62 -0
- package/dist/shaders/dithering.js +271 -0
- package/dist/shaders/dithering.js.map +7 -0
- package/dist/shaders/dot-grid.d.ts +65 -0
- package/dist/shaders/dot-grid.js +110 -0
- package/dist/shaders/dot-grid.js.map +7 -0
- package/dist/shaders/dot-orbit.d.ts +57 -0
- package/dist/shaders/dot-orbit.js +123 -0
- package/dist/shaders/dot-orbit.js.map +7 -0
- package/dist/shaders/fluted-glass.d.ts +112 -0
- package/dist/shaders/fluted-glass.js +361 -0
- package/dist/shaders/fluted-glass.js.map +7 -0
- package/dist/shaders/gem-smoke.d.ts +96 -0
- package/dist/shaders/gem-smoke.js +573 -0
- package/dist/shaders/gem-smoke.js.map +7 -0
- package/dist/shaders/god-rays.d.ts +67 -0
- package/dist/shaders/god-rays.js +133 -0
- package/dist/shaders/god-rays.js.map +7 -0
- package/dist/shaders/grain-gradient.d.ts +80 -0
- package/dist/shaders/grain-gradient.js +301 -0
- package/dist/shaders/grain-gradient.js.map +7 -0
- package/dist/shaders/halftone-cmyk.d.ts +104 -0
- package/dist/shaders/halftone-cmyk.js +295 -0
- package/dist/shaders/halftone-cmyk.js.map +7 -0
- package/dist/shaders/halftone-dots.d.ts +80 -0
- package/dist/shaders/halftone-dots.js +321 -0
- package/dist/shaders/halftone-dots.js.map +7 -0
- package/dist/shaders/heatmap.d.ts +66 -0
- package/dist/shaders/heatmap.js +384 -0
- package/dist/shaders/heatmap.js.map +7 -0
- package/dist/shaders/image-dithering.d.ts +64 -0
- package/dist/shaders/image-dithering.js +199 -0
- package/dist/shaders/image-dithering.js.map +7 -0
- package/dist/shaders/lens-distortion.d.ts +97 -0
- package/dist/shaders/lens-distortion.js +276 -0
- package/dist/shaders/lens-distortion.js.map +7 -0
- package/dist/shaders/liquid-metal.d.ts +89 -0
- package/dist/shaders/liquid-metal.js +633 -0
- package/dist/shaders/liquid-metal.js.map +7 -0
- package/dist/shaders/mesh-gradient.d.ts +52 -0
- package/dist/shaders/mesh-gradient.js +131 -0
- package/dist/shaders/mesh-gradient.js.map +7 -0
- package/dist/shaders/metaballs.d.ts +51 -0
- package/dist/shaders/metaballs.js +111 -0
- package/dist/shaders/metaballs.js.map +7 -0
- package/dist/shaders/neuro-noise.d.ts +47 -0
- package/dist/shaders/neuro-noise.js +77 -0
- package/dist/shaders/neuro-noise.js.map +7 -0
- package/dist/shaders/paper-texture.d.ts +109 -0
- package/dist/shaders/paper-texture.js +527 -0
- package/dist/shaders/paper-texture.js.map +7 -0
- package/dist/shaders/perlin-noise.d.ts +52 -0
- package/dist/shaders/perlin-noise.js +167 -0
- package/dist/shaders/perlin-noise.js.map +7 -0
- package/dist/shaders/pulsing-border.d.ts +98 -0
- package/dist/shaders/pulsing-border.js +239 -0
- package/dist/shaders/pulsing-border.js.map +7 -0
- package/dist/shaders/simplex-noise.d.ts +45 -0
- package/dist/shaders/simplex-noise.js +92 -0
- package/dist/shaders/simplex-noise.js.map +7 -0
- package/dist/shaders/smoke-ring.d.ts +61 -0
- package/dist/shaders/smoke-ring.js +133 -0
- package/dist/shaders/smoke-ring.js.map +7 -0
- package/dist/shaders/spiral.d.ts +61 -0
- package/dist/shaders/spiral.js +83 -0
- package/dist/shaders/spiral.js.map +7 -0
- package/dist/shaders/static-mesh-gradient.d.ts +63 -0
- package/dist/shaders/static-mesh-gradient.js +131 -0
- package/dist/shaders/static-mesh-gradient.js.map +7 -0
- package/dist/shaders/static-radial-gradient.d.ts +72 -0
- package/dist/shaders/static-radial-gradient.js +188 -0
- package/dist/shaders/static-radial-gradient.js.map +7 -0
- package/dist/shaders/swirl.d.ts +63 -0
- package/dist/shaders/swirl.js +104 -0
- package/dist/shaders/swirl.js.map +7 -0
- package/dist/shaders/voronoi.d.ts +65 -0
- package/dist/shaders/voronoi.js +139 -0
- package/dist/shaders/voronoi.js.map +7 -0
- package/dist/shaders/warp.d.ts +70 -0
- package/dist/shaders/warp.js +130 -0
- package/dist/shaders/warp.js.map +7 -0
- package/dist/shaders/water.d.ts +59 -0
- package/dist/shaders/water.js +122 -0
- package/dist/shaders/water.js.map +7 -0
- package/dist/shaders/waves.d.ts +53 -0
- package/dist/shaders/waves.js +66 -0
- package/dist/shaders/waves.js.map +7 -0
- package/dist/shared-webgl-renderer.d.ts +63 -0
- package/dist/shared-webgl-renderer.js +262 -0
- package/dist/shared-webgl-renderer.js.map +7 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +7 -0
- package/dist/vertex-shader.d.ts +2 -0
- package/dist/vertex-shader.js +160 -0
- package/dist/vertex-shader.js.map +7 -0
- package/package.json +29 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/liquid-metal.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\r\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\r\nimport { declarePI, rotation2, simplexNoise, colorBandingFix } from '../shader-utils.js';\r\n\r\n/**\r\n * Futuristic liquid metal material applied to uploaded logo or abstract shape.\r\n * Fluid motion imitation applied over user image with animated stripe pattern\r\n * getting distorted along shape edges.\r\n *\r\n * Fragment shader uniforms:\r\n * - u_time (float): Animation time\r\n * - u_resolution (vec2): Canvas resolution in pixels\r\n * - u_image (sampler2D): Pre-processed source image texture (R = edge gradient, G = opacity)\r\n * - u_colorBack (vec4): Background color in RGBA\r\n * - u_colorTint (vec4): Overlay color in RGBA (color burn blending used)\r\n * - u_repetition (float): Density of pattern stripes (1 to 10)\r\n * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)\r\n * - u_shiftRed (float): R-channel dispersion (-1 to 1)\r\n * - u_shiftBlue (float): B-channel dispersion (-1 to 1)\r\n * - u_distortion (float): Noise distortion over the stripes pattern (0 to 1)\r\n * - u_contour (float): Strength of the distortion on the shape edges (0 to 1)\r\n * - u_angle (float): Direction of pattern animation in degrees (0 to 360)\r\n * - u_shape (float): Predefined shape mask, needs no image (0 = none, 1 = circle, 2 = daisy, 3 = diamond, 4 = metaballs)\r\n * - u_isImage (bool): Whether an image is being used as the effect mask\r\n *\r\n * Vertex shader outputs (used in fragment shader):\r\n * - v_imageUV (vec2): UV coordinates for sampling the source image, with fit, scale, rotation, and offset applied\r\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied (used when no image)\r\n * - v_responsiveUV (vec2): Responsive UV coordinates that adapt to canvas aspect ratio (used for canvas-fill mode)\r\n * - v_responsiveBoxGivenSize (vec2): TBD\r\n *\r\n * Vertex shader uniforms:\r\n * - u_resolution (vec2): Canvas resolution in pixels\r\n * - u_pixelRatio (float): Device pixel ratio\r\n * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)\r\n * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)\r\n * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas\r\n * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas\r\n * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)\r\n * - u_scale (float): Overall zoom level of the graphics (0.1 to 4)\r\n * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)\r\n * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)\r\n * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)\r\n * - u_imageAspectRatio (float): Aspect ratio of the source image\r\n *\r\n */\r\n\r\n// language=GLSL\r\nexport const liquidMetalFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform sampler2D u_image;\r\n\r\nuniform vec2 u_resolution;\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colorBack;\r\nuniform vec4 u_colorTint;\r\n\r\nuniform float u_softness;\r\nuniform float u_repetition;\r\nuniform float u_shiftRed;\r\nuniform float u_shiftBlue;\r\nuniform float u_distortion;\r\nuniform float u_contour;\r\nuniform float u_angle;\r\n\r\nuniform float u_shape;\r\nuniform bool u_isImage;\r\n\r\nin vec2 v_objectUV;\r\nin vec2 v_responsiveUV;\r\nin vec2 v_responsiveBoxGivenSize;\r\nin vec2 v_imageUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ declarePI }\r\n${ rotation2 }\r\n${ simplexNoise }\r\n\r\nfloat getColorChanges(float c1, float c2, float stripe_p, vec3 w, float blur, float bump, float tint) {\r\n\r\n float ch = mix(c2, c1, smoothstep(.0, 2. * blur, stripe_p));\r\n\r\n float border = w[0];\r\n ch = mix(ch, c2, smoothstep(border, border + 2. * blur, stripe_p));\r\n\r\n if (u_isImage == true) {\r\n bump = smoothstep(.2, .8, bump);\r\n }\r\n border = w[0] + .4 * (1. - bump) * w[1];\r\n ch = mix(ch, c1, smoothstep(border, border + 2. * blur, stripe_p));\r\n\r\n border = w[0] + .5 * (1. - bump) * w[1];\r\n ch = mix(ch, c2, smoothstep(border, border + 2. * blur, stripe_p));\r\n\r\n border = w[0] + w[1];\r\n ch = mix(ch, c1, smoothstep(border, border + 2. * blur, stripe_p));\r\n\r\n float gradient_t = (stripe_p - w[0] - w[1]) / w[2];\r\n float gradient = mix(c1, c2, smoothstep(0., 1., gradient_t));\r\n ch = mix(ch, gradient, smoothstep(border, border + .5 * blur, stripe_p));\r\n\r\n // Tint color is applied with color burn blending\r\n ch = mix(ch, 1. - min(1., (1. - ch) / max(tint, 0.0001)), u_colorTint.a);\r\n return ch;\r\n}\r\n\r\nfloat getImgFrame(vec2 uv, float th) {\r\n float frame = 1.;\r\n frame *= smoothstep(0., th, uv.y);\r\n frame *= 1.0 - smoothstep(1. - th, 1., uv.y);\r\n frame *= smoothstep(0., th, uv.x);\r\n frame *= 1.0 - smoothstep(1. - th, 1., uv.x);\r\n return frame;\r\n}\r\n\r\nfloat blurEdge3x3(sampler2D tex, vec2 uv, vec2 dudx, vec2 dudy, float radius, float centerSample) {\r\n vec2 texel = 1.0 / vec2(textureSize(tex, 0));\r\n vec2 r = radius * texel;\r\n\r\n float w1 = 1.0, w2 = 2.0, w4 = 4.0;\r\n float norm = 16.0;\r\n float sum = w4 * centerSample;\r\n\r\n sum += w2 * textureGrad(tex, uv + vec2(0.0, -r.y), dudx, dudy).r;\r\n sum += w2 * textureGrad(tex, uv + vec2(0.0, r.y), dudx, dudy).r;\r\n sum += w2 * textureGrad(tex, uv + vec2(-r.x, 0.0), dudx, dudy).r;\r\n sum += w2 * textureGrad(tex, uv + vec2(r.x, 0.0), dudx, dudy).r;\r\n\r\n sum += w1 * textureGrad(tex, uv + vec2(-r.x, -r.y), dudx, dudy).r;\r\n sum += w1 * textureGrad(tex, uv + vec2(r.x, -r.y), dudx, dudy).r;\r\n sum += w1 * textureGrad(tex, uv + vec2(-r.x, r.y), dudx, dudy).r;\r\n sum += w1 * textureGrad(tex, uv + vec2(r.x, r.y), dudx, dudy).r;\r\n\r\n return sum / norm;\r\n}\r\n\r\nfloat lst(float edge0, float edge1, float x) {\r\n return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\r\n}\r\n\r\nvoid main() {\r\n\r\n const float firstFrameOffset = 2.8;\r\n float t = .3 * (u_time + firstFrameOffset);\r\n\r\n vec2 uv = v_imageUV;\r\n vec2 dudx = dFdx(v_imageUV);\r\n vec2 dudy = dFdy(v_imageUV);\r\n vec4 img = textureGrad(u_image, uv, dudx, dudy);\r\n\r\n if (u_isImage == false) {\r\n uv = v_objectUV + .5;\r\n uv.y = 1. - uv.y;\r\n }\r\n\r\n float cycleWidth = u_repetition;\r\n float edge = 0.;\r\n float contOffset = 1.;\r\n\r\n vec2 rotatedUV = uv - vec2(.5);\r\n float angle = (-u_angle + 70.) * PI / 180.;\r\n float cosA = cos(angle);\r\n float sinA = sin(angle);\r\n rotatedUV = vec2(\r\n rotatedUV.x * cosA - rotatedUV.y * sinA,\r\n rotatedUV.x * sinA + rotatedUV.y * cosA\r\n ) + vec2(.5);\r\n\r\n // u_contour is applied in 2 separate ranges:\r\n // - 0 to .4 sets the edge hardness, saturated above .4 (both branches below)\r\n // - .5 to 1 warps the stripes direction along the edges, inactive below .5 (see u_contour range 2)\r\n if (u_isImage == true) {\r\n float edgeRaw = img.r;\r\n edge = blurEdge3x3(u_image, uv, dudx, dudy, 6., edgeRaw);\r\n edge = pow(edge, 1.6);\r\n edge *= mix(0.0, 1.0, smoothstep(0.0, 0.4, u_contour));\r\n } else {\r\n if (u_shape < 1.) {\r\n // full-fill on canvas\r\n vec2 borderUV = v_responsiveUV + .5;\r\n float ratio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\r\n vec2 mask = min(borderUV, 1. - borderUV);\r\n vec2 pixel_thickness = min(250. / v_responsiveBoxGivenSize, vec2(.5));\r\n float maskX = smoothstep(0.0, pixel_thickness.x, mask.x);\r\n float maskY = smoothstep(0.0, pixel_thickness.y, mask.y);\r\n maskX = pow(maskX, .25);\r\n maskY = pow(maskY, .25);\r\n edge = clamp(1. - maskX * maskY, 0., 1.);\r\n\r\n uv = v_responsiveUV;\r\n if (ratio > 1.) {\r\n uv.y /= ratio;\r\n } else {\r\n uv.x *= ratio;\r\n }\r\n uv += .5;\r\n uv.y = 1. - uv.y;\r\n\r\n cycleWidth *= 2.;\r\n contOffset = 1.5;\r\n\r\n } else if (u_shape < 2.) {\r\n // circle\r\n vec2 shapeUV = uv - .5;\r\n shapeUV *= .67;\r\n edge = pow(clamp(3. * length(shapeUV), 0., 1.), 18.);\r\n } else if (u_shape < 3.) {\r\n // daisy\r\n vec2 shapeUV = uv - .5;\r\n shapeUV *= 1.68;\r\n\r\n float r = length(shapeUV) * 2.;\r\n float a = atan(shapeUV.y, shapeUV.x) + .2;\r\n r *= (1. + .05 * sin(3. * a + 2. * t));\r\n float f = abs(cos(a * 3.));\r\n edge = smoothstep(f, f + .7, r);\r\n edge *= edge;\r\n\r\n uv *= .8;\r\n cycleWidth *= 1.6;\r\n\r\n } else if (u_shape < 4.) {\r\n // diamond\r\n vec2 shapeUV = uv - .5;\r\n shapeUV = rotate(shapeUV, .25 * PI);\r\n shapeUV *= 1.42;\r\n shapeUV += .5;\r\n vec2 mask = min(shapeUV, 1. - shapeUV);\r\n vec2 pixel_thickness = vec2(.15);\r\n float maskX = smoothstep(0.0, pixel_thickness.x, mask.x);\r\n float maskY = smoothstep(0.0, pixel_thickness.y, mask.y);\r\n maskX = pow(maskX, .25);\r\n maskY = pow(maskY, .25);\r\n edge = clamp(1. - maskX * maskY, 0., 1.);\r\n } else if (u_shape < 5.) {\r\n // metaballs\r\n vec2 shapeUV = uv - .5;\r\n shapeUV *= 1.3;\r\n edge = 0.;\r\n for (int i = 0; i < 5; i++) {\r\n float fi = float(i);\r\n float speed = 1.5 + 2./3. * sin(fi * 12.345);\r\n float angle = -fi * 1.5;\r\n vec2 dir1 = vec2(cos(angle), sin(angle));\r\n vec2 dir2 = vec2(cos(angle + 1.57), sin(angle + 1.));\r\n vec2 traj = .4 * (dir1 * sin(t * speed + fi * 1.23) + dir2 * cos(t * (speed * 0.7) + fi * 2.17));\r\n float d = length(shapeUV + traj);\r\n edge += pow(1.0 - clamp(d, 0.0, 1.0), 4.0);\r\n }\r\n edge = 1. - smoothstep(.65, .9, edge);\r\n edge = pow(edge, 4.);\r\n }\r\n\r\n edge = mix(smoothstep(.9 - 2. * fwidth(edge), .9, edge), edge, smoothstep(0.0, 0.4, u_contour));\r\n\r\n }\r\n\r\n float opacity = 0.;\r\n if (u_isImage == true) {\r\n opacity = img.g;\r\n float frame = getImgFrame(v_imageUV, 0.);\r\n opacity *= frame;\r\n } else {\r\n opacity = 1. - smoothstep(.9 - 2. * fwidth(edge), .9, edge);\r\n if (u_shape < 2.) {\r\n edge = 1.2 * edge;\r\n } else if (u_shape < 5.) {\r\n edge = 1.8 * pow(edge, 1.5);\r\n }\r\n }\r\n\r\n float diagBLtoTR = rotatedUV.x - rotatedUV.y;\r\n float diagTLtoBR = rotatedUV.x + rotatedUV.y;\r\n\r\n vec3 color = vec3(0.);\r\n vec3 color1 = vec3(.98, 0.98, 1.);\r\n vec3 color2 = vec3(.1, .1, .1 + .1 * smoothstep(.7, 1.3, diagTLtoBR));\r\n\r\n vec2 grad_uv = uv - .5;\r\n\r\n float dist = length(grad_uv + vec2(0., .2 * diagBLtoTR));\r\n grad_uv = rotate(grad_uv, (.25 - .2 * diagBLtoTR) * PI);\r\n float direction = grad_uv.x;\r\n\r\n float bump = pow(1.8 * dist, 1.2);\r\n bump = 1. - bump;\r\n bump *= pow(uv.y, .3);\r\n\r\n\r\n float thin_strip_1_ratio = .12 / cycleWidth * (1. - .4 * bump);\r\n float thin_strip_2_ratio = .07 / cycleWidth * (1. + .4 * bump);\r\n float wide_strip_ratio = (1. - thin_strip_1_ratio - thin_strip_2_ratio);\r\n\r\n float thin_strip_1_width = cycleWidth * thin_strip_1_ratio;\r\n float thin_strip_2_width = cycleWidth * thin_strip_2_ratio;\r\n\r\n float noise = snoise(uv - t);\r\n\r\n edge += (1. - edge) * u_distortion * noise;\r\n\r\n direction += diagBLtoTR;\r\n float contour = 0.;\r\n direction -= 2. * noise * diagBLtoTR * (smoothstep(0., 1., edge) * (1.0 - smoothstep(0., 1., edge)));\r\n // u_contour range 2\r\n direction *= mix(1., 1. - edge, smoothstep(.5, 1., u_contour));\r\n direction -= 1.7 * edge * smoothstep(.5, 1., u_contour);\r\n direction += .2 * pow(u_contour, 4.) * (1.0 - smoothstep(0., 1., edge));\r\n\r\n bump *= clamp(pow(uv.y, .1), .3, 1.);\r\n direction *= (.1 + (1.1 - edge) * bump);\r\n\r\n direction *= (.4 + .6 * (1.0 - smoothstep(.5, 1., edge)));\r\n direction += .18 * (smoothstep(.1, .2, uv.y) * (1.0 - smoothstep(.2, .4, uv.y)));\r\n direction += .03 * (smoothstep(.1, .2, 1. - uv.y) * (1.0 - smoothstep(.2, .4, 1. - uv.y)));\r\n\r\n direction *= (.5 + .5 * pow(uv.y, 2.));\r\n direction *= cycleWidth;\r\n direction -= t;\r\n\r\n\r\n float colorDispersion = (1. - bump);\r\n colorDispersion = clamp(colorDispersion, 0., 1.);\r\n float dispersionRed = colorDispersion;\r\n dispersionRed += .03 * bump * noise;\r\n dispersionRed += 5. * (smoothstep(-.1, .2, uv.y) * (1.0 - smoothstep(.1, .5, uv.y))) * (smoothstep(.4, .6, bump) * (1.0 - smoothstep(.4, 1., bump)));\r\n dispersionRed -= diagBLtoTR;\r\n\r\n float dispersionBlue = colorDispersion;\r\n dispersionBlue *= 1.3;\r\n dispersionBlue += (smoothstep(0., .4, uv.y) * (1.0 - smoothstep(.1, .8, uv.y))) * (smoothstep(.4, .6, bump) * (1.0 - smoothstep(.4, .8, bump)));\r\n dispersionBlue -= .2 * edge;\r\n\r\n dispersionRed *= (u_shiftRed / 20.);\r\n dispersionBlue *= (u_shiftBlue / 20.);\r\n\r\n float blur = 0.;\r\n float rExtraBlur = 0.;\r\n float gExtraBlur = 0.;\r\n if (u_isImage == true) {\r\n float softness = 0.05 * u_softness;\r\n blur = softness + .5 * smoothstep(1., 10., u_repetition) * smoothstep(.0, 1., edge);\r\n float smallCanvasT = 1.0 - smoothstep(100., 500., min(u_resolution.x, u_resolution.y));\r\n blur += smallCanvasT * smoothstep(.0, 1., edge);\r\n rExtraBlur = softness * (0.05 + .1 * (u_shiftRed / 20.) * bump);\r\n gExtraBlur = softness * 0.05 / max(0.001, abs(1. - diagBLtoTR));\r\n } else {\r\n blur = u_softness / 15. + .3 * contour;\r\n }\r\n\r\n vec3 w = vec3(thin_strip_1_width, thin_strip_2_width, wide_strip_ratio);\r\n w[1] -= .02 * smoothstep(.0, 1., edge + bump);\r\n float stripe_r = fract(direction + dispersionRed);\r\n float r = getColorChanges(color1.r, color2.r, stripe_r, w, blur + fwidth(stripe_r) + rExtraBlur, bump, u_colorTint.r);\r\n float stripe_g = fract(direction);\r\n float g = getColorChanges(color1.g, color2.g, stripe_g, w, blur + fwidth(stripe_g) + gExtraBlur, bump, u_colorTint.g);\r\n float stripe_b = fract(direction - dispersionBlue);\r\n float b = getColorChanges(color1.b, color2.b, stripe_b, w, blur + fwidth(stripe_b), bump, u_colorTint.b);\r\n\r\n color = vec3(r, g, b);\r\n color *= opacity;\r\n\r\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\r\n color = color + bgColor * (1. - opacity);\r\n opacity = opacity + u_colorBack.a * (1. - opacity);\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\n// Configuration for Poisson solver\r\nexport const POISSON_CONFIG_OPTIMIZED = {\r\n measurePerformance: false, // Set to true to see performance metrics\r\n workingSize: 512, // Size to solve Poisson at (will upscale to original size)\r\n iterations: 40, // SOR converges ~2-20x faster than standard Gauss-Seidel\r\n};\r\n\r\n// Precomputed pixel data for sparse processing\r\ninterface SparsePixelData {\r\n interiorPixels: Uint32Array; // Indices of interior pixels\r\n boundaryPixels: Uint32Array; // Indices of boundary pixels\r\n pixelCount: number;\r\n // Neighbor indices for each interior pixel (4 neighbors per pixel)\r\n // Layout: [east, west, north, south] for each pixel\r\n neighborIndices: Int32Array;\r\n}\r\n\r\nexport function toProcessedLiquidMetal(file: File | string): Promise<{ imageData: ImageData; pngBlob: Blob }> {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n const isBlob = typeof file === 'string' && file.startsWith('blob:');\r\n\r\n return new Promise((resolve, reject) => {\r\n if (!file || !ctx) {\r\n reject(new Error('Invalid file or canvas context'));\r\n return;\r\n }\r\n\r\n const blobContentTypePromise = isBlob && fetch(file).then((res) => res.headers.get('Content-Type'));\r\n const img = new Image();\r\n img.crossOrigin = 'anonymous';\r\n const totalStartTime = performance.now();\r\n\r\n img.onload = async () => {\r\n // Force SVG to load at a high fidelity size if it's an SVG\r\n let isSVG;\r\n\r\n const blobContentType = await blobContentTypePromise;\r\n\r\n if (blobContentType) {\r\n isSVG = blobContentType === 'image/svg+xml';\r\n } else if (typeof file === 'string') {\r\n isSVG = file.endsWith('.svg') || file.startsWith('data:image/svg+xml');\r\n } else {\r\n isSVG = file.type === 'image/svg+xml';\r\n }\r\n\r\n let originalWidth = img.width || img.naturalWidth;\r\n let originalHeight = img.height || img.naturalHeight;\r\n\r\n if (isSVG) {\r\n // Scale SVG to max dimension while preserving aspect ratio\r\n const svgMaxSize = 4096;\r\n const aspectRatio = originalWidth / originalHeight;\r\n\r\n if (originalWidth > originalHeight) {\r\n originalWidth = svgMaxSize;\r\n originalHeight = svgMaxSize / aspectRatio;\r\n } else {\r\n originalHeight = svgMaxSize;\r\n originalWidth = svgMaxSize * aspectRatio;\r\n }\r\n\r\n img.width = originalWidth;\r\n img.height = originalHeight;\r\n }\r\n\r\n // Always scale to working resolution for consistency\r\n const minDimension = Math.min(originalWidth, originalHeight);\r\n const targetSize = POISSON_CONFIG_OPTIMIZED.workingSize;\r\n\r\n // Calculate scale to fit within workingSize\r\n const scaleFactor = targetSize / minDimension;\r\n const width = Math.round(originalWidth * scaleFactor);\r\n const height = Math.round(originalHeight * scaleFactor);\r\n\r\n if (POISSON_CONFIG_OPTIMIZED.measurePerformance) {\r\n console.log(`[Processing Mode]`);\r\n console.log(` Original: ${originalWidth}\u00D7${originalHeight}`);\r\n console.log(` Working: ${width}\u00D7${height} (${(scaleFactor * 100).toFixed(1)}% scale)`);\r\n if (scaleFactor < 1) {\r\n console.log(` Speedup: ~${Math.round(1 / (scaleFactor * scaleFactor))}\u00D7`);\r\n }\r\n }\r\n\r\n canvas.width = originalWidth;\r\n canvas.height = originalHeight;\r\n\r\n // Use a smaller canvas for shape detection and Poisson solving\r\n const shapeCanvas = document.createElement('canvas');\r\n shapeCanvas.width = width;\r\n shapeCanvas.height = height;\r\n\r\n const shapeCtx = shapeCanvas.getContext('2d')!;\r\n shapeCtx.drawImage(img, 0, 0, width, height);\r\n\r\n // 1) Build optimized masks using TypedArrays\r\n const startMask = performance.now();\r\n\r\n const shapeImageData = shapeCtx.getImageData(0, 0, width, height);\r\n const data = shapeImageData.data;\r\n\r\n // Use Uint8Array for masks (1 byte per pixel vs 8+ bytes for boolean array)\r\n const shapeMask = new Uint8Array(width * height);\r\n const boundaryMask = new Uint8Array(width * height);\r\n\r\n // First pass: identify shape pixels\r\n let shapePixelCount = 0;\r\n for (let i = 0, idx = 0; i < data.length; i += 4, idx++) {\r\n const a = data[i + 3];\r\n const isShape = a === 0 ? 0 : 1;\r\n shapeMask[idx] = isShape;\r\n shapePixelCount += isShape;\r\n }\r\n\r\n // 2) Optimized boundary detection using sparse approach\r\n // Only check shape pixels, not all pixels\r\n const boundaryIndices: number[] = [];\r\n const interiorIndices: number[] = [];\r\n\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const idx = y * width + x;\r\n if (!shapeMask[idx]) continue;\r\n\r\n // Check if pixel is on boundary (optimized: early exit)\r\n let isBoundary = false;\r\n\r\n // Check 4-connected neighbors first (most common case)\r\n if (x === 0 || x === width - 1 || y === 0 || y === height - 1) {\r\n isBoundary = true;\r\n } else {\r\n // Check all 8 neighbors (including diagonals) for comprehensive boundary detection\r\n isBoundary =\r\n !shapeMask[idx - 1] || // left\r\n !shapeMask[idx + 1] || // right\r\n !shapeMask[idx - width] || // top\r\n !shapeMask[idx + width] || // bottom\r\n !shapeMask[idx - width - 1] || // top-left\r\n !shapeMask[idx - width + 1] || // top-right\r\n !shapeMask[idx + width - 1] || // bottom-left\r\n !shapeMask[idx + width + 1]; // bottom-right\r\n }\r\n\r\n if (isBoundary) {\r\n boundaryMask[idx] = 1;\r\n boundaryIndices.push(idx);\r\n } else {\r\n interiorIndices.push(idx);\r\n }\r\n }\r\n }\r\n\r\n if (POISSON_CONFIG_OPTIMIZED.measurePerformance) {\r\n console.log(`[Mask Building] Time: ${(performance.now() - startMask).toFixed(2)}ms`);\r\n console.log(\r\n ` Shape pixels: ${shapePixelCount} / ${width * height} (${((shapePixelCount / (width * height)) * 100).toFixed(1)}%)`\r\n );\r\n console.log(` Interior pixels: ${interiorIndices.length}`);\r\n console.log(` Boundary pixels: ${boundaryIndices.length}`);\r\n }\r\n\r\n // 3) Precompute sparse data structure for solver\r\n const sparseData = buildSparseData(\r\n shapeMask,\r\n boundaryMask,\r\n new Uint32Array(interiorIndices),\r\n new Uint32Array(boundaryIndices),\r\n width,\r\n height\r\n );\r\n\r\n // 4) Solve Poisson equation with optimized sparse solver\r\n const startSolve = performance.now();\r\n const u = solvePoissonSparse(sparseData, shapeMask, boundaryMask, width, height);\r\n\r\n if (POISSON_CONFIG_OPTIMIZED.measurePerformance) {\r\n console.log(`[Poisson Solve] Time: ${(performance.now() - startSolve).toFixed(2)}ms`);\r\n }\r\n\r\n // 5) Generate output image\r\n let maxVal = 0;\r\n let finalImageData: ImageData;\r\n\r\n // Only check shape pixels for max value\r\n for (let i = 0; i < interiorIndices.length; i++) {\r\n const idx = interiorIndices[i]!;\r\n if (u[idx]! > maxVal) maxVal = u[idx]!;\r\n }\r\n\r\n // Create gradient image at working resolution\r\n const tempCanvas = document.createElement('canvas');\r\n tempCanvas.width = width;\r\n tempCanvas.height = height;\r\n const tempCtx = tempCanvas.getContext('2d')!;\r\n\r\n const tempImg = tempCtx.createImageData(width, height);\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const idx = y * width + x;\r\n const px = idx * 4;\r\n\r\n if (!shapeMask[idx]) {\r\n tempImg.data[px] = 255;\r\n tempImg.data[px + 1] = 255;\r\n tempImg.data[px + 2] = 255;\r\n tempImg.data[px + 3] = 0; // Alpha = 0 for background\r\n } else {\r\n const poissonRatio = u[idx]! / maxVal;\r\n const gray = 255 * (1 - poissonRatio);\r\n tempImg.data[px] = gray;\r\n tempImg.data[px + 1] = gray;\r\n tempImg.data[px + 2] = gray;\r\n tempImg.data[px + 3] = 255; // Alpha = 255 for shape\r\n }\r\n }\r\n }\r\n tempCtx.putImageData(tempImg, 0, 0);\r\n\r\n // Upscale to original resolution with smooth interpolation\r\n ctx.imageSmoothingEnabled = true;\r\n ctx.imageSmoothingQuality = 'high';\r\n ctx.drawImage(tempCanvas, 0, 0, width, height, 0, 0, originalWidth, originalHeight);\r\n\r\n // Now get the upscaled image data for final output\r\n const outImg = ctx.getImageData(0, 0, originalWidth, originalHeight);\r\n\r\n // Re-apply edges from original resolution with anti-aliasing\r\n // This ensures edges are pixel-perfect while gradient is smooth\r\n const originalCanvas = document.createElement('canvas');\r\n originalCanvas.width = originalWidth;\r\n originalCanvas.height = originalHeight;\r\n const originalCtx = originalCanvas.getContext('2d')!;\r\n // originalCtx.fillStyle = \"white\";\r\n // originalCtx.fillRect(0, 0, originalWidth, originalHeight);\r\n originalCtx.drawImage(img, 0, 0, originalWidth, originalHeight);\r\n const originalData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);\r\n\r\n // Process each pixel: Red channel = gradient, Alpha channel = original alpha\r\n for (let i = 0; i < outImg.data.length; i += 4) {\r\n const a = originalData.data[i + 3]!;\r\n // Use only alpha to determine background vs shape\r\n const upscaledAlpha = outImg.data[i + 3]!;\r\n if (a === 0) {\r\n // Background pixel\r\n outImg.data[i] = 255;\r\n outImg.data[i + 1] = 0;\r\n } else {\r\n // Red channel carries the gradient\r\n // Check if upscale missed this pixel by looking at alpha channel\r\n // If upscaled alpha is 0, the low-res version thought this was background\r\n outImg.data[i] = upscaledAlpha === 0 ? 0 : outImg.data[i]!; // gradient or 0\r\n outImg.data[i + 1] = a; // original alpha\r\n }\r\n\r\n // Unused channels fixed\r\n outImg.data[i + 2] = 255;\r\n outImg.data[i + 3] = 255;\r\n }\r\n\r\n ctx.putImageData(outImg, 0, 0);\r\n finalImageData = outImg;\r\n canvas.toBlob((blob) => {\r\n if (!blob) {\r\n reject(new Error('Failed to create PNG blob'));\r\n return;\r\n }\r\n\r\n if (POISSON_CONFIG_OPTIMIZED.measurePerformance) {\r\n const totalTime = performance.now() - totalStartTime;\r\n console.log(`[Total Processing Time] ${totalTime.toFixed(2)}ms`);\r\n if (scaleFactor < 1) {\r\n const estimatedFullResTime = totalTime * Math.pow((originalWidth * originalHeight) / (width * height), 1.5);\r\n console.log(`[Estimated time at full resolution] ~${estimatedFullResTime.toFixed(0)}ms`);\r\n console.log(\r\n `[Time saved] ~${(estimatedFullResTime - totalTime).toFixed(0)}ms (${Math.round(estimatedFullResTime / totalTime)}\u00D7 faster)`\r\n );\r\n }\r\n }\r\n\r\n resolve({\r\n imageData: finalImageData,\r\n pngBlob: blob,\r\n });\r\n }, 'image/png');\r\n };\r\n\r\n img.onerror = () => reject(new Error('Failed to load image'));\r\n img.src = typeof file === 'string' ? file : URL.createObjectURL(file);\r\n });\r\n}\r\n\r\nfunction buildSparseData(\r\n shapeMask: Uint8Array,\r\n boundaryMask: Uint8Array,\r\n interiorPixels: Uint32Array,\r\n boundaryPixels: Uint32Array,\r\n width: number,\r\n height: number\r\n): SparsePixelData {\r\n const pixelCount = interiorPixels.length;\r\n\r\n // Build neighbor indices for sparse processing\r\n // For each interior pixel, store indices of its 4 neighbors\r\n // Use -1 for out-of-bounds or non-shape neighbors\r\n const neighborIndices = new Int32Array(pixelCount * 4);\r\n\r\n for (let i = 0; i < pixelCount; i++) {\r\n const idx = interiorPixels[i]!;\r\n const x = idx % width;\r\n const y = Math.floor(idx / width);\r\n\r\n // East neighbor\r\n neighborIndices[i * 4 + 0] = x < width - 1 && shapeMask[idx + 1] ? idx + 1 : -1;\r\n // West neighbor\r\n neighborIndices[i * 4 + 1] = x > 0 && shapeMask[idx - 1] ? idx - 1 : -1;\r\n // North neighbor\r\n neighborIndices[i * 4 + 2] = y > 0 && shapeMask[idx - width] ? idx - width : -1;\r\n // South neighbor\r\n neighborIndices[i * 4 + 3] = y < height - 1 && shapeMask[idx + width] ? idx + width : -1;\r\n }\r\n\r\n return {\r\n interiorPixels,\r\n boundaryPixels,\r\n pixelCount,\r\n neighborIndices,\r\n };\r\n}\r\n\r\nfunction solvePoissonSparse(\r\n sparseData: SparsePixelData,\r\n shapeMask: Uint8Array,\r\n boundaryMask: Uint8Array,\r\n width: number,\r\n height: number\r\n): Float32Array {\r\n // This controls how smooth the falloff gradient will be and extend into the shape\r\n const ITERATIONS = POISSON_CONFIG_OPTIMIZED.iterations;\r\n\r\n // Keep C constant - only iterations control gradient spread\r\n const C = 0.01;\r\n\r\n const u = new Float32Array(width * height);\r\n const { interiorPixels, neighborIndices, pixelCount } = sparseData;\r\n\r\n // Performance tracking\r\n const startTime = performance.now();\r\n\r\n // Red-Black SOR for better symmetry with fewer iterations\r\n // omega between 1.8-1.95 typically gives best convergence for Poisson\r\n const omega = 1.9;\r\n\r\n // Pre-classify pixels as red or black for efficient processing\r\n const redPixels: number[] = [];\r\n const blackPixels: number[] = [];\r\n\r\n for (let i = 0; i < pixelCount; i++) {\r\n const idx = interiorPixels[i]!;\r\n const x = idx % width;\r\n const y = Math.floor(idx / width);\r\n\r\n if ((x + y) % 2 === 0) {\r\n redPixels.push(i);\r\n } else {\r\n blackPixels.push(i);\r\n }\r\n }\r\n\r\n for (let iter = 0; iter < ITERATIONS; iter++) {\r\n // Red pass: update red pixels\r\n for (const i of redPixels) {\r\n const idx = interiorPixels[i]!;\r\n\r\n // Get precomputed neighbor indices\r\n const eastIdx = neighborIndices[i * 4 + 0]!;\r\n const westIdx = neighborIndices[i * 4 + 1]!;\r\n const northIdx = neighborIndices[i * 4 + 2]!;\r\n const southIdx = neighborIndices[i * 4 + 3]!;\r\n\r\n // Sum neighbors (use 0 for out-of-bounds)\r\n let sumN = 0;\r\n if (eastIdx >= 0) sumN += u[eastIdx]!;\r\n if (westIdx >= 0) sumN += u[westIdx]!;\r\n if (northIdx >= 0) sumN += u[northIdx]!;\r\n if (southIdx >= 0) sumN += u[southIdx]!;\r\n\r\n // SOR update: blend new value with old value\r\n const newValue = (C + sumN) / 4;\r\n u[idx] = omega * newValue + (1 - omega) * u[idx]!;\r\n }\r\n\r\n // Black pass: update black pixels\r\n for (const i of blackPixels) {\r\n const idx = interiorPixels[i]!;\r\n\r\n // Get precomputed neighbor indices\r\n const eastIdx = neighborIndices[i * 4 + 0]!;\r\n const westIdx = neighborIndices[i * 4 + 1]!;\r\n const northIdx = neighborIndices[i * 4 + 2]!;\r\n const southIdx = neighborIndices[i * 4 + 3]!;\r\n\r\n // Sum neighbors (use 0 for out-of-bounds)\r\n let sumN = 0;\r\n if (eastIdx >= 0) sumN += u[eastIdx]!;\r\n if (westIdx >= 0) sumN += u[westIdx]!;\r\n if (northIdx >= 0) sumN += u[northIdx]!;\r\n if (southIdx >= 0) sumN += u[southIdx]!;\r\n\r\n // SOR update: blend new value with old value\r\n const newValue = (C + sumN) / 4;\r\n u[idx] = omega * newValue + (1 - omega) * u[idx]!;\r\n }\r\n }\r\n\r\n if (POISSON_CONFIG_OPTIMIZED.measurePerformance) {\r\n const elapsed = performance.now() - startTime;\r\n\r\n console.log(`[Optimized Poisson Solver (SOR \u03C9=${omega})]`);\r\n console.log(` Working size: ${width}\u00D7${height}`);\r\n console.log(` Iterations: ${ITERATIONS}`);\r\n console.log(` Time: ${elapsed.toFixed(2)}ms`);\r\n console.log(` Interior pixels processed: ${pixelCount}`);\r\n console.log(` Speed: ${((ITERATIONS * pixelCount) / (elapsed * 1000)).toFixed(2)} Mpixels/sec`);\r\n }\r\n\r\n return u;\r\n}\r\n\r\nexport interface LiquidMetalUniforms extends ShaderSizingUniforms {\r\n u_colorBack: [number, number, number, number];\r\n u_colorTint: [number, number, number, number];\r\n u_image: HTMLImageElement | string | undefined;\r\n u_repetition: number;\r\n u_shiftRed: number;\r\n u_shiftBlue: number;\r\n u_contour: number;\r\n u_softness: number;\r\n u_distortion: number;\r\n u_angle: number;\r\n u_shape: (typeof LiquidMetalShapes)[LiquidMetalShape];\r\n u_isImage: boolean;\r\n}\r\n\r\nexport interface LiquidMetalParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorBack?: string;\r\n colorTint?: string;\r\n image?: HTMLImageElement | string | undefined;\r\n repetition?: number;\r\n shiftRed?: number;\r\n shiftBlue?: number;\r\n contour?: number;\r\n softness?: number;\r\n distortion?: number;\r\n angle?: number;\r\n shape?: LiquidMetalShape;\r\n}\r\n\r\nexport const LiquidMetalShapes = {\r\n none: 0,\r\n circle: 1,\r\n daisy: 2,\r\n diamond: 3,\r\n metaballs: 4,\r\n} as const;\r\n\r\nexport type LiquidMetalShape = keyof typeof LiquidMetalShapes;\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { vec4 } from '../types.js';
|
|
2
|
+
import type { ShaderMotionParams } from '../shader-mount.js';
|
|
3
|
+
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
4
|
+
export declare const meshGradientMeta: {
|
|
5
|
+
readonly maxColorCount: 10;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A flowing composition of color spots, moving along distinct trajectories
|
|
9
|
+
* and transformed by organic distortion.
|
|
10
|
+
*
|
|
11
|
+
* Fragment shader uniforms:
|
|
12
|
+
* - u_time (float): Animation time
|
|
13
|
+
* - u_colors (vec4[]): Up to 10 color spots in RGBA
|
|
14
|
+
* - u_colorsCount (float): Number of active colors
|
|
15
|
+
* - u_distortion (float): Power of organic noise distortion (0 to 1)
|
|
16
|
+
* - u_swirl (float): Power of vortex distortion (0 to 1)
|
|
17
|
+
* - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)
|
|
18
|
+
* - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)
|
|
19
|
+
*
|
|
20
|
+
* Vertex shader outputs (used in fragment shader):
|
|
21
|
+
* - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
|
|
22
|
+
*
|
|
23
|
+
* Vertex shader uniforms:
|
|
24
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
25
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
26
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
27
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
28
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
29
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
30
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
31
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
32
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
33
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
34
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export declare const meshGradientFragmentShader: string;
|
|
38
|
+
export interface MeshGradientUniforms extends ShaderSizingUniforms {
|
|
39
|
+
u_colors: vec4[];
|
|
40
|
+
u_colorsCount: number;
|
|
41
|
+
u_distortion: number;
|
|
42
|
+
u_swirl: number;
|
|
43
|
+
u_grainMixer: number;
|
|
44
|
+
u_grainOverlay: number;
|
|
45
|
+
}
|
|
46
|
+
export interface MeshGradientParams extends ShaderSizingParams, ShaderMotionParams {
|
|
47
|
+
colors?: string[];
|
|
48
|
+
distortion?: number;
|
|
49
|
+
swirl?: number;
|
|
50
|
+
grainMixer?: number;
|
|
51
|
+
grainOverlay?: number;
|
|
52
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
} from "../shader-sizing.js";
|
|
8
|
+
import { declarePI, rotation2, proceduralHash21 } from "../shader-utils.js";
|
|
9
|
+
const meshGradientMeta = {
|
|
10
|
+
maxColorCount: 10
|
|
11
|
+
};
|
|
12
|
+
const meshGradientFragmentShader = `#version 300 es
|
|
13
|
+
precision mediump float;
|
|
14
|
+
|
|
15
|
+
uniform float u_time;
|
|
16
|
+
|
|
17
|
+
uniform vec4 u_colors[${meshGradientMeta.maxColorCount}];
|
|
18
|
+
uniform float u_colorsCount;
|
|
19
|
+
|
|
20
|
+
uniform float u_distortion;
|
|
21
|
+
uniform float u_swirl;
|
|
22
|
+
uniform float u_grainMixer;
|
|
23
|
+
uniform float u_grainOverlay;
|
|
24
|
+
|
|
25
|
+
in vec2 v_objectUV;
|
|
26
|
+
out vec4 fragColor;
|
|
27
|
+
|
|
28
|
+
${declarePI}
|
|
29
|
+
${rotation2}
|
|
30
|
+
${proceduralHash21}
|
|
31
|
+
|
|
32
|
+
float valueNoise(vec2 st) {
|
|
33
|
+
vec2 i = floor(st);
|
|
34
|
+
vec2 f = fract(st);
|
|
35
|
+
float a = hash21(i);
|
|
36
|
+
float b = hash21(i + vec2(1.0, 0.0));
|
|
37
|
+
float c = hash21(i + vec2(0.0, 1.0));
|
|
38
|
+
float d = hash21(i + vec2(1.0, 1.0));
|
|
39
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
40
|
+
float x1 = mix(a, b, u.x);
|
|
41
|
+
float x2 = mix(c, d, u.x);
|
|
42
|
+
return mix(x1, x2, u.y);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
float noise(vec2 n, vec2 seedOffset) {
|
|
46
|
+
return valueNoise(n + seedOffset);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
vec2 getPosition(int i, float t) {
|
|
50
|
+
float a = float(i) * .37;
|
|
51
|
+
float b = .6 + fract(float(i) / 3.) * .9;
|
|
52
|
+
float c = .8 + fract(float(i + 1) / 4.);
|
|
53
|
+
|
|
54
|
+
float x = sin(t * b + a);
|
|
55
|
+
float y = cos(t * c + a * 1.5);
|
|
56
|
+
|
|
57
|
+
return .5 + .5 * vec2(x, y);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void main() {
|
|
61
|
+
vec2 uv = v_objectUV;
|
|
62
|
+
uv += .5;
|
|
63
|
+
vec2 grainUV = uv * 1000.;
|
|
64
|
+
|
|
65
|
+
float mixerGrain = 0.;
|
|
66
|
+
if (u_grainMixer > 0.) {
|
|
67
|
+
mixerGrain = .4 * u_grainMixer * (noise(grainUV, vec2(0.)) - .5);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const float firstFrameOffset = 41.5;
|
|
71
|
+
float t = .5 * (u_time + firstFrameOffset);
|
|
72
|
+
|
|
73
|
+
float radius = smoothstep(0., 1., length(uv - .5));
|
|
74
|
+
float center = 1. - radius;
|
|
75
|
+
for (float i = 1.; i <= 2.; i++) {
|
|
76
|
+
uv.x += u_distortion * center / i * sin(t + i * .4 * smoothstep(.0, 1., uv.y)) * cos(.2 * t + i * 2.4 * smoothstep(.0, 1., uv.y));
|
|
77
|
+
uv.y += u_distortion * center / i * cos(t + i * 2. * smoothstep(.0, 1., uv.x));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
vec2 uvRotated = uv;
|
|
81
|
+
uvRotated -= vec2(.5);
|
|
82
|
+
float angle = 3. * u_swirl * radius;
|
|
83
|
+
uvRotated = rotate(uvRotated, -angle);
|
|
84
|
+
uvRotated += vec2(.5);
|
|
85
|
+
|
|
86
|
+
vec3 color = vec3(0.);
|
|
87
|
+
float opacity = 0.;
|
|
88
|
+
float totalWeight = 0.;
|
|
89
|
+
|
|
90
|
+
for (int i = 0; i < ${meshGradientMeta.maxColorCount}; i++) {
|
|
91
|
+
if (i >= int(u_colorsCount)) break;
|
|
92
|
+
|
|
93
|
+
vec2 pos = getPosition(i, t) + mixerGrain;
|
|
94
|
+
vec3 colorFraction = u_colors[i].rgb * u_colors[i].a;
|
|
95
|
+
float opacityFraction = u_colors[i].a;
|
|
96
|
+
|
|
97
|
+
float dist = length(uvRotated - pos);
|
|
98
|
+
|
|
99
|
+
dist = pow(dist, 3.5);
|
|
100
|
+
float weight = 1. / (dist + 1e-3);
|
|
101
|
+
color += colorFraction * weight;
|
|
102
|
+
opacity += opacityFraction * weight;
|
|
103
|
+
totalWeight += weight;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
color /= max(1e-4, totalWeight);
|
|
107
|
+
opacity /= max(1e-4, totalWeight);
|
|
108
|
+
|
|
109
|
+
if (u_grainOverlay > 0.) {
|
|
110
|
+
float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));
|
|
111
|
+
grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);
|
|
112
|
+
grainOverlay = pow(grainOverlay, 1.3);
|
|
113
|
+
|
|
114
|
+
float grainOverlayV = grainOverlay * 2. - 1.;
|
|
115
|
+
vec3 grainOverlayColor = vec3(step(0., grainOverlayV));
|
|
116
|
+
float grainOverlayStrength = u_grainOverlay * abs(grainOverlayV);
|
|
117
|
+
grainOverlayStrength = pow(grainOverlayStrength, .8);
|
|
118
|
+
color = mix(color, grainOverlayColor, .35 * grainOverlayStrength);
|
|
119
|
+
|
|
120
|
+
opacity += .5 * grainOverlayStrength;
|
|
121
|
+
}
|
|
122
|
+
opacity = clamp(opacity, 0., 1.);
|
|
123
|
+
|
|
124
|
+
fragColor = vec4(color, opacity);
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
export {
|
|
128
|
+
meshGradientFragmentShader,
|
|
129
|
+
meshGradientMeta
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=mesh-gradient.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/mesh-gradient.ts"],
|
|
4
|
+
"sourcesContent": ["import type { vec4 } from '../types.js';\r\nimport type { ShaderMotionParams } from '../shader-mount.js';\r\nimport {\r\n type ShaderSizingParams,\r\n type ShaderSizingUniforms,\r\n} from '../shader-sizing.js';\r\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\r\n\r\nexport const meshGradientMeta = {\r\n maxColorCount: 10,\r\n} as const;\r\n\r\n/**\r\n * A flowing composition of color spots, moving along distinct trajectories\r\n * and transformed by organic distortion.\r\n *\r\n * Fragment shader uniforms:\r\n * - u_time (float): Animation time\r\n * - u_colors (vec4[]): Up to 10 color spots in RGBA\r\n * - u_colorsCount (float): Number of active colors\r\n * - u_distortion (float): Power of organic noise distortion (0 to 1)\r\n * - u_swirl (float): Power of vortex distortion (0 to 1)\r\n * - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)\r\n * - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)\r\n *\r\n * Vertex shader outputs (used in fragment shader):\r\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied\r\n *\r\n * Vertex shader uniforms:\r\n * - u_resolution (vec2): Canvas resolution in pixels\r\n * - u_pixelRatio (float): Device pixel ratio\r\n * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)\r\n * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)\r\n * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas\r\n * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas\r\n * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)\r\n * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)\r\n * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)\r\n * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)\r\n * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)\r\n *\r\n */\r\n\r\n// language=GLSL\r\nexport const meshGradientFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colors[${meshGradientMeta.maxColorCount}];\r\nuniform float u_colorsCount;\r\n\r\nuniform float u_distortion;\r\nuniform float u_swirl;\r\nuniform float u_grainMixer;\r\nuniform float u_grainOverlay;\r\n\r\nin vec2 v_objectUV;\r\nout vec4 fragColor;\r\n\r\n${declarePI}\r\n${rotation2}\r\n${proceduralHash21}\r\n\r\nfloat valueNoise(vec2 st) {\r\n vec2 i = floor(st);\r\n vec2 f = fract(st);\r\n float a = hash21(i);\r\n float b = hash21(i + vec2(1.0, 0.0));\r\n float c = hash21(i + vec2(0.0, 1.0));\r\n float d = hash21(i + vec2(1.0, 1.0));\r\n vec2 u = f * f * (3.0 - 2.0 * f);\r\n float x1 = mix(a, b, u.x);\r\n float x2 = mix(c, d, u.x);\r\n return mix(x1, x2, u.y);\r\n}\r\n\r\nfloat noise(vec2 n, vec2 seedOffset) {\r\n return valueNoise(n + seedOffset);\r\n}\r\n\r\nvec2 getPosition(int i, float t) {\r\n float a = float(i) * .37;\r\n float b = .6 + fract(float(i) / 3.) * .9;\r\n float c = .8 + fract(float(i + 1) / 4.);\r\n\r\n float x = sin(t * b + a);\r\n float y = cos(t * c + a * 1.5);\r\n\r\n return .5 + .5 * vec2(x, y);\r\n}\r\n\r\nvoid main() {\r\n vec2 uv = v_objectUV;\r\n uv += .5;\r\n vec2 grainUV = uv * 1000.;\r\n\r\n float mixerGrain = 0.;\r\n if (u_grainMixer > 0.) {\r\n mixerGrain = .4 * u_grainMixer * (noise(grainUV, vec2(0.)) - .5);\r\n }\r\n\r\n const float firstFrameOffset = 41.5;\r\n float t = .5 * (u_time + firstFrameOffset);\r\n\r\n float radius = smoothstep(0., 1., length(uv - .5));\r\n float center = 1. - radius;\r\n for (float i = 1.; i <= 2.; i++) {\r\n uv.x += u_distortion * center / i * sin(t + i * .4 * smoothstep(.0, 1., uv.y)) * cos(.2 * t + i * 2.4 * smoothstep(.0, 1., uv.y));\r\n uv.y += u_distortion * center / i * cos(t + i * 2. * smoothstep(.0, 1., uv.x));\r\n }\r\n\r\n vec2 uvRotated = uv;\r\n uvRotated -= vec2(.5);\r\n float angle = 3. * u_swirl * radius;\r\n uvRotated = rotate(uvRotated, -angle);\r\n uvRotated += vec2(.5);\r\n\r\n vec3 color = vec3(0.);\r\n float opacity = 0.;\r\n float totalWeight = 0.;\r\n\r\n for (int i = 0; i < ${meshGradientMeta.maxColorCount}; i++) {\r\n if (i >= int(u_colorsCount)) break;\r\n\r\n vec2 pos = getPosition(i, t) + mixerGrain;\r\n vec3 colorFraction = u_colors[i].rgb * u_colors[i].a;\r\n float opacityFraction = u_colors[i].a;\r\n\r\n float dist = length(uvRotated - pos);\r\n\r\n dist = pow(dist, 3.5);\r\n float weight = 1. / (dist + 1e-3);\r\n color += colorFraction * weight;\r\n opacity += opacityFraction * weight;\r\n totalWeight += weight;\r\n }\r\n\r\n color /= max(1e-4, totalWeight);\r\n opacity /= max(1e-4, totalWeight);\r\n\r\n if (u_grainOverlay > 0.) {\r\n float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));\r\n grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);\r\n grainOverlay = pow(grainOverlay, 1.3);\r\n\r\n float grainOverlayV = grainOverlay * 2. - 1.;\r\n vec3 grainOverlayColor = vec3(step(0., grainOverlayV));\r\n float grainOverlayStrength = u_grainOverlay * abs(grainOverlayV);\r\n grainOverlayStrength = pow(grainOverlayStrength, .8);\r\n color = mix(color, grainOverlayColor, .35 * grainOverlayStrength);\r\n\r\n opacity += .5 * grainOverlayStrength;\r\n }\r\n opacity = clamp(opacity, 0., 1.);\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\nexport interface MeshGradientUniforms extends ShaderSizingUniforms {\r\n u_colors: vec4[];\r\n u_colorsCount: number;\r\n u_distortion: number;\r\n u_swirl: number;\r\n u_grainMixer: number;\r\n u_grainOverlay: number;\r\n}\r\n\r\nexport interface MeshGradientParams extends ShaderSizingParams, ShaderMotionParams {\r\n colors?: string[];\r\n distortion?: number;\r\n swirl?: number;\r\n grainMixer?: number;\r\n grainOverlay?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA;AAAA,OAGO;AACP,SAAS,WAAW,WAAW,wBAAwB;AAEhD,MAAM,mBAAmB;AAAA,EAC9B,eAAe;AACjB;AAkCO,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA,wBAK1B,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWpD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA4DM,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;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { vec4 } from '../types.js';
|
|
2
|
+
import type { ShaderMotionParams } from '../shader-mount.js';
|
|
3
|
+
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
4
|
+
export declare const metaballsMeta: {
|
|
5
|
+
readonly maxColorCount: 8;
|
|
6
|
+
readonly maxBallsCount: 20;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Up to 20 colored gooey balls moving around the center and merging into smooth organic shapes.
|
|
10
|
+
*
|
|
11
|
+
* Fragment shader uniforms:
|
|
12
|
+
* - u_time (float): Animation time
|
|
13
|
+
* - u_colorBack (vec4): Background color in RGBA
|
|
14
|
+
* - u_colors (vec4[]): Up to 8 base colors in RGBA, applied to the balls in order (colors beyond u_count are unused)
|
|
15
|
+
* - u_colorsCount (float): Number of active colors
|
|
16
|
+
* - u_count (float): Number of balls, fractional values shrink the last ball (1 to 20)
|
|
17
|
+
* - u_size (float): Size of the balls (0 to 1)
|
|
18
|
+
* - u_noiseTexture (sampler2D): Pre-computed randomizer source texture
|
|
19
|
+
*
|
|
20
|
+
* Vertex shader outputs (used in fragment shader):
|
|
21
|
+
* - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
|
|
22
|
+
*
|
|
23
|
+
* Vertex shader uniforms:
|
|
24
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
25
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
26
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
27
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
28
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
29
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
30
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
31
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
32
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
33
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
34
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export declare const metaballsFragmentShader: string;
|
|
38
|
+
export interface MetaballsUniforms extends ShaderSizingUniforms {
|
|
39
|
+
u_colorBack: [number, number, number, number];
|
|
40
|
+
u_colors: vec4[];
|
|
41
|
+
u_colorsCount: number;
|
|
42
|
+
u_count: number;
|
|
43
|
+
u_size: number;
|
|
44
|
+
u_noiseTexture?: HTMLImageElement;
|
|
45
|
+
}
|
|
46
|
+
export interface MetaballsParams extends ShaderSizingParams, ShaderMotionParams {
|
|
47
|
+
colorBack?: string;
|
|
48
|
+
colors?: string[];
|
|
49
|
+
count?: number;
|
|
50
|
+
size?: number;
|
|
51
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import {} from "../shader-sizing.js";
|
|
7
|
+
import { declarePI, textureRandomizerR, colorBandingFix } from "../shader-utils.js";
|
|
8
|
+
const metaballsMeta = {
|
|
9
|
+
maxColorCount: 8,
|
|
10
|
+
maxBallsCount: 20
|
|
11
|
+
};
|
|
12
|
+
const metaballsFragmentShader = `#version 300 es
|
|
13
|
+
precision mediump float;
|
|
14
|
+
|
|
15
|
+
uniform float u_time;
|
|
16
|
+
|
|
17
|
+
uniform sampler2D u_noiseTexture;
|
|
18
|
+
|
|
19
|
+
uniform vec4 u_colorBack;
|
|
20
|
+
uniform vec4 u_colors[${metaballsMeta.maxColorCount}];
|
|
21
|
+
uniform float u_colorsCount;
|
|
22
|
+
uniform float u_size;
|
|
23
|
+
uniform float u_count;
|
|
24
|
+
|
|
25
|
+
in vec2 v_objectUV;
|
|
26
|
+
|
|
27
|
+
out vec4 fragColor;
|
|
28
|
+
|
|
29
|
+
${declarePI}
|
|
30
|
+
${textureRandomizerR}
|
|
31
|
+
float noise(float x) {
|
|
32
|
+
float i = floor(x);
|
|
33
|
+
float f = fract(x);
|
|
34
|
+
float u = f * f * (3.0 - 2.0 * f);
|
|
35
|
+
vec2 p0 = vec2(i, 0.0);
|
|
36
|
+
vec2 p1 = vec2(i + 1.0, 0.0);
|
|
37
|
+
return mix(randomR(p0), randomR(p1), u);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
float getBallShape(vec2 uv, vec2 c, float p) {
|
|
41
|
+
float s = .5 * length(uv - c);
|
|
42
|
+
s = 1. - clamp(s, 0., 1.);
|
|
43
|
+
s = pow(s, p);
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
void main() {
|
|
48
|
+
vec2 shape_uv = v_objectUV;
|
|
49
|
+
|
|
50
|
+
shape_uv += .5;
|
|
51
|
+
|
|
52
|
+
const float firstFrameOffset = 2503.4;
|
|
53
|
+
float t = .2 * (u_time + firstFrameOffset);
|
|
54
|
+
|
|
55
|
+
vec3 totalColor = vec3(0.);
|
|
56
|
+
float totalShape = 0.;
|
|
57
|
+
float totalOpacity = 0.;
|
|
58
|
+
|
|
59
|
+
for (int i = 0; i < ${metaballsMeta.maxBallsCount}; i++) {
|
|
60
|
+
if (i >= int(ceil(u_count))) break;
|
|
61
|
+
|
|
62
|
+
float idxFract = float(i) / float(${metaballsMeta.maxBallsCount});
|
|
63
|
+
float angle = TWO_PI * idxFract;
|
|
64
|
+
|
|
65
|
+
float speed = 1. - .2 * idxFract;
|
|
66
|
+
float noiseX = noise(angle * 10. + float(i) + t * speed);
|
|
67
|
+
float noiseY = noise(angle * 20. + float(i) - t * speed);
|
|
68
|
+
|
|
69
|
+
vec2 pos = vec2(.5) + 1e-4 + .9 * (vec2(noiseX, noiseY) - .5);
|
|
70
|
+
|
|
71
|
+
int safeIndex = i % int(u_colorsCount + 0.5);
|
|
72
|
+
vec4 ballColor = u_colors[safeIndex];
|
|
73
|
+
ballColor.rgb *= ballColor.a;
|
|
74
|
+
|
|
75
|
+
float sizeFrac = 1.;
|
|
76
|
+
if (float(i) > floor(u_count - 1.)) {
|
|
77
|
+
sizeFrac *= fract(u_count);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
float shape = getBallShape(shape_uv, pos, 45. - 30. * u_size * sizeFrac);
|
|
81
|
+
shape *= pow(u_size, .2);
|
|
82
|
+
shape = smoothstep(0., 1., shape);
|
|
83
|
+
|
|
84
|
+
totalColor += ballColor.rgb * shape;
|
|
85
|
+
totalShape += shape;
|
|
86
|
+
totalOpacity += ballColor.a * shape;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
totalColor /= max(totalShape, 1e-4);
|
|
90
|
+
totalOpacity /= max(totalShape, 1e-4);
|
|
91
|
+
|
|
92
|
+
float edge_width = fwidth(totalShape);
|
|
93
|
+
float finalShape = smoothstep(.4, .4 + edge_width, totalShape);
|
|
94
|
+
|
|
95
|
+
vec3 color = totalColor * finalShape;
|
|
96
|
+
float opacity = totalOpacity * finalShape;
|
|
97
|
+
|
|
98
|
+
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
99
|
+
color = color + bgColor * (1. - opacity);
|
|
100
|
+
opacity = opacity + u_colorBack.a * (1. - opacity);
|
|
101
|
+
|
|
102
|
+
${colorBandingFix}
|
|
103
|
+
|
|
104
|
+
fragColor = vec4(color, opacity);
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
export {
|
|
108
|
+
metaballsFragmentShader,
|
|
109
|
+
metaballsMeta
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=metaballs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/metaballs.ts"],
|
|
4
|
+
"sourcesContent": ["import type { vec4 } from '../types.js';\r\nimport type { ShaderMotionParams } from '../shader-mount.js';\r\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\r\nimport { declarePI, textureRandomizerR, colorBandingFix } from '../shader-utils.js';\r\n\r\nexport const metaballsMeta = {\r\n maxColorCount: 8,\r\n maxBallsCount: 20,\r\n} as const;\r\n\r\n/**\r\n * Up to 20 colored gooey balls moving around the center and merging into smooth organic shapes.\r\n *\r\n * Fragment shader uniforms:\r\n * - u_time (float): Animation time\r\n * - u_colorBack (vec4): Background color in RGBA\r\n * - u_colors (vec4[]): Up to 8 base colors in RGBA, applied to the balls in order (colors beyond u_count are unused)\r\n * - u_colorsCount (float): Number of active colors\r\n * - u_count (float): Number of balls, fractional values shrink the last ball (1 to 20)\r\n * - u_size (float): Size of the balls (0 to 1)\r\n * - u_noiseTexture (sampler2D): Pre-computed randomizer source texture\r\n *\r\n * Vertex shader outputs (used in fragment shader):\r\n * - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied\r\n *\r\n * Vertex shader uniforms:\r\n * - u_resolution (vec2): Canvas resolution in pixels\r\n * - u_pixelRatio (float): Device pixel ratio\r\n * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)\r\n * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)\r\n * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas\r\n * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas\r\n * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)\r\n * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)\r\n * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)\r\n * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)\r\n * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)\r\n *\r\n */\r\n\r\n// language=GLSL\r\nexport const metaballsFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform float u_time;\r\n\r\nuniform sampler2D u_noiseTexture;\r\n\r\nuniform vec4 u_colorBack;\r\nuniform vec4 u_colors[${ metaballsMeta.maxColorCount }];\r\nuniform float u_colorsCount;\r\nuniform float u_size;\r\nuniform float u_count;\r\n\r\nin vec2 v_objectUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ declarePI }\r\n${ textureRandomizerR }\r\nfloat noise(float x) {\r\n float i = floor(x);\r\n float f = fract(x);\r\n float u = f * f * (3.0 - 2.0 * f);\r\n vec2 p0 = vec2(i, 0.0);\r\n vec2 p1 = vec2(i + 1.0, 0.0);\r\n return mix(randomR(p0), randomR(p1), u);\r\n}\r\n\r\nfloat getBallShape(vec2 uv, vec2 c, float p) {\r\n float s = .5 * length(uv - c);\r\n s = 1. - clamp(s, 0., 1.);\r\n s = pow(s, p);\r\n return s;\r\n}\r\n\r\nvoid main() {\r\n vec2 shape_uv = v_objectUV;\r\n\r\n shape_uv += .5;\r\n\r\n const float firstFrameOffset = 2503.4;\r\n float t = .2 * (u_time + firstFrameOffset);\r\n\r\n vec3 totalColor = vec3(0.);\r\n float totalShape = 0.;\r\n float totalOpacity = 0.;\r\n\r\n for (int i = 0; i < ${ metaballsMeta.maxBallsCount }; i++) {\r\n if (i >= int(ceil(u_count))) break;\r\n\r\n float idxFract = float(i) / float(${ metaballsMeta.maxBallsCount });\r\n float angle = TWO_PI * idxFract;\r\n\r\n float speed = 1. - .2 * idxFract;\r\n float noiseX = noise(angle * 10. + float(i) + t * speed);\r\n float noiseY = noise(angle * 20. + float(i) - t * speed);\r\n\r\n vec2 pos = vec2(.5) + 1e-4 + .9 * (vec2(noiseX, noiseY) - .5);\r\n\r\n int safeIndex = i % int(u_colorsCount + 0.5);\r\n vec4 ballColor = u_colors[safeIndex];\r\n ballColor.rgb *= ballColor.a;\r\n\r\n float sizeFrac = 1.;\r\n if (float(i) > floor(u_count - 1.)) {\r\n sizeFrac *= fract(u_count);\r\n }\r\n\r\n float shape = getBallShape(shape_uv, pos, 45. - 30. * u_size * sizeFrac);\r\n shape *= pow(u_size, .2);\r\n shape = smoothstep(0., 1., shape);\r\n\r\n totalColor += ballColor.rgb * shape;\r\n totalShape += shape;\r\n totalOpacity += ballColor.a * shape;\r\n }\r\n\r\n totalColor /= max(totalShape, 1e-4);\r\n totalOpacity /= max(totalShape, 1e-4);\r\n\r\n float edge_width = fwidth(totalShape);\r\n float finalShape = smoothstep(.4, .4 + edge_width, totalShape);\r\n\r\n vec3 color = totalColor * finalShape;\r\n float opacity = totalOpacity * finalShape;\r\n\r\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\r\n color = color + bgColor * (1. - opacity);\r\n opacity = opacity + u_colorBack.a * (1. - opacity);\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\nexport interface MetaballsUniforms extends ShaderSizingUniforms {\r\n u_colorBack: [number, number, number, number];\r\n u_colors: vec4[];\r\n u_colorsCount: number;\r\n u_count: number;\r\n u_size: number;\r\n u_noiseTexture?: HTMLImageElement;\r\n}\r\n\r\nexport interface MetaballsParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorBack?: string;\r\n colors?: string[];\r\n count?: number;\r\n size?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,eAAmE;AACnE,SAAS,WAAW,oBAAoB,uBAAuB;AAExD,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,eAAe;AACjB;AAiCO,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQtB,cAAc,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlD,SAAU;AAAA,EACV,kBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA6BG,cAAc,aAAc;AAAA;AAAA;AAAA,wCAGZ,cAAc,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwChE,eAAgB;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ShaderMotionParams } from '../shader-mount.js';
|
|
2
|
+
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
3
|
+
/**
|
|
4
|
+
* A glowing, web-like structure of fluid lines and soft intersections.
|
|
5
|
+
* Great for creating atmospheric, organic-yet-futuristic visuals.
|
|
6
|
+
*
|
|
7
|
+
* Fragment shader uniforms:
|
|
8
|
+
* - u_time (float): Animation time
|
|
9
|
+
* - u_colorFront (vec4): Graphics highlight color in RGBA
|
|
10
|
+
* - u_colorMid (vec4): Graphics main color in RGBA
|
|
11
|
+
* - u_colorBack (vec4): Background color in RGBA
|
|
12
|
+
* - u_brightness (float): Luminosity of the crossing points (0 to 1)
|
|
13
|
+
* - u_contrast (float): Sharpness of the transition between colorMid and colorBack (0 to 1)
|
|
14
|
+
*
|
|
15
|
+
* Vertex shader outputs (used in fragment shader):
|
|
16
|
+
* - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied
|
|
17
|
+
*
|
|
18
|
+
* Vertex shader uniforms:
|
|
19
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
20
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
21
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
22
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
23
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
24
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
25
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
26
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
27
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
28
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
29
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
30
|
+
*
|
|
31
|
+
* Original algorithm: https://x.com/zozuar/status/1625182758745128981/
|
|
32
|
+
*/
|
|
33
|
+
export declare const neuroNoiseFragmentShader: string;
|
|
34
|
+
export interface NeuroNoiseUniforms extends ShaderSizingUniforms {
|
|
35
|
+
u_colorFront: [number, number, number, number];
|
|
36
|
+
u_colorMid: [number, number, number, number];
|
|
37
|
+
u_colorBack: [number, number, number, number];
|
|
38
|
+
u_brightness: number;
|
|
39
|
+
u_contrast: number;
|
|
40
|
+
}
|
|
41
|
+
export interface NeuroNoiseParams extends ShaderSizingParams, ShaderMotionParams {
|
|
42
|
+
colorFront?: string;
|
|
43
|
+
colorMid?: string;
|
|
44
|
+
colorBack?: string;
|
|
45
|
+
brightness?: number;
|
|
46
|
+
contrast?: number;
|
|
47
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import {} from "../shader-sizing.js";
|
|
7
|
+
import { rotation2, colorBandingFix } from "../shader-utils.js";
|
|
8
|
+
const neuroNoiseFragmentShader = `#version 300 es
|
|
9
|
+
precision mediump float;
|
|
10
|
+
|
|
11
|
+
uniform float u_time;
|
|
12
|
+
|
|
13
|
+
uniform vec4 u_colorFront;
|
|
14
|
+
uniform vec4 u_colorMid;
|
|
15
|
+
uniform vec4 u_colorBack;
|
|
16
|
+
uniform float u_brightness;
|
|
17
|
+
uniform float u_contrast;
|
|
18
|
+
|
|
19
|
+
in vec2 v_patternUV;
|
|
20
|
+
|
|
21
|
+
out vec4 fragColor;
|
|
22
|
+
|
|
23
|
+
${rotation2}
|
|
24
|
+
|
|
25
|
+
float neuroShape(vec2 uv, float t) {
|
|
26
|
+
vec2 sine_acc = vec2(0.);
|
|
27
|
+
vec2 res = vec2(0.);
|
|
28
|
+
float scale = 8.;
|
|
29
|
+
|
|
30
|
+
for (int j = 0; j < 15; j++) {
|
|
31
|
+
uv = rotate(uv, 1.);
|
|
32
|
+
sine_acc = rotate(sine_acc, 1.);
|
|
33
|
+
vec2 layer = uv * scale + float(j) + sine_acc - t;
|
|
34
|
+
sine_acc += sin(layer);
|
|
35
|
+
res += (.5 + .5 * cos(layer)) / scale;
|
|
36
|
+
scale *= (1.2);
|
|
37
|
+
}
|
|
38
|
+
return res.x + res.y;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void main() {
|
|
42
|
+
vec2 shape_uv = v_patternUV;
|
|
43
|
+
shape_uv *= .13;
|
|
44
|
+
|
|
45
|
+
float t = .5 * u_time;
|
|
46
|
+
|
|
47
|
+
float noise = neuroShape(shape_uv, t);
|
|
48
|
+
|
|
49
|
+
noise = (1. + u_brightness) * noise * noise;
|
|
50
|
+
noise = pow(noise, .7 + 6. * u_contrast);
|
|
51
|
+
noise = min(1.4, noise);
|
|
52
|
+
|
|
53
|
+
float blend = smoothstep(0.7, 1.4, noise);
|
|
54
|
+
|
|
55
|
+
vec4 frontC = u_colorFront;
|
|
56
|
+
frontC.rgb *= frontC.a;
|
|
57
|
+
vec4 midC = u_colorMid;
|
|
58
|
+
midC.rgb *= midC.a;
|
|
59
|
+
vec4 blendFront = mix(midC, frontC, blend);
|
|
60
|
+
|
|
61
|
+
float safeNoise = max(noise, 0.0);
|
|
62
|
+
vec3 color = blendFront.rgb * safeNoise;
|
|
63
|
+
float opacity = clamp(blendFront.a * safeNoise, 0., 1.);
|
|
64
|
+
|
|
65
|
+
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
66
|
+
color = color + bgColor * (1. - opacity);
|
|
67
|
+
opacity = opacity + u_colorBack.a * (1. - opacity);
|
|
68
|
+
|
|
69
|
+
${colorBandingFix}
|
|
70
|
+
|
|
71
|
+
fragColor = vec4(color, opacity);
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
export {
|
|
75
|
+
neuroNoiseFragmentShader
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=neuro-noise.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/neuro-noise.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\r\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\r\nimport { rotation2, colorBandingFix } from '../shader-utils.js';\r\n\r\n/**\r\n * A glowing, web-like structure of fluid lines and soft intersections.\r\n * Great for creating atmospheric, organic-yet-futuristic visuals.\r\n *\r\n * Fragment shader uniforms:\r\n * - u_time (float): Animation time\r\n * - u_colorFront (vec4): Graphics highlight color in RGBA\r\n * - u_colorMid (vec4): Graphics main color in RGBA\r\n * - u_colorBack (vec4): Background color in RGBA\r\n * - u_brightness (float): Luminosity of the crossing points (0 to 1)\r\n * - u_contrast (float): Sharpness of the transition between colorMid and colorBack (0 to 1)\r\n *\r\n * Vertex shader outputs (used in fragment shader):\r\n * - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied\r\n *\r\n * Vertex shader uniforms:\r\n * - u_resolution (vec2): Canvas resolution in pixels\r\n * - u_pixelRatio (float): Device pixel ratio\r\n * - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)\r\n * - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)\r\n * - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas\r\n * - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas\r\n * - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)\r\n * - u_scale (float): Overall zoom level of the graphics (0.01 to 4)\r\n * - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)\r\n * - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)\r\n * - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)\r\n *\r\n * Original algorithm: https://x.com/zozuar/status/1625182758745128981/\r\n */\r\n\r\n// language=GLSL\r\nexport const neuroNoiseFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colorFront;\r\nuniform vec4 u_colorMid;\r\nuniform vec4 u_colorBack;\r\nuniform float u_brightness;\r\nuniform float u_contrast;\r\n\r\nin vec2 v_patternUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ rotation2 }\r\n\r\nfloat neuroShape(vec2 uv, float t) {\r\n vec2 sine_acc = vec2(0.);\r\n vec2 res = vec2(0.);\r\n float scale = 8.;\r\n\r\n for (int j = 0; j < 15; j++) {\r\n uv = rotate(uv, 1.);\r\n sine_acc = rotate(sine_acc, 1.);\r\n vec2 layer = uv * scale + float(j) + sine_acc - t;\r\n sine_acc += sin(layer);\r\n res += (.5 + .5 * cos(layer)) / scale;\r\n scale *= (1.2);\r\n }\r\n return res.x + res.y;\r\n}\r\n\r\nvoid main() {\r\n vec2 shape_uv = v_patternUV;\r\n shape_uv *= .13;\r\n\r\n float t = .5 * u_time;\r\n\r\n float noise = neuroShape(shape_uv, t);\r\n\r\n noise = (1. + u_brightness) * noise * noise;\r\n noise = pow(noise, .7 + 6. * u_contrast);\r\n noise = min(1.4, noise);\r\n\r\n float blend = smoothstep(0.7, 1.4, noise);\r\n\r\n vec4 frontC = u_colorFront;\r\n frontC.rgb *= frontC.a;\r\n vec4 midC = u_colorMid;\r\n midC.rgb *= midC.a;\r\n vec4 blendFront = mix(midC, frontC, blend);\r\n\r\n float safeNoise = max(noise, 0.0);\r\n vec3 color = blendFront.rgb * safeNoise;\r\n float opacity = clamp(blendFront.a * safeNoise, 0., 1.);\r\n\r\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\r\n color = color + bgColor * (1. - opacity);\r\n opacity = opacity + u_colorBack.a * (1. - opacity);\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\nexport interface NeuroNoiseUniforms extends ShaderSizingUniforms {\r\n u_colorFront: [number, number, number, number];\r\n u_colorMid: [number, number, number, number];\r\n u_colorBack: [number, number, number, number];\r\n u_brightness: number;\r\n u_contrast: number;\r\n}\r\n\r\nexport interface NeuroNoiseParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorFront?: string;\r\n colorMid?: string;\r\n colorBack?: string;\r\n brightness?: number;\r\n contrast?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,eAAmE;AACnE,SAAS,WAAW,uBAAuB;AAkCpC,MAAM,2BAAmC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAe7C,SAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8CR,eAAgB;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|