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/pulsing-border.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, textureRandomizerGB, colorBandingFix } from '../shader-utils.js';\r\n\r\nexport const pulsingBorderMeta = {\r\n maxColorCount: 5,\r\n maxSpots: 4,\r\n} as const;\r\n\r\n/**\r\n * Luminous trails of color merging into a glowing gradient contour.\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 5 spot colors in RGBA\r\n * - u_colorsCount (float): Number of active colors\r\n * - u_roundness (float): Border radius (0 to 1)\r\n * - u_thickness (float): Border base width (0 to 1)\r\n * - u_softness (float): Border edge sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)\r\n * - u_marginLeft (float): Distance from the left edge to the effect (0 to 1)\r\n * - u_marginRight (float): Distance from the right edge to the effect (0 to 1)\r\n * - u_marginTop (float): Distance from the top edge to the effect (0 to 1)\r\n * - u_marginBottom (float): Distance from the bottom edge to the effect (0 to 1)\r\n * - u_aspectRatio (float): Aspect ratio mode (0 = auto, 1 = square)\r\n * - u_intensity (float): Thickness of individual color spots (0 to 1)\r\n * - u_bloom (float): Power of glow, 0 = normal blending, 1 = additive blending (0 to 1)\r\n * - u_spots (float): Number of spots added for each color (1 to 4)\r\n * - u_spotSize (float): Angular size of spots (0 to 1)\r\n * - u_pulse (float): Optional pulsing animation intensity (0 to 1)\r\n * - u_smoke (float): Optional noisy shape extending the border (0 to 1)\r\n * - u_smokeSize (float): Size of the smoke effect, needs smoke > 0 (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_responsiveUV (vec2): Responsive UV coordinates that adapt to canvas aspect ratio\r\n * - v_responsiveBoxGivenSize (vec2): Given size of the responsive bounding box\r\n * - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied (used for smoke calculation)\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 pulsingBorderFragmentShader: string = `#version 300 es\r\nprecision lowp float;\r\n\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colorBack;\r\nuniform vec4 u_colors[${ pulsingBorderMeta.maxColorCount }];\r\nuniform float u_colorsCount;\r\nuniform float u_roundness;\r\nuniform float u_thickness;\r\nuniform float u_marginLeft;\r\nuniform float u_marginRight;\r\nuniform float u_marginTop;\r\nuniform float u_marginBottom;\r\nuniform float u_aspectRatio;\r\nuniform float u_softness;\r\nuniform float u_intensity;\r\nuniform float u_bloom;\r\nuniform float u_spotSize;\r\nuniform float u_spots;\r\nuniform float u_pulse;\r\nuniform float u_smoke;\r\nuniform float u_smokeSize;\r\n\r\nuniform sampler2D u_noiseTexture;\r\n\r\nin vec2 v_responsiveUV;\r\nin vec2 v_responsiveBoxGivenSize;\r\nin vec2 v_patternUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ declarePI }\r\n\r\nfloat beat(float time) {\r\n float first = pow(abs(sin(time * TWO_PI)), 10.);\r\n float second = pow(abs(sin((time - .15) * TWO_PI)), 10.);\r\n\r\n return clamp(first + 0.6 * second, 0.0, 1.0);\r\n}\r\n\r\nfloat sst(float edge0, float edge1, float x) {\r\n return smoothstep(edge0, edge1, x);\r\n}\r\n\r\nfloat roundedBox(vec2 uv, vec2 halfSize, float distance, float cornerDistance, float thickness, float softness) {\r\n float borderDistance = abs(distance);\r\n float aa = 2. * fwidth(distance);\r\n float border = 1. - sst(min(mix(thickness, -thickness, softness), thickness + aa), max(mix(thickness, -thickness, softness), thickness + aa), borderDistance);\r\n float cornerFadeCircles = 0.;\r\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv + halfSize) / thickness)));\r\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(-halfSize.x, halfSize.y)) / thickness)));\r\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(halfSize.x, -halfSize.y)) / thickness)));\r\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - halfSize) / thickness)));\r\n aa = fwidth(cornerDistance);\r\n float cornerFade = sst(0., mix(aa, thickness, softness), cornerDistance);\r\n cornerFade *= cornerFadeCircles;\r\n border += cornerFade;\r\n return border;\r\n}\r\n\r\n${ textureRandomizerGB }\r\n\r\nfloat randomG(vec2 p) {\r\n vec2 uv = floor(p) / 100. + .5;\r\n return texture(u_noiseTexture, fract(uv)).g;\r\n}\r\nfloat valueNoise(vec2 st) {\r\n vec2 i = floor(st);\r\n vec2 f = fract(st);\r\n float a = randomG(i);\r\n float b = randomG(i + vec2(1.0, 0.0));\r\n float c = randomG(i + vec2(0.0, 1.0));\r\n float d = randomG(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\nvoid main() {\r\n const float firstFrameOffset = 109.;\r\n float t = 1.2 * (u_time + firstFrameOffset);\r\n\r\n vec2 borderUV = v_responsiveUV;\r\n float pulse = u_pulse * beat(.18 * u_time);\r\n\r\n float canvasRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\r\n vec2 halfSize = vec2(.5);\r\n borderUV.x *= max(canvasRatio, 1.);\r\n borderUV.y /= min(canvasRatio, 1.);\r\n halfSize.x *= max(canvasRatio, 1.);\r\n halfSize.y /= min(canvasRatio, 1.);\r\n\r\n float mL = u_marginLeft;\r\n float mR = u_marginRight;\r\n float mT = u_marginTop;\r\n float mB = u_marginBottom;\r\n float mX = mL + mR;\r\n float mY = mT + mB;\r\n\r\n if (u_aspectRatio > 0.) {\r\n float shapeRatio = canvasRatio * (1. - mX) / max(1. - mY, 1e-6);\r\n float freeX = shapeRatio > 1. ? (1. - mX) * (1. - 1. / max(abs(shapeRatio), 1e-6)) : 0.;\r\n float freeY = shapeRatio < 1. ? (1. - mY) * (1. - shapeRatio) : 0.;\r\n mL += freeX * 0.5;\r\n mR += freeX * 0.5;\r\n mT += freeY * 0.5;\r\n mB += freeY * 0.5;\r\n mX = mL + mR;\r\n mY = mT + mB;\r\n }\r\n\r\n float thickness = .5 * u_thickness * min(halfSize.x, halfSize.y);\r\n\r\n halfSize.x *= (1. - mX);\r\n halfSize.y *= (1. - mY);\r\n\r\n vec2 centerShift = vec2(\r\n (mL - mR) * max(canvasRatio, 1.) * 0.5,\r\n (mB - mT) / min(canvasRatio, 1.) * 0.5\r\n );\r\n\r\n borderUV -= centerShift;\r\n halfSize -= mix(thickness, 0., u_softness);\r\n\r\n float radius = mix(0., min(halfSize.x, halfSize.y), u_roundness);\r\n vec2 d = abs(borderUV) - halfSize + radius;\r\n float outsideDistance = length(max(d, .0001)) - radius;\r\n float insideDistance = min(max(d.x, d.y), .0001);\r\n float cornerDistance = abs(min(max(d.x, d.y) - .45 * radius, .0));\r\n float distance = outsideDistance + insideDistance;\r\n\r\n float borderThickness = mix(thickness, 3. * thickness, u_softness);\r\n float border = roundedBox(borderUV, halfSize, distance, cornerDistance, borderThickness, u_softness);\r\n border = pow(border, 1. + u_softness);\r\n\r\n vec2 smokeUV = .3 * u_smokeSize * v_patternUV;\r\n float smoke = clamp(3. * valueNoise(2.7 * smokeUV + .5 * t), 0., 1.);\r\n smoke -= valueNoise(3.4 * smokeUV - .5 * t);\r\n float smokeThickness = thickness + .2;\r\n smokeThickness = min(.4, max(smokeThickness, .1));\r\n smoke *= roundedBox(borderUV, halfSize, distance, cornerDistance, smokeThickness, 1.);\r\n smoke = 30. * smoke * smoke;\r\n smoke *= mix(0., .5, pow(u_smoke, 2.));\r\n smoke *= mix(1., pulse, u_pulse);\r\n smoke = clamp(smoke, 0., 1.);\r\n border += smoke;\r\n\r\n border = clamp(border, 0., 1.);\r\n\r\n vec3 blendColor = vec3(0.);\r\n float blendAlpha = 0.;\r\n vec3 addColor = vec3(0.);\r\n float addAlpha = 0.;\r\n\r\n float bloom = 4. * u_bloom;\r\n float intensity = 1. + (1. + 4. * u_softness) * u_intensity;\r\n\r\n float angle = atan(borderUV.y, borderUV.x) / TWO_PI;\r\n\r\n for (int colorIdx = 0; colorIdx < ${ pulsingBorderMeta.maxColorCount }; colorIdx++) {\r\n if (colorIdx >= int(u_colorsCount)) break;\r\n float colorIdxF = float(colorIdx);\r\n\r\n vec3 c = u_colors[colorIdx].rgb * u_colors[colorIdx].a;\r\n float a = u_colors[colorIdx].a;\r\n\r\n for (int spotIdx = 0; spotIdx < ${ pulsingBorderMeta.maxSpots }; spotIdx++) {\r\n if (spotIdx >= int(u_spots)) break;\r\n float spotIdxF = float(spotIdx);\r\n\r\n vec2 randVal = randomGB(vec2(spotIdxF * 10. + 2., 40. + colorIdxF));\r\n\r\n float time = (.1 + .15 * abs(sin(spotIdxF * (2. + colorIdxF)) * cos(spotIdxF * (2. + 2.5 * colorIdxF)))) * t + randVal.x * 3.;\r\n time *= mix(1., -1., step(.5, randVal.y));\r\n\r\n float mask = .5 + .5 * mix(\r\n sin(t + spotIdxF * (5. - 1.5 * colorIdxF)),\r\n cos(t + spotIdxF * (3. + 1.3 * colorIdxF)),\r\n step(mod(colorIdxF, 2.), .5)\r\n );\r\n\r\n float p = clamp(2. * u_pulse - randVal.x, 0., 1.);\r\n mask = mix(mask, pulse, p);\r\n\r\n float atg1 = fract(angle + time);\r\n float spotSize = .05 + .6 * pow(u_spotSize, 2.) + .05 * randVal.x;\r\n spotSize = mix(spotSize, .1, p);\r\n float sector = sst(.5 - spotSize, .5, atg1) * (1. - sst(.5, .5 + spotSize, atg1));\r\n\r\n sector *= mask;\r\n sector *= border;\r\n sector *= intensity;\r\n sector = clamp(sector, 0., 1.);\r\n\r\n vec3 srcColor = c * sector;\r\n float srcAlpha = a * sector;\r\n\r\n blendColor += ((1. - blendAlpha) * srcColor);\r\n blendAlpha = blendAlpha + (1. - blendAlpha) * srcAlpha;\r\n addColor += srcColor;\r\n addAlpha += srcAlpha;\r\n }\r\n }\r\n\r\n vec3 accumColor = mix(blendColor, addColor, bloom);\r\n float accumAlpha = mix(blendAlpha, addAlpha, bloom);\r\n accumAlpha = clamp(accumAlpha, 0., 1.);\r\n\r\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\r\n vec3 color = accumColor + (1. - accumAlpha) * bgColor;\r\n float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}`;\r\n\r\nexport interface PulsingBorderUniforms extends ShaderSizingUniforms {\r\n u_colorBack: [number, number, number, number];\r\n u_colors: vec4[];\r\n u_colorsCount: number;\r\n u_roundness: number;\r\n u_thickness: number;\r\n u_marginLeft: number;\r\n u_marginRight: number;\r\n u_marginTop: number;\r\n u_marginBottom: number;\r\n u_aspectRatio: (typeof PulsingBorderAspectRatios)[PulsingBorderAspectRatio];\r\n u_softness: number;\r\n u_intensity: number;\r\n u_bloom: number;\r\n u_spots: number;\r\n u_spotSize: number;\r\n u_pulse: number;\r\n u_smoke: number;\r\n u_smokeSize: number;\r\n u_noiseTexture?: HTMLImageElement;\r\n}\r\n\r\nexport interface PulsingBorderParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorBack?: string;\r\n colors?: string[];\r\n roundness?: number;\r\n thickness?: number;\r\n margin?: number;\r\n marginLeft?: number;\r\n marginRight?: number;\r\n marginTop?: number;\r\n marginBottom?: number;\r\n aspectRatio?: PulsingBorderAspectRatio;\r\n softness?: number;\r\n intensity?: number;\r\n bloom?: number;\r\n spots?: number;\r\n spotSize?: number;\r\n pulse?: number;\r\n smoke?: number;\r\n smokeSize?: number;\r\n}\r\n\r\nexport const PulsingBorderAspectRatios = {\r\n auto: 0,\r\n square: 1,\r\n} as const;\r\n\r\nexport type PulsingBorderAspectRatio = keyof typeof PulsingBorderAspectRatios;\r\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,eAAmE;AACnE,SAAS,WAAW,qBAAqB,uBAAuB;AAEzD,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AAAA,EACf,UAAU;AACZ;AAgDO,MAAM,8BAAsC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAM1B,kBAAkB,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,EA0BtD,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,EA6BV,mBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAoGgB,kBAAkB,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAOhC,kBAAkB,QAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8C7D,eAAgB;AAAA;AAAA;AAAA;AAgDd,MAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,QAAQ;AACV;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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 simplexNoiseMeta: {
|
|
5
|
+
readonly maxColorCount: 10;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A multi-color gradient mapped into smooth, animated curves built as a combination of 2 Simplex noises.
|
|
9
|
+
*
|
|
10
|
+
* Fragment shader uniforms:
|
|
11
|
+
* - u_time (float): Animation time
|
|
12
|
+
* - u_colors (vec4[]): Up to 10 base colors in RGBA
|
|
13
|
+
* - u_colorsCount (float): Number of active colors
|
|
14
|
+
* - u_stepsPerColor (float): Number of extra colors between base colors, 1 = N colors, 2 = 2×N, etc., needs 2+ colors (1 to 10)
|
|
15
|
+
* - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient, needs 2+ colors (0 to 1)
|
|
16
|
+
*
|
|
17
|
+
* Vertex shader outputs (used in fragment shader):
|
|
18
|
+
* - v_patternUV (vec2): UV coordinates for pattern with global sizing (rotation, scale, offset, etc) applied
|
|
19
|
+
*
|
|
20
|
+
* Vertex shader uniforms:
|
|
21
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
22
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
23
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
24
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
25
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
26
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
27
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
28
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
29
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
30
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
31
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
export declare const simplexNoiseFragmentShader: string;
|
|
35
|
+
export interface SimplexNoiseUniforms extends ShaderSizingUniforms {
|
|
36
|
+
u_colors: vec4[];
|
|
37
|
+
u_colorsCount: number;
|
|
38
|
+
u_stepsPerColor: number;
|
|
39
|
+
u_softness: number;
|
|
40
|
+
}
|
|
41
|
+
export interface SimplexNoiseParams extends ShaderSizingParams, ShaderMotionParams {
|
|
42
|
+
colors?: string[];
|
|
43
|
+
stepsPerColor?: number;
|
|
44
|
+
softness?: number;
|
|
45
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import {} from "../shader-sizing.js";
|
|
7
|
+
import { simplexNoise, colorBandingFix } from "../shader-utils.js";
|
|
8
|
+
const simplexNoiseMeta = {
|
|
9
|
+
maxColorCount: 10
|
|
10
|
+
};
|
|
11
|
+
const simplexNoiseFragmentShader = `#version 300 es
|
|
12
|
+
precision mediump float;
|
|
13
|
+
|
|
14
|
+
uniform float u_time;
|
|
15
|
+
|
|
16
|
+
uniform vec4 u_colors[${simplexNoiseMeta.maxColorCount}];
|
|
17
|
+
uniform float u_colorsCount;
|
|
18
|
+
uniform float u_stepsPerColor;
|
|
19
|
+
uniform float u_softness;
|
|
20
|
+
|
|
21
|
+
in vec2 v_patternUV;
|
|
22
|
+
|
|
23
|
+
out vec4 fragColor;
|
|
24
|
+
|
|
25
|
+
${simplexNoise}
|
|
26
|
+
|
|
27
|
+
float getNoise(vec2 uv, float t) {
|
|
28
|
+
float noise = .5 * snoise(uv - vec2(0., .3 * t));
|
|
29
|
+
noise += .5 * snoise(2. * uv + vec2(0., .32 * t));
|
|
30
|
+
|
|
31
|
+
return noise;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
float steppedSmooth(float m, float steps, float softness) {
|
|
35
|
+
float stepT = floor(m * steps) / steps;
|
|
36
|
+
float f = m * steps - floor(m * steps);
|
|
37
|
+
float fw = steps * fwidth(m);
|
|
38
|
+
float smoothed = smoothstep(.5 - softness, min(1., .5 + softness + fw), f);
|
|
39
|
+
return stepT + smoothed / steps;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void main() {
|
|
43
|
+
vec2 shape_uv = v_patternUV;
|
|
44
|
+
shape_uv *= .1;
|
|
45
|
+
|
|
46
|
+
float t = .2 * u_time;
|
|
47
|
+
|
|
48
|
+
float shape = .5 + .5 * getNoise(shape_uv, t);
|
|
49
|
+
|
|
50
|
+
float mixer = (shape - .5 / u_colorsCount) * u_colorsCount;
|
|
51
|
+
|
|
52
|
+
float steps = max(1., u_stepsPerColor);
|
|
53
|
+
|
|
54
|
+
vec4 gradient = u_colors[0];
|
|
55
|
+
gradient.rgb *= gradient.a;
|
|
56
|
+
for (int i = 1; i < ${simplexNoiseMeta.maxColorCount}; i++) {
|
|
57
|
+
if (i >= int(u_colorsCount)) break;
|
|
58
|
+
|
|
59
|
+
float localM = clamp(mixer - float(i - 1), 0., 1.);
|
|
60
|
+
localM = steppedSmooth(localM, steps, .5 * u_softness);
|
|
61
|
+
|
|
62
|
+
vec4 c = u_colors[i];
|
|
63
|
+
c.rgb *= c.a;
|
|
64
|
+
gradient = mix(gradient, c, localM);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {
|
|
68
|
+
float localM = mixer + 1.;
|
|
69
|
+
if (mixer > (u_colorsCount - 1.)) {
|
|
70
|
+
localM = mixer - (u_colorsCount - 1.);
|
|
71
|
+
}
|
|
72
|
+
localM = steppedSmooth(localM, steps, .5 * u_softness);
|
|
73
|
+
vec4 cFst = u_colors[0];
|
|
74
|
+
cFst.rgb *= cFst.a;
|
|
75
|
+
vec4 cLast = u_colors[int(u_colorsCount - 1.)];
|
|
76
|
+
cLast.rgb *= cLast.a;
|
|
77
|
+
gradient = mix(cLast, cFst, localM);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
vec3 color = gradient.rgb;
|
|
81
|
+
float opacity = gradient.a;
|
|
82
|
+
|
|
83
|
+
${colorBandingFix}
|
|
84
|
+
|
|
85
|
+
fragColor = vec4(color, opacity);
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
export {
|
|
89
|
+
simplexNoiseFragmentShader,
|
|
90
|
+
simplexNoiseMeta
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=simplex-noise.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/simplex-noise.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 { simplexNoise, colorBandingFix } from '../shader-utils.js';\r\n\r\nexport const simplexNoiseMeta = {\r\n maxColorCount: 10,\r\n} as const;\r\n\r\n/**\r\n * A multi-color gradient mapped into smooth, animated curves built as a combination of 2 Simplex noises.\r\n *\r\n * Fragment shader uniforms:\r\n * - u_time (float): Animation time\r\n * - u_colors (vec4[]): Up to 10 base colors in RGBA\r\n * - u_colorsCount (float): Number of active colors\r\n * - u_stepsPerColor (float): Number of extra colors between base colors, 1 = N colors, 2 = 2\u00D7N, etc., needs 2+ colors (1 to 10)\r\n * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient, needs 2+ colors (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 */\r\n\r\n// language=GLSL\r\nexport const simplexNoiseFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colors[${ simplexNoiseMeta.maxColorCount }];\r\nuniform float u_colorsCount;\r\nuniform float u_stepsPerColor;\r\nuniform float u_softness;\r\n\r\nin vec2 v_patternUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ simplexNoise }\r\n\r\nfloat getNoise(vec2 uv, float t) {\r\n float noise = .5 * snoise(uv - vec2(0., .3 * t));\r\n noise += .5 * snoise(2. * uv + vec2(0., .32 * t));\r\n\r\n return noise;\r\n}\r\n\r\nfloat steppedSmooth(float m, float steps, float softness) {\r\n float stepT = floor(m * steps) / steps;\r\n float f = m * steps - floor(m * steps);\r\n float fw = steps * fwidth(m);\r\n float smoothed = smoothstep(.5 - softness, min(1., .5 + softness + fw), f);\r\n return stepT + smoothed / steps;\r\n}\r\n\r\nvoid main() {\r\n vec2 shape_uv = v_patternUV;\r\n shape_uv *= .1;\r\n\r\n float t = .2 * u_time;\r\n\r\n float shape = .5 + .5 * getNoise(shape_uv, t);\r\n\r\n float mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\r\n\r\n float steps = max(1., u_stepsPerColor);\r\n\r\n vec4 gradient = u_colors[0];\r\n gradient.rgb *= gradient.a;\r\n for (int i = 1; i < ${ simplexNoiseMeta.maxColorCount }; i++) {\r\n if (i >= int(u_colorsCount)) break;\r\n\r\n float localM = clamp(mixer - float(i - 1), 0., 1.);\r\n localM = steppedSmooth(localM, steps, .5 * u_softness);\r\n\r\n vec4 c = u_colors[i];\r\n c.rgb *= c.a;\r\n gradient = mix(gradient, c, localM);\r\n }\r\n\r\n if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {\r\n float localM = mixer + 1.;\r\n if (mixer > (u_colorsCount - 1.)) {\r\n localM = mixer - (u_colorsCount - 1.);\r\n }\r\n localM = steppedSmooth(localM, steps, .5 * u_softness);\r\n vec4 cFst = u_colors[0];\r\n cFst.rgb *= cFst.a;\r\n vec4 cLast = u_colors[int(u_colorsCount - 1.)];\r\n cLast.rgb *= cLast.a;\r\n gradient = mix(cLast, cFst, localM);\r\n }\r\n\r\n vec3 color = gradient.rgb;\r\n float opacity = gradient.a;\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\nexport interface SimplexNoiseUniforms extends ShaderSizingUniforms {\r\n u_colors: vec4[];\r\n u_colorsCount: number;\r\n u_stepsPerColor: number;\r\n u_softness: number;\r\n}\r\n\r\nexport interface SimplexNoiseParams extends ShaderSizingParams, ShaderMotionParams {\r\n colors?: string[];\r\n stepsPerColor?: number;\r\n softness?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,eAAmE;AACnE,SAAS,cAAc,uBAAuB;AAEvC,MAAM,mBAAmB;AAAA,EAC9B,eAAe;AACjB;AA+BO,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKzB,iBAAiB,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrD,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA+BS,iBAAiB,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,IA2BnD,eAAgB;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
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 smokeRingMeta: {
|
|
5
|
+
readonly maxColorCount: 10;
|
|
6
|
+
readonly maxNoiseIterations: 8;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Radial multi-colored gradient shaped with layered noise for a natural, smoky aesthetic.
|
|
10
|
+
*
|
|
11
|
+
*
|
|
12
|
+
* Fragment shader uniforms:
|
|
13
|
+
* - u_time (float): Animation time
|
|
14
|
+
* - u_colorBack (vec4): Background color in RGBA
|
|
15
|
+
* - u_colors (vec4[]): Up to 10 gradient colors in RGBA
|
|
16
|
+
* - u_colorsCount (float): Number of active colors
|
|
17
|
+
* - u_thickness (float): Thickness of the ring shape (0.01 to 1)
|
|
18
|
+
* - u_radius (float): Radius of the ring shape (0 to 1)
|
|
19
|
+
* - u_innerShape (float): Ring inner fill amount, needs radius > 0 (0 to 4)
|
|
20
|
+
* - u_noiseIterations (float): Number of noise layers, more layers gives more details (1 to 8)
|
|
21
|
+
* - u_noiseScale (float): Noise frequency (0.01 to 5)
|
|
22
|
+
* - u_noiseTexture (sampler2D): Pre-computed randomizer source texture
|
|
23
|
+
*
|
|
24
|
+
* Vertex shader outputs (used in fragment shader):
|
|
25
|
+
* - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
|
|
26
|
+
*
|
|
27
|
+
* Vertex shader uniforms:
|
|
28
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
29
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
30
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
31
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
32
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
33
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
34
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
35
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
36
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
37
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
38
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
export declare const smokeRingFragmentShader: string;
|
|
42
|
+
export interface SmokeRingUniforms extends ShaderSizingUniforms {
|
|
43
|
+
u_colorBack: [number, number, number, number];
|
|
44
|
+
u_colors: vec4[];
|
|
45
|
+
u_colorsCount: number;
|
|
46
|
+
u_noiseScale: number;
|
|
47
|
+
u_thickness: number;
|
|
48
|
+
u_radius: number;
|
|
49
|
+
u_innerShape: number;
|
|
50
|
+
u_noiseIterations: number;
|
|
51
|
+
u_noiseTexture?: HTMLImageElement;
|
|
52
|
+
}
|
|
53
|
+
export interface SmokeRingParams extends ShaderSizingParams, ShaderMotionParams {
|
|
54
|
+
colorBack?: string;
|
|
55
|
+
colors?: string[];
|
|
56
|
+
noiseScale?: number;
|
|
57
|
+
thickness?: number;
|
|
58
|
+
radius?: number;
|
|
59
|
+
innerShape?: number;
|
|
60
|
+
noiseIterations?: number;
|
|
61
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
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 smokeRingMeta = {
|
|
9
|
+
maxColorCount: 10,
|
|
10
|
+
maxNoiseIterations: 8
|
|
11
|
+
};
|
|
12
|
+
const smokeRingFragmentShader = `#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[${smokeRingMeta.maxColorCount}];
|
|
21
|
+
uniform float u_colorsCount;
|
|
22
|
+
|
|
23
|
+
uniform float u_thickness;
|
|
24
|
+
uniform float u_radius;
|
|
25
|
+
uniform float u_innerShape;
|
|
26
|
+
uniform float u_noiseScale;
|
|
27
|
+
uniform float u_noiseIterations;
|
|
28
|
+
|
|
29
|
+
in vec2 v_objectUV;
|
|
30
|
+
|
|
31
|
+
out vec4 fragColor;
|
|
32
|
+
|
|
33
|
+
${declarePI}
|
|
34
|
+
${textureRandomizerR}
|
|
35
|
+
float valueNoise(vec2 st) {
|
|
36
|
+
vec2 i = floor(st);
|
|
37
|
+
vec2 f = fract(st);
|
|
38
|
+
float a = randomR(i);
|
|
39
|
+
float b = randomR(i + vec2(1.0, 0.0));
|
|
40
|
+
float c = randomR(i + vec2(0.0, 1.0));
|
|
41
|
+
float d = randomR(i + vec2(1.0, 1.0));
|
|
42
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
43
|
+
float x1 = mix(a, b, u.x);
|
|
44
|
+
float x2 = mix(c, d, u.x);
|
|
45
|
+
return mix(x1, x2, u.y);
|
|
46
|
+
}
|
|
47
|
+
vec2 fbm(vec2 n0, vec2 n1) {
|
|
48
|
+
vec2 total = vec2(0.0);
|
|
49
|
+
float amplitude = .4;
|
|
50
|
+
for (int i = 0; i < ${smokeRingMeta.maxNoiseIterations}; i++) {
|
|
51
|
+
if (i >= int(u_noiseIterations)) break;
|
|
52
|
+
total.x += valueNoise(n0) * amplitude;
|
|
53
|
+
total.y += valueNoise(n1) * amplitude;
|
|
54
|
+
n0 *= 1.99;
|
|
55
|
+
n1 *= 1.99;
|
|
56
|
+
amplitude *= 0.65;
|
|
57
|
+
}
|
|
58
|
+
return total;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
float getNoise(vec2 uv, vec2 pUv, float t) {
|
|
62
|
+
vec2 pUvLeft = pUv + .03 * t;
|
|
63
|
+
float period = max(abs(u_noiseScale * TWO_PI), 1e-6);
|
|
64
|
+
vec2 pUvRight = vec2(fract(pUv.x / period) * period, pUv.y) + .03 * t;
|
|
65
|
+
vec2 noise = fbm(pUvLeft, pUvRight);
|
|
66
|
+
return mix(noise.y, noise.x, smoothstep(-.25, .25, uv.x));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
float getRingShape(vec2 uv) {
|
|
70
|
+
float radius = u_radius;
|
|
71
|
+
float thickness = u_thickness;
|
|
72
|
+
|
|
73
|
+
float distance = length(uv);
|
|
74
|
+
float ringValue = 1. - smoothstep(radius, radius + thickness, distance);
|
|
75
|
+
ringValue *= smoothstep(radius - pow(u_innerShape, 3.) * thickness, radius, distance);
|
|
76
|
+
|
|
77
|
+
return ringValue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
void main() {
|
|
81
|
+
vec2 shape_uv = v_objectUV;
|
|
82
|
+
|
|
83
|
+
float t = u_time;
|
|
84
|
+
|
|
85
|
+
float cycleDuration = 3.;
|
|
86
|
+
float period2 = 2.0 * cycleDuration;
|
|
87
|
+
float localTime1 = fract((0.1 * t + cycleDuration) / period2) * period2;
|
|
88
|
+
float localTime2 = fract((0.1 * t) / period2) * period2;
|
|
89
|
+
float timeBlend = .5 + .5 * sin(.1 * t * PI / cycleDuration - .5 * PI);
|
|
90
|
+
|
|
91
|
+
float atg = atan(shape_uv.y, shape_uv.x) + .001;
|
|
92
|
+
float l = length(shape_uv);
|
|
93
|
+
float radialOffset = .5 * l - inversesqrt(max(1e-4, l));
|
|
94
|
+
vec2 polar_uv1 = vec2(atg, localTime1 - radialOffset) * u_noiseScale;
|
|
95
|
+
vec2 polar_uv2 = vec2(atg, localTime2 - radialOffset) * u_noiseScale;
|
|
96
|
+
|
|
97
|
+
float noise1 = getNoise(shape_uv, polar_uv1, t);
|
|
98
|
+
float noise2 = getNoise(shape_uv, polar_uv2, t);
|
|
99
|
+
|
|
100
|
+
float noise = mix(noise1, noise2, timeBlend);
|
|
101
|
+
|
|
102
|
+
shape_uv *= (.8 + 1.2 * noise);
|
|
103
|
+
|
|
104
|
+
float ringShape = getRingShape(shape_uv);
|
|
105
|
+
|
|
106
|
+
float mixer = ringShape * ringShape * (u_colorsCount - 1.);
|
|
107
|
+
int idxLast = int(u_colorsCount) - 1;
|
|
108
|
+
vec4 gradient = u_colors[idxLast];
|
|
109
|
+
gradient.rgb *= gradient.a;
|
|
110
|
+
for (int i = ${smokeRingMeta.maxColorCount} - 2; i >= 0; i--) {
|
|
111
|
+
float localT = clamp(mixer - float(idxLast - i - 1), 0., 1.);
|
|
112
|
+
vec4 c = u_colors[i];
|
|
113
|
+
c.rgb *= c.a;
|
|
114
|
+
gradient = mix(gradient, c, localT);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
vec3 color = gradient.rgb * ringShape;
|
|
118
|
+
float opacity = gradient.a * ringShape;
|
|
119
|
+
|
|
120
|
+
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
121
|
+
color = color + bgColor * (1. - opacity);
|
|
122
|
+
opacity = opacity + u_colorBack.a * (1. - opacity);
|
|
123
|
+
|
|
124
|
+
${colorBandingFix}
|
|
125
|
+
|
|
126
|
+
fragColor = vec4(color, opacity);
|
|
127
|
+
}
|
|
128
|
+
`;
|
|
129
|
+
export {
|
|
130
|
+
smokeRingFragmentShader,
|
|
131
|
+
smokeRingMeta
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=smoke-ring.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/smoke-ring.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 smokeRingMeta = {\r\n maxColorCount: 10,\r\n maxNoiseIterations: 8,\r\n} as const;\r\n\r\n/**\r\n * Radial multi-colored gradient shaped with layered noise for a natural, smoky aesthetic.\r\n *\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 10 gradient colors in RGBA\r\n * - u_colorsCount (float): Number of active colors\r\n * - u_thickness (float): Thickness of the ring shape (0.01 to 1)\r\n * - u_radius (float): Radius of the ring shape (0 to 1)\r\n * - u_innerShape (float): Ring inner fill amount, needs radius > 0 (0 to 4)\r\n * - u_noiseIterations (float): Number of noise layers, more layers gives more details (1 to 8)\r\n * - u_noiseScale (float): Noise frequency (0.01 to 5)\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 smokeRingFragmentShader: 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[${ smokeRingMeta.maxColorCount }];\r\nuniform float u_colorsCount;\r\n\r\nuniform float u_thickness;\r\nuniform float u_radius;\r\nuniform float u_innerShape;\r\nuniform float u_noiseScale;\r\nuniform float u_noiseIterations;\r\n\r\nin vec2 v_objectUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ declarePI }\r\n${ textureRandomizerR }\r\nfloat valueNoise(vec2 st) {\r\n vec2 i = floor(st);\r\n vec2 f = fract(st);\r\n float a = randomR(i);\r\n float b = randomR(i + vec2(1.0, 0.0));\r\n float c = randomR(i + vec2(0.0, 1.0));\r\n float d = randomR(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\nvec2 fbm(vec2 n0, vec2 n1) {\r\n vec2 total = vec2(0.0);\r\n float amplitude = .4;\r\n for (int i = 0; i < ${ smokeRingMeta.maxNoiseIterations }; i++) {\r\n if (i >= int(u_noiseIterations)) break;\r\n total.x += valueNoise(n0) * amplitude;\r\n total.y += valueNoise(n1) * amplitude;\r\n n0 *= 1.99;\r\n n1 *= 1.99;\r\n amplitude *= 0.65;\r\n }\r\n return total;\r\n}\r\n\r\nfloat getNoise(vec2 uv, vec2 pUv, float t) {\r\n vec2 pUvLeft = pUv + .03 * t;\r\n float period = max(abs(u_noiseScale * TWO_PI), 1e-6);\r\n vec2 pUvRight = vec2(fract(pUv.x / period) * period, pUv.y) + .03 * t;\r\n vec2 noise = fbm(pUvLeft, pUvRight);\r\n return mix(noise.y, noise.x, smoothstep(-.25, .25, uv.x));\r\n}\r\n\r\nfloat getRingShape(vec2 uv) {\r\n float radius = u_radius;\r\n float thickness = u_thickness;\r\n\r\n float distance = length(uv);\r\n float ringValue = 1. - smoothstep(radius, radius + thickness, distance);\r\n ringValue *= smoothstep(radius - pow(u_innerShape, 3.) * thickness, radius, distance);\r\n\r\n return ringValue;\r\n}\r\n\r\nvoid main() {\r\n vec2 shape_uv = v_objectUV;\r\n\r\n float t = u_time;\r\n\r\n float cycleDuration = 3.;\r\n float period2 = 2.0 * cycleDuration;\r\n float localTime1 = fract((0.1 * t + cycleDuration) / period2) * period2;\r\n float localTime2 = fract((0.1 * t) / period2) * period2;\r\n float timeBlend = .5 + .5 * sin(.1 * t * PI / cycleDuration - .5 * PI);\r\n\r\n float atg = atan(shape_uv.y, shape_uv.x) + .001;\r\n float l = length(shape_uv);\r\n float radialOffset = .5 * l - inversesqrt(max(1e-4, l));\r\n vec2 polar_uv1 = vec2(atg, localTime1 - radialOffset) * u_noiseScale;\r\n vec2 polar_uv2 = vec2(atg, localTime2 - radialOffset) * u_noiseScale;\r\n \r\n float noise1 = getNoise(shape_uv, polar_uv1, t);\r\n float noise2 = getNoise(shape_uv, polar_uv2, t);\r\n\r\n float noise = mix(noise1, noise2, timeBlend);\r\n\r\n shape_uv *= (.8 + 1.2 * noise);\r\n\r\n float ringShape = getRingShape(shape_uv);\r\n\r\n float mixer = ringShape * ringShape * (u_colorsCount - 1.);\r\n int idxLast = int(u_colorsCount) - 1;\r\n vec4 gradient = u_colors[idxLast];\r\n gradient.rgb *= gradient.a;\r\n for (int i = ${ smokeRingMeta.maxColorCount } - 2; i >= 0; i--) {\r\n float localT = clamp(mixer - float(idxLast - i - 1), 0., 1.);\r\n vec4 c = u_colors[i];\r\n c.rgb *= c.a;\r\n gradient = mix(gradient, c, localT);\r\n }\r\n\r\n vec3 color = gradient.rgb * ringShape;\r\n float opacity = gradient.a * ringShape;\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 SmokeRingUniforms extends ShaderSizingUniforms {\r\n u_colorBack: [number, number, number, number];\r\n u_colors: vec4[];\r\n u_colorsCount: number;\r\n u_noiseScale: number;\r\n u_thickness: number;\r\n u_radius: number;\r\n u_innerShape: number;\r\n u_noiseIterations: number;\r\n u_noiseTexture?: HTMLImageElement;\r\n}\r\n\r\nexport interface SmokeRingParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorBack?: string;\r\n colors?: string[];\r\n noiseScale?: number;\r\n thickness?: number;\r\n radius?: number;\r\n innerShape?: number;\r\n noiseIterations?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,eAAmE;AACnE,SAAS,WAAW,oBAAoB,uBAAuB;AAExD,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,oBAAoB;AACtB;AAqCO,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQtB,cAAc,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAalD,SAAU;AAAA,EACV,kBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAgBG,cAAc,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBA4DxC,cAAc,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAczC,eAAgB;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ShaderMotionParams } from '../shader-mount.js';
|
|
2
|
+
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
3
|
+
/**
|
|
4
|
+
* A single-colored animated spiral that morphs across a wide range of shapes -
|
|
5
|
+
* from crisp, thin-lined geometry to flowing whirlpool forms and wavy, abstract rings.
|
|
6
|
+
*
|
|
7
|
+
* Vertex shader uniforms:
|
|
8
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
9
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
10
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
11
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
12
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
13
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
14
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
15
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
16
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
17
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
18
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
19
|
+
*
|
|
20
|
+
* Vertex shader outputs (used in fragment shader):
|
|
21
|
+
* - v_patternUV (vec2): UV coordinates in pixels (scaled by 0.01 for precision), with rotation and offset applied
|
|
22
|
+
*
|
|
23
|
+
* Fragment shader uniforms:
|
|
24
|
+
* - u_time (float): Animation time
|
|
25
|
+
* - u_colorBack (vec4): Background color in RGBA
|
|
26
|
+
* - u_colorFront (vec4): Foreground (ink) color in RGBA
|
|
27
|
+
* - u_density (float): Spacing falloff simulating perspective, 0 = flat spiral (0 to 1)
|
|
28
|
+
* - u_distortion (float): Power of shape distortion applied along the spiral (0 to 1)
|
|
29
|
+
* - u_strokeWidth (float): Thickness of spiral curve (0 to 1)
|
|
30
|
+
* - u_strokeTaper (float): How much stroke loses width away from center, 0 = full visibility (0 to 1)
|
|
31
|
+
* - u_strokeCap (float): Extra stroke width at the center, needs strokeWidth ≠ 0.5 (0 to 1)
|
|
32
|
+
* - u_noise (float): Noise distortion applied over the canvas, needs noiseFrequency > 0 (0 to 1)
|
|
33
|
+
* - u_noiseFrequency (float): Noise frequency, needs noise > 0 (0 to 1)
|
|
34
|
+
* - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export declare const spiralFragmentShader: string;
|
|
38
|
+
export interface SpiralUniforms extends ShaderSizingUniforms {
|
|
39
|
+
u_colorBack: [number, number, number, number];
|
|
40
|
+
u_colorFront: [number, number, number, number];
|
|
41
|
+
u_density: number;
|
|
42
|
+
u_distortion: number;
|
|
43
|
+
u_strokeWidth: number;
|
|
44
|
+
u_strokeTaper: number;
|
|
45
|
+
u_strokeCap: number;
|
|
46
|
+
u_noise: number;
|
|
47
|
+
u_noiseFrequency: number;
|
|
48
|
+
u_softness: number;
|
|
49
|
+
}
|
|
50
|
+
export interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {
|
|
51
|
+
colorBack?: string;
|
|
52
|
+
colorFront?: string;
|
|
53
|
+
density?: number;
|
|
54
|
+
distortion?: number;
|
|
55
|
+
strokeWidth?: number;
|
|
56
|
+
strokeTaper?: number;
|
|
57
|
+
strokeCap?: number;
|
|
58
|
+
noise?: number;
|
|
59
|
+
noiseFrequency?: number;
|
|
60
|
+
softness?: number;
|
|
61
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import {} from "../shader-sizing.js";
|
|
7
|
+
import { simplexNoise, declarePI, colorBandingFix } from "../shader-utils.js";
|
|
8
|
+
const spiralFragmentShader = `#version 300 es
|
|
9
|
+
precision mediump float;
|
|
10
|
+
|
|
11
|
+
uniform float u_time;
|
|
12
|
+
|
|
13
|
+
uniform vec4 u_colorBack;
|
|
14
|
+
uniform vec4 u_colorFront;
|
|
15
|
+
uniform float u_density;
|
|
16
|
+
uniform float u_distortion;
|
|
17
|
+
uniform float u_strokeWidth;
|
|
18
|
+
uniform float u_strokeCap;
|
|
19
|
+
uniform float u_strokeTaper;
|
|
20
|
+
uniform float u_noise;
|
|
21
|
+
uniform float u_noiseFrequency;
|
|
22
|
+
uniform float u_softness;
|
|
23
|
+
|
|
24
|
+
in vec2 v_patternUV;
|
|
25
|
+
|
|
26
|
+
out vec4 fragColor;
|
|
27
|
+
|
|
28
|
+
${declarePI}
|
|
29
|
+
${simplexNoise}
|
|
30
|
+
|
|
31
|
+
void main() {
|
|
32
|
+
vec2 uv = 2. * v_patternUV;
|
|
33
|
+
|
|
34
|
+
float t = u_time;
|
|
35
|
+
float l = length(uv);
|
|
36
|
+
float density = clamp(u_density, 0., 1.);
|
|
37
|
+
l = pow(max(l, 1e-6), density);
|
|
38
|
+
float angle = atan(uv.y, uv.x) - t;
|
|
39
|
+
float angleNormalised = angle / TWO_PI;
|
|
40
|
+
|
|
41
|
+
if (u_noise > 0.) {
|
|
42
|
+
angleNormalised += .125 * u_noise * snoise(16. * pow(u_noiseFrequency, 3.) * uv);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
float offset = l + angleNormalised;
|
|
46
|
+
offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));
|
|
47
|
+
float stripe = fract(offset);
|
|
48
|
+
|
|
49
|
+
float shape = 2. * abs(stripe - .5);
|
|
50
|
+
float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.)));
|
|
54
|
+
width = mix(width, wCap, u_strokeCap);
|
|
55
|
+
width *= (1. - clamp(u_strokeTaper, 0., 1.) * l);
|
|
56
|
+
|
|
57
|
+
float fw = fwidth(offset);
|
|
58
|
+
float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth)));
|
|
59
|
+
float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.));
|
|
60
|
+
pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.)));
|
|
61
|
+
|
|
62
|
+
float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape);
|
|
63
|
+
|
|
64
|
+
vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
|
|
65
|
+
float fgOpacity = u_colorFront.a;
|
|
66
|
+
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
67
|
+
float bgOpacity = u_colorBack.a;
|
|
68
|
+
|
|
69
|
+
vec3 color = fgColor * res;
|
|
70
|
+
float opacity = fgOpacity * res;
|
|
71
|
+
|
|
72
|
+
color += bgColor * (1. - opacity);
|
|
73
|
+
opacity += bgOpacity * (1. - opacity);
|
|
74
|
+
|
|
75
|
+
${colorBandingFix}
|
|
76
|
+
|
|
77
|
+
fragColor = vec4(color, opacity);
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
export {
|
|
81
|
+
spiralFragmentShader
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=spiral.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/spiral.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\r\nimport { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\r\nimport { simplexNoise, declarePI, colorBandingFix } from '../shader-utils.js';\r\n\r\n/**\r\n * A single-colored animated spiral that morphs across a wide range of shapes -\r\n * from crisp, thin-lined geometry to flowing whirlpool forms and wavy, abstract rings.\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 * Vertex shader outputs (used in fragment shader):\r\n * - v_patternUV (vec2): UV coordinates in pixels (scaled by 0.01 for precision), with rotation and offset applied\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_colorFront (vec4): Foreground (ink) color in RGBA\r\n * - u_density (float): Spacing falloff simulating perspective, 0 = flat spiral (0 to 1)\r\n * - u_distortion (float): Power of shape distortion applied along the spiral (0 to 1)\r\n * - u_strokeWidth (float): Thickness of spiral curve (0 to 1)\r\n * - u_strokeTaper (float): How much stroke loses width away from center, 0 = full visibility (0 to 1)\r\n * - u_strokeCap (float): Extra stroke width at the center, needs strokeWidth \u2260 0.5 (0 to 1)\r\n * - u_noise (float): Noise distortion applied over the canvas, needs noiseFrequency > 0 (0 to 1)\r\n * - u_noiseFrequency (float): Noise frequency, needs noise > 0 (0 to 1)\r\n * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1)\r\n *\r\n */\r\n\r\n// language=GLSL\r\nexport const spiralFragmentShader: string = `#version 300 es\r\nprecision mediump float;\r\n\r\nuniform float u_time;\r\n\r\nuniform vec4 u_colorBack;\r\nuniform vec4 u_colorFront;\r\nuniform float u_density;\r\nuniform float u_distortion;\r\nuniform float u_strokeWidth;\r\nuniform float u_strokeCap;\r\nuniform float u_strokeTaper;\r\nuniform float u_noise;\r\nuniform float u_noiseFrequency;\r\nuniform float u_softness;\r\n\r\nin vec2 v_patternUV;\r\n\r\nout vec4 fragColor;\r\n\r\n${ declarePI }\r\n${ simplexNoise }\r\n\r\nvoid main() {\r\n vec2 uv = 2. * v_patternUV;\r\n\r\n float t = u_time;\r\n float l = length(uv);\r\n float density = clamp(u_density, 0., 1.);\r\n l = pow(max(l, 1e-6), density);\r\n float angle = atan(uv.y, uv.x) - t;\r\n float angleNormalised = angle / TWO_PI;\r\n\r\n if (u_noise > 0.) {\r\n angleNormalised += .125 * u_noise * snoise(16. * pow(u_noiseFrequency, 3.) * uv);\r\n }\r\n\r\n float offset = l + angleNormalised;\r\n offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));\r\n float stripe = fract(offset);\r\n\r\n float shape = 2. * abs(stripe - .5);\r\n float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);\r\n\r\n\r\n float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.)));\r\n width = mix(width, wCap, u_strokeCap);\r\n width *= (1. - clamp(u_strokeTaper, 0., 1.) * l);\r\n\r\n float fw = fwidth(offset);\r\n float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth)));\r\n float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.));\r\n pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.)));\r\n\r\n float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape);\r\n\r\n vec3 fgColor = u_colorFront.rgb * u_colorFront.a;\r\n float fgOpacity = u_colorFront.a;\r\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\r\n float bgOpacity = u_colorBack.a;\r\n\r\n vec3 color = fgColor * res;\r\n float opacity = fgOpacity * res;\r\n\r\n color += bgColor * (1. - opacity);\r\n opacity += bgOpacity * (1. - opacity);\r\n\r\n ${ colorBandingFix }\r\n\r\n fragColor = vec4(color, opacity);\r\n}\r\n`;\r\n\r\nexport interface SpiralUniforms extends ShaderSizingUniforms {\r\n u_colorBack: [number, number, number, number];\r\n u_colorFront: [number, number, number, number];\r\n u_density: number;\r\n u_distortion: number;\r\n u_strokeWidth: number;\r\n u_strokeTaper: number;\r\n u_strokeCap: number;\r\n u_noise: number;\r\n u_noiseFrequency: number;\r\n u_softness: number;\r\n}\r\n\r\nexport interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {\r\n colorBack?: string;\r\n colorFront?: string;\r\n density?: number;\r\n distortion?: number;\r\n strokeWidth?: number;\r\n strokeTaper?: number;\r\n strokeCap?: number;\r\n noise?: number;\r\n noiseFrequency?: number;\r\n softness?: number;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,eAAmE;AACnE,SAAS,cAAc,WAAW,uBAAuB;AAsClD,MAAM,uBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBzC,SAAU;AAAA,EACV,YAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8CX,eAAgB;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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 staticMeshGradientMeta: {
|
|
5
|
+
readonly maxColorCount: 10;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Multi-point mesh gradient with up to 10 color spots, enhanced by two-direction warping,
|
|
9
|
+
* adjustable blend sharpness, and grain controls.
|
|
10
|
+
*
|
|
11
|
+
* Fragment shader uniforms:
|
|
12
|
+
* - u_colors (vec4[]): Up to 10 gradient colors in RGBA
|
|
13
|
+
* - u_colorsCount (float): Number of active colors
|
|
14
|
+
* - u_positions (float): Color spots placement seed (0 to 100)
|
|
15
|
+
* - u_waveX (float): Strength of sine wave distortion along X axis (0 to 1)
|
|
16
|
+
* - u_waveXShift (float): Phase offset applied to the X-axis wave, needs waveX > 0 (0 to 1)
|
|
17
|
+
* - u_waveY (float): Strength of sine wave distortion along Y axis (0 to 1)
|
|
18
|
+
* - u_waveYShift (float): Phase offset applied to the Y-axis wave, needs waveY > 0 (0 to 1)
|
|
19
|
+
* - u_mixing (float): Blending behavior, 0 = hard stripes, 0.5 = smooth, 1 = gradual blend (0 to 1)
|
|
20
|
+
* - u_grainMixer (float): Strength of grain distortion applied to shape edges (0 to 1)
|
|
21
|
+
* - u_grainOverlay (float): Post-processing black/white grain overlay (0 to 1)
|
|
22
|
+
*
|
|
23
|
+
* Vertex shader outputs (used in fragment shader):
|
|
24
|
+
* - v_objectUV (vec2): Object box UV coordinates with global sizing (scale, rotation, offsets, etc) applied
|
|
25
|
+
*
|
|
26
|
+
* Vertex shader uniforms:
|
|
27
|
+
* - u_resolution (vec2): Canvas resolution in pixels
|
|
28
|
+
* - u_pixelRatio (float): Device pixel ratio
|
|
29
|
+
* - u_originX (float): Reference point for positioning world width in the canvas (0 to 1)
|
|
30
|
+
* - u_originY (float): Reference point for positioning world height in the canvas (0 to 1)
|
|
31
|
+
* - u_worldWidth (float): Virtual width of the graphic before it's scaled to fit the canvas
|
|
32
|
+
* - u_worldHeight (float): Virtual height of the graphic before it's scaled to fit the canvas
|
|
33
|
+
* - u_fit (float): How to fit the rendered shader into the canvas dimensions (0 = none, 1 = contain, 2 = cover)
|
|
34
|
+
* - u_scale (float): Overall zoom level of the graphics (0.01 to 4)
|
|
35
|
+
* - u_rotation (float): Overall rotation angle of the graphics in degrees (0 to 360)
|
|
36
|
+
* - u_offsetX (float): Horizontal offset of the graphics center (-1 to 1)
|
|
37
|
+
* - u_offsetY (float): Vertical offset of the graphics center (-1 to 1)
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
export declare const staticMeshGradientFragmentShader: string;
|
|
41
|
+
export interface StaticMeshGradientUniforms extends ShaderSizingUniforms {
|
|
42
|
+
u_colors: vec4[];
|
|
43
|
+
u_colorsCount: number;
|
|
44
|
+
u_positions: number;
|
|
45
|
+
u_waveX: number;
|
|
46
|
+
u_waveXShift: number;
|
|
47
|
+
u_waveY: number;
|
|
48
|
+
u_waveYShift: number;
|
|
49
|
+
u_mixing: number;
|
|
50
|
+
u_grainMixer: number;
|
|
51
|
+
u_grainOverlay: number;
|
|
52
|
+
}
|
|
53
|
+
export interface StaticMeshGradientParams extends ShaderSizingParams, ShaderMotionParams {
|
|
54
|
+
colors?: string[];
|
|
55
|
+
positions?: number;
|
|
56
|
+
waveX?: number;
|
|
57
|
+
waveXShift?: number;
|
|
58
|
+
waveY?: number;
|
|
59
|
+
waveYShift?: number;
|
|
60
|
+
mixing?: number;
|
|
61
|
+
grainMixer?: number;
|
|
62
|
+
grainOverlay?: number;
|
|
63
|
+
}
|