@paper-design/shaders 0.0.45 → 0.0.47
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/README.md +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +2 -2
- package/dist/shader-mount.d.ts +1 -0
- package/dist/shader-mount.js +12 -12
- package/dist/shader-mount.js.map +2 -2
- package/dist/shader-sizing.d.ts +2 -2
- package/dist/shader-sizing.js +43 -6
- package/dist/shader-sizing.js.map +2 -2
- package/dist/shader-utils.d.ts +8 -5
- package/dist/shader-utils.js +70 -51
- package/dist/shader-utils.js.map +2 -2
- package/dist/shaders/color-panels.js +5 -5
- package/dist/shaders/color-panels.js.map +1 -1
- package/dist/shaders/dithering.d.ts +1 -1
- package/dist/shaders/dithering.js +13 -11
- package/dist/shaders/dithering.js.map +2 -2
- package/dist/shaders/dot-grid.js +2 -2
- package/dist/shaders/dot-grid.js.map +2 -2
- package/dist/shaders/dot-orbit.d.ts +3 -0
- package/dist/shaders/dot-orbit.js +9 -9
- package/dist/shaders/dot-orbit.js.map +2 -2
- package/dist/shaders/fluted-glass.d.ts +72 -0
- package/dist/shaders/fluted-glass.js +188 -0
- package/dist/shaders/fluted-glass.js.map +7 -0
- package/dist/shaders/god-rays.d.ts +2 -0
- package/dist/shaders/god-rays.js +20 -9
- package/dist/shaders/god-rays.js.map +2 -2
- package/dist/shaders/grain-gradient.js +60 -37
- package/dist/shaders/grain-gradient.js.map +2 -2
- package/dist/shaders/image-dithering.d.ts +49 -0
- package/dist/shaders/image-dithering.js +164 -0
- package/dist/shaders/image-dithering.js.map +7 -0
- package/dist/shaders/liquid-metal.js +4 -4
- package/dist/shaders/liquid-metal.js.map +2 -2
- package/dist/shaders/mesh-gradient.js +2 -2
- package/dist/shaders/mesh-gradient.js.map +2 -2
- package/dist/shaders/metaballs.d.ts +3 -0
- package/dist/shaders/metaballs.js +8 -7
- package/dist/shaders/metaballs.js.map +2 -2
- package/dist/shaders/neuro-noise.d.ts +1 -1
- package/dist/shaders/neuro-noise.js +2 -2
- package/dist/shaders/neuro-noise.js.map +2 -2
- package/dist/shaders/paper-texture.d.ts +53 -0
- package/dist/shaders/paper-texture.js +238 -0
- package/dist/shaders/paper-texture.js.map +7 -0
- package/dist/shaders/perlin-noise.js +111 -117
- package/dist/shaders/perlin-noise.js.map +2 -2
- package/dist/shaders/pulsing-border.js +20 -10
- package/dist/shaders/pulsing-border.js.map +2 -2
- package/dist/shaders/simplex-noise.js +6 -5
- package/dist/shaders/simplex-noise.js.map +2 -2
- package/dist/shaders/smoke-ring.js +20 -16
- package/dist/shaders/smoke-ring.js.map +2 -2
- package/dist/shaders/spiral.js +3 -3
- package/dist/shaders/spiral.js.map +2 -2
- package/dist/shaders/static-mesh-gradient.d.ts +2 -0
- package/dist/shaders/static-mesh-gradient.js +15 -14
- package/dist/shaders/static-mesh-gradient.js.map +2 -2
- package/dist/shaders/static-radial-gradient.d.ts +2 -0
- package/dist/shaders/static-radial-gradient.js +15 -13
- package/dist/shaders/static-radial-gradient.js.map +2 -2
- package/dist/shaders/swirl.js +3 -3
- package/dist/shaders/swirl.js.map +2 -2
- package/dist/shaders/voronoi.js +6 -10
- package/dist/shaders/voronoi.js.map +2 -2
- package/dist/shaders/warp.d.ts +3 -0
- package/dist/shaders/warp.js +20 -4
- package/dist/shaders/warp.js.map +2 -2
- package/dist/shaders/water.d.ts +39 -0
- package/dist/shaders/water.js +119 -0
- package/dist/shaders/water.js.map +7 -0
- package/dist/vertex-shader.d.ts +1 -1
- package/dist/vertex-shader.js +59 -22
- package/dist/vertex-shader.js.map +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
2
|
+
* Paper Shaders *
|
|
3
|
+
* https://github.com/paper-design/shaders *
|
|
4
|
+
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
|
+
|
|
6
|
+
import { sizingUV } from "../shader-sizing.js";
|
|
7
|
+
import { proceduralHash21 } from "../shader-utils.js";
|
|
8
|
+
const imageDitheringFragmentShader = `#version 300 es
|
|
9
|
+
precision lowp float;
|
|
10
|
+
|
|
11
|
+
uniform float u_time;
|
|
12
|
+
uniform mediump vec2 u_resolution;
|
|
13
|
+
uniform mediump float u_pixelRatio;
|
|
14
|
+
uniform mediump float u_originX;
|
|
15
|
+
uniform mediump float u_originY;
|
|
16
|
+
uniform mediump float u_worldWidth;
|
|
17
|
+
uniform mediump float u_worldHeight;
|
|
18
|
+
uniform mediump float u_fit;
|
|
19
|
+
|
|
20
|
+
uniform mediump float u_scale;
|
|
21
|
+
uniform mediump float u_rotation;
|
|
22
|
+
uniform mediump float u_offsetX;
|
|
23
|
+
uniform mediump float u_offsetY;
|
|
24
|
+
|
|
25
|
+
uniform vec4 u_colorFront;
|
|
26
|
+
uniform vec4 u_colorBack;
|
|
27
|
+
uniform vec4 u_colorHighlight;
|
|
28
|
+
|
|
29
|
+
uniform sampler2D u_image;
|
|
30
|
+
uniform mediump float u_imageAspectRatio;
|
|
31
|
+
|
|
32
|
+
uniform float u_type;
|
|
33
|
+
uniform float u_pxSize;
|
|
34
|
+
uniform bool u_originalColors;
|
|
35
|
+
uniform float u_colorSteps;
|
|
36
|
+
|
|
37
|
+
out vec4 fragColor;
|
|
38
|
+
|
|
39
|
+
float getUvFrame(vec2 uv, vec2 px) {
|
|
40
|
+
float left = step(-px.x, uv.x);
|
|
41
|
+
float right = step(uv.x, 1.);
|
|
42
|
+
float bottom = step(-px.y, uv.y);
|
|
43
|
+
float top = step(uv.y, 1. + px.y);
|
|
44
|
+
|
|
45
|
+
return left * right * bottom * top;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
${proceduralHash21}
|
|
49
|
+
|
|
50
|
+
const int bayer2x2[4] = int[4](0, 2, 3, 1);
|
|
51
|
+
const int bayer4x4[16] = int[16](
|
|
52
|
+
0, 8, 2, 10,
|
|
53
|
+
12, 4, 14, 6,
|
|
54
|
+
3, 11, 1, 9,
|
|
55
|
+
15, 7, 13, 5
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const int bayer8x8[64] = int[64](
|
|
59
|
+
0, 32, 8, 40, 2, 34, 10, 42,
|
|
60
|
+
48, 16, 56, 24, 50, 18, 58, 26,
|
|
61
|
+
12, 44, 4, 36, 14, 46, 6, 38,
|
|
62
|
+
60, 28, 52, 20, 62, 30, 54, 22,
|
|
63
|
+
3, 35, 11, 43, 1, 33, 9, 41,
|
|
64
|
+
51, 19, 59, 27, 49, 17, 57, 25,
|
|
65
|
+
15, 47, 7, 39, 13, 45, 5, 37,
|
|
66
|
+
63, 31, 55, 23, 61, 29, 53, 21
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
float getBayerValue(vec2 uv, int size) {
|
|
70
|
+
ivec2 pos = ivec2(mod(uv, float(size)));
|
|
71
|
+
int index = pos.y * size + pos.x;
|
|
72
|
+
|
|
73
|
+
if (size == 2) {
|
|
74
|
+
return float(bayer2x2[index]) / 4.0;
|
|
75
|
+
} else if (size == 4) {
|
|
76
|
+
return float(bayer4x4[index]) / 16.0;
|
|
77
|
+
} else if (size == 8) {
|
|
78
|
+
return float(bayer8x8[index]) / 64.0;
|
|
79
|
+
}
|
|
80
|
+
return 0.0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
void main() {
|
|
85
|
+
|
|
86
|
+
#define USE_IMAGE_SIZING
|
|
87
|
+
#define USE_PIXELIZATION
|
|
88
|
+
${sizingUV}
|
|
89
|
+
|
|
90
|
+
vec2 dithering_uv = pxSizeUv;
|
|
91
|
+
vec2 ditheringNoise_uv = u_resolution * uv;
|
|
92
|
+
vec4 image = texture(u_image, imageUV);
|
|
93
|
+
float frame = getUvFrame(imageUV, pxSize / u_resolution.xy);
|
|
94
|
+
|
|
95
|
+
int type = int(floor(u_type));
|
|
96
|
+
float dithering = 0.0;
|
|
97
|
+
|
|
98
|
+
float lum = dot(vec3(.2126, .7152, .0722), image.rgb);
|
|
99
|
+
|
|
100
|
+
switch (type) {
|
|
101
|
+
case 1: {
|
|
102
|
+
dithering = step(hash21(ditheringNoise_uv), lum);
|
|
103
|
+
} break;
|
|
104
|
+
case 2:
|
|
105
|
+
dithering = getBayerValue(dithering_uv, 2);
|
|
106
|
+
break;
|
|
107
|
+
case 3:
|
|
108
|
+
dithering = getBayerValue(dithering_uv, 4);
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
dithering = getBayerValue(dithering_uv, 8);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
float steps = max(floor(u_colorSteps), 1.);
|
|
117
|
+
float ditherAmount = 1.0 / (steps);
|
|
118
|
+
|
|
119
|
+
vec3 color = vec3(0.0);
|
|
120
|
+
float opacity = 1.;
|
|
121
|
+
|
|
122
|
+
dithering -= .5;
|
|
123
|
+
float brightness = clamp(lum + dithering * ditherAmount, 0.0, 1.0);
|
|
124
|
+
brightness = mix(0.0, brightness, frame);
|
|
125
|
+
float quantLum = floor(brightness * steps + 0.5) / steps;
|
|
126
|
+
|
|
127
|
+
if (u_originalColors == true) {
|
|
128
|
+
vec3 normColor = image.rgb / max(lum, 0.001);
|
|
129
|
+
color = normColor * quantLum;
|
|
130
|
+
|
|
131
|
+
float quantAlpha = floor(image.a * steps + 0.5) / steps;
|
|
132
|
+
opacity = mix(quantLum, 1., quantAlpha);
|
|
133
|
+
} else {
|
|
134
|
+
vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
|
|
135
|
+
float fgOpacity = u_colorFront.a;
|
|
136
|
+
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
137
|
+
float bgOpacity = u_colorBack.a;
|
|
138
|
+
vec3 hlColor = u_colorHighlight.rgb * u_colorHighlight.a;
|
|
139
|
+
float hlOpacity = u_colorHighlight.a;
|
|
140
|
+
|
|
141
|
+
fgColor = mix(fgColor, hlColor, step(1.02 - .02 * u_colorSteps, brightness));
|
|
142
|
+
fgOpacity = mix(fgOpacity, hlOpacity, step(1.02 - .02 * u_colorSteps, brightness));
|
|
143
|
+
|
|
144
|
+
color = fgColor * quantLum;
|
|
145
|
+
opacity = fgOpacity * quantLum;
|
|
146
|
+
color += bgColor * (1.0 - opacity);
|
|
147
|
+
opacity += bgOpacity * (1.0 - opacity);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
fragColor = vec4(color, opacity);
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
const DitheringTypes = {
|
|
155
|
+
"random": 1,
|
|
156
|
+
"2x2": 2,
|
|
157
|
+
"4x4": 3,
|
|
158
|
+
"8x8": 4
|
|
159
|
+
};
|
|
160
|
+
export {
|
|
161
|
+
DitheringTypes,
|
|
162
|
+
imageDitheringFragmentShader
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=image-dithering.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shaders/image-dithering.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingUV, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { proceduralHash21 } from '../shader-utils.js';\n\n/**\n * Dithering effect over user texture using 3-color palette\n * or colors sampled from original image\n *\n * Uniforms:\n * - u_colorBack, u_colorFront, u_colorHighlight (RGBA)\n * (u_colorHighlight to be the lightest parts of u_colorFront pixels)\n * - pxSize: px size set relative to canvas resolution\n * - u_type (float used as integer)\n * ---- 1: random dithering\n * ---- 2: 2x2 Bayer matrix\n * ---- 3: 4x4 Bayer matrix\n * ---- 4: 8x8 Bayer matrix\n * - u_originalColors - switching between 3 colors palette and original image colors\n * - u_colorSteps - number of colors to use (applies to both color modes)\n *\n * Note: pixelization is applied to the shapes BEFORE dithering,\n * meaning pixels don't react to scaling and fit\n */\n\n// language=GLSL\nexport const imageDitheringFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform float u_time;\nuniform mediump vec2 u_resolution;\nuniform mediump float u_pixelRatio;\nuniform mediump float u_originX;\nuniform mediump float u_originY;\nuniform mediump float u_worldWidth;\nuniform mediump float u_worldHeight;\nuniform mediump float u_fit;\n\nuniform mediump float u_scale;\nuniform mediump float u_rotation;\nuniform mediump float u_offsetX;\nuniform mediump float u_offsetY;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorBack;\nuniform vec4 u_colorHighlight;\n\nuniform sampler2D u_image;\nuniform mediump float u_imageAspectRatio;\n\nuniform float u_type;\nuniform float u_pxSize;\nuniform bool u_originalColors;\nuniform float u_colorSteps;\n\nout vec4 fragColor;\n\nfloat getUvFrame(vec2 uv, vec2 px) {\n float left = step(-px.x, uv.x);\n float right = step(uv.x, 1.);\n float bottom = step(-px.y, uv.y);\n float top = step(uv.y, 1. + px.y);\n\n return left * right * bottom * top;\n}\n\n${proceduralHash21}\n\nconst int bayer2x2[4] = int[4](0, 2, 3, 1);\nconst int bayer4x4[16] = int[16](\n 0, 8, 2, 10,\n 12, 4, 14, 6,\n 3, 11, 1, 9,\n 15, 7, 13, 5\n);\n\nconst int bayer8x8[64] = int[64](\n 0, 32, 8, 40, 2, 34, 10, 42,\n 48, 16, 56, 24, 50, 18, 58, 26,\n 12, 44, 4, 36, 14, 46, 6, 38,\n 60, 28, 52, 20, 62, 30, 54, 22,\n 3, 35, 11, 43, 1, 33, 9, 41,\n 51, 19, 59, 27, 49, 17, 57, 25,\n 15, 47, 7, 39, 13, 45, 5, 37,\n 63, 31, 55, 23, 61, 29, 53, 21\n);\n\nfloat getBayerValue(vec2 uv, int size) {\n ivec2 pos = ivec2(mod(uv, float(size)));\n int index = pos.y * size + pos.x;\n\n if (size == 2) {\n return float(bayer2x2[index]) / 4.0;\n } else if (size == 4) {\n return float(bayer4x4[index]) / 16.0;\n } else if (size == 8) {\n return float(bayer8x8[index]) / 64.0;\n }\n return 0.0;\n}\n\n\nvoid main() {\n\n #define USE_IMAGE_SIZING\n #define USE_PIXELIZATION\n ${sizingUV}\n\n vec2 dithering_uv = pxSizeUv;\n vec2 ditheringNoise_uv = u_resolution * uv;\n vec4 image = texture(u_image, imageUV);\n float frame = getUvFrame(imageUV, pxSize / u_resolution.xy);\n\n int type = int(floor(u_type));\n float dithering = 0.0;\n\n float lum = dot(vec3(.2126, .7152, .0722), image.rgb);\n\n switch (type) {\n case 1: {\n dithering = step(hash21(ditheringNoise_uv), lum);\n } break;\n case 2:\n dithering = getBayerValue(dithering_uv, 2);\n break;\n case 3:\n dithering = getBayerValue(dithering_uv, 4);\n break;\n default:\n dithering = getBayerValue(dithering_uv, 8);\n break;\n }\n\n\n float steps = max(floor(u_colorSteps), 1.);\n float ditherAmount = 1.0 / (steps);\n \n vec3 color = vec3(0.0);\n float opacity = 1.;\n\n dithering -= .5;\n float brightness = clamp(lum + dithering * ditherAmount, 0.0, 1.0);\n brightness = mix(0.0, brightness, frame);\n float quantLum = floor(brightness * steps + 0.5) / steps;\n\n if (u_originalColors == true) {\n vec3 normColor = image.rgb / max(lum, 0.001);\n color = normColor * quantLum;\n\n float quantAlpha = floor(image.a * steps + 0.5) / steps;\n opacity = mix(quantLum, 1., quantAlpha);\n } else {\n vec3 fgColor = u_colorFront.rgb * u_colorFront.a;\n float fgOpacity = u_colorFront.a;\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n float bgOpacity = u_colorBack.a;\n vec3 hlColor = u_colorHighlight.rgb * u_colorHighlight.a;\n float hlOpacity = u_colorHighlight.a;\n\n fgColor = mix(fgColor, hlColor, step(1.02 - .02 * u_colorSteps, brightness));\n fgOpacity = mix(fgOpacity, hlOpacity, step(1.02 - .02 * u_colorSteps, brightness));\n\n color = fgColor * quantLum;\n opacity = fgOpacity * quantLum;\n color += bgColor * (1.0 - opacity);\n opacity += bgOpacity * (1.0 - opacity);\n }\n\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface ImageDitheringUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_colorFront: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_colorHighlight: [number, number, number, number];\n u_type: (typeof DitheringTypes)[DitheringType];\n u_pxSize: number;\n u_colorSteps: number;\n u_originalColors: boolean;\n}\n\nexport interface ImageDitheringParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string | undefined;\n colorFront?: string;\n colorBack?: string;\n colorHighlight?: string;\n type?: DitheringType;\n pxSize?: number;\n colorSteps?: number;\n originalColors?: boolean;\n}\n\nexport const DitheringTypes = {\n 'random': 1,\n '2x2': 2,\n '4x4': 3,\n '8x8': 4,\n} as const;\n\nexport type DitheringType = keyof typeof DitheringTypes;\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,SAAS,gBAAoE;AAC7E,SAAS,wBAAwB;AAuB1B,MAAM,+BAAuC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwClD,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,IAwCd,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyFL,MAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
5
|
|
|
6
6
|
import { sizingVariablesDeclaration } from "../shader-sizing.js";
|
|
7
|
-
import { declarePI,
|
|
7
|
+
import { declarePI, rotation2, simplexNoise, colorBandingFix } from "../shader-utils.js";
|
|
8
8
|
const liquidMetalFragmentShader = `#version 300 es
|
|
9
9
|
precision mediump float;
|
|
10
10
|
|
|
@@ -26,8 +26,8 @@ ${sizingVariablesDeclaration}
|
|
|
26
26
|
out vec4 fragColor;
|
|
27
27
|
|
|
28
28
|
${declarePI}
|
|
29
|
-
${
|
|
30
|
-
${
|
|
29
|
+
${rotation2}
|
|
30
|
+
${simplexNoise}
|
|
31
31
|
|
|
32
32
|
float getColorChanges(float c1, float c2, float stripe_p, vec3 w, float blur, float bump, float tint) {
|
|
33
33
|
|
|
@@ -127,7 +127,7 @@ void main() {
|
|
|
127
127
|
mask = pow(mask, 4.);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
float opacity = 1. - smoothstep(.
|
|
130
|
+
float opacity = 1. - smoothstep(.82 - 2. * fwidth(mask), .82, mask);
|
|
131
131
|
|
|
132
132
|
float ridge = .15 * (smoothstep(.0, .15, uv.y) * smoothstep(.4, .15, uv.y));
|
|
133
133
|
ridge += .05 * (smoothstep(.1, .2, 1. - uv.y) * smoothstep(.4, .2, 1. - uv.y));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/liquid-metal.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI,
|
|
5
|
-
"mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, simplexNoise, colorBandingFix } from '../shader-utils.js';\n\n/**\n *\n * Fluid motion imitation applied over abstract shapes\n * (animated stripe pattern getting distorted with shape edges)\n *\n * Uniforms:\n * - u_colorBack, u_colorTint (RGBA)\n * - u_repetition: density of pattern stripes\n * - u_softness: blur between stripes\n * - u_shiftRed & u_shiftBlue: color dispersion between the stripes\n * - u_distortion: pattern distortion on the whole canvas\n * - u_contour: distortion power over the shape edges\n * - u_shape (float used as integer):\n * ---- 0: canvas-screen rectangle, needs u_worldWidth = u_worldHeight = 0 to be responsive (see vertex shader)\n * ---- 1: static circle\n * ---- 2: animated flower-like polar shape\n * ---- 3: animated metaballs\n *\n */\n\n// language=GLSL\nexport const liquidMetalFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorTint;\n\nuniform float u_softness;\nuniform float u_repetition;\nuniform float u_shiftRed;\nuniform float u_shiftBlue;\nuniform float u_distortion;\nuniform float u_contour;\nuniform float u_shape;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${simplexNoise}\n\nfloat getColorChanges(float c1, float c2, float stripe_p, vec3 w, float blur, float bump, float tint) {\n \n float ch = mix(c2, c1, smoothstep(.0, 2. * blur, stripe_p));\n\n float border = w[0];\n ch = mix(ch, c2, smoothstep(border, border + 2. * blur, stripe_p));\n\n border = w[0] + .4 * (1. - bump) * w[1];\n ch = mix(ch, c1, smoothstep(border, border + 2. * blur, stripe_p));\n\n border = w[0] + .5 * (1. - bump) * w[1];\n ch = mix(ch, c2, smoothstep(border, border + 2. * blur, stripe_p));\n\n border = w[0] + w[1];\n ch = mix(ch, c1, smoothstep(border, border + 2. * blur, stripe_p));\n\n float gradient_t = (stripe_p - w[0] - w[1]) / w[2];\n float gradient = mix(c1, c2, smoothstep(0., 1., gradient_t));\n ch = mix(ch, gradient, smoothstep(border, border + .5 * blur, stripe_p));\n \n // Tint color is applied with color burn blending\n ch = mix(ch, 1. - min(1., (1. - ch) / max(tint, 0.0001)), u_colorTint.a);\n return ch;\n}\n\nvoid main() {\n\n float t = .1 * u_time;\n\n vec2 uv = v_objectUV;\n uv += .5;\n uv.y = 1. - uv.y;\n\n float cycleWidth = .5 * u_repetition;\n\n float mask = 1.;\n float contOffset = 1.;\n\n if (u_shape < 1.) {\n\n vec2 borderUV = v_responsiveUV + .5;\n float ratio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\n vec2 edge = min(borderUV, 1. - borderUV);\n vec2 pixel_thickness = 250. / v_responsiveBoxGivenSize;\n float maskX = smoothstep(0.0, pixel_thickness.x, edge.x);\n float maskY = smoothstep(0.0, pixel_thickness.y, edge.y);\n maskX = pow(maskX, .25);\n maskY = pow(maskY, .25);\n mask = clamp(1. - maskX * maskY, 0., 1.);\n\n uv = v_responsiveUV;\n if (ratio > 1.) {\n uv.y /= ratio;\n } else {\n uv.x *= ratio;\n }\n uv += .5;\n uv.y = 1. - uv.y;\n\n cycleWidth *= 2.;\n contOffset = 1.5;\n\n } else if (u_shape < 2.) {\n vec2 shapeUV = uv - .5;\n shapeUV *= .67;\n mask = pow(clamp(3. * length(shapeUV), 0., 1.), 18.);\n } else if (u_shape < 3.) {\n vec2 shapeUV = uv - .5;\n shapeUV *= 1.68;\n\n float r = length(shapeUV) * 2.;\n float a = atan(shapeUV.y, shapeUV.x) + .2;\n r *= (1. + .05 * sin(3. * a + 2. * t));\n float f = abs(cos(a * 3.));\n mask = smoothstep(f, f + .7, r);\n mask = pow(mask, 2.);\n\n uv *= .8;\n cycleWidth *= 1.6;\n\n } else if (u_shape < 4.) {\n vec2 shapeUV = uv - .5;\n shapeUV *= 1.3;\n mask = 0.;\n for (int i = 0; i < 5; i++) {\n float fi = float(i);\n float speed = 4.5 + 2. * sin(fi * 12.345);\n float angle = -fi * 1.5;\n vec2 dir1 = vec2(cos(angle), sin(angle));\n vec2 dir2 = vec2(cos(angle + 1.57), sin(angle + 1.));\n vec2 traj = .4 * (dir1 * sin(t * speed + fi * 1.23) + dir2 * cos(t * (speed * 0.7) + fi * 2.17));\n float d = length(shapeUV + traj);\n mask += pow(1.0 - clamp(d, 0.0, 1.0), 4.0);\n }\n mask = 1. - smoothstep(.65, .9, mask);\n mask = pow(mask, 4.);\n }\n\n float opacity = 1. - smoothstep(.82 - 2. * fwidth(mask), .82, mask);\n\n float ridge = .15 * (smoothstep(.0, .15, uv.y) * smoothstep(.4, .15, uv.y));\n ridge += .05 * (smoothstep(.1, .2, 1. - uv.y) * smoothstep(.4, .2, 1. - uv.y));\n mask += ridge;\n\n float diagBLtoTR = uv.x - uv.y;\n float diagTLtoBR = uv.x + uv.y;\n\n vec3 color = vec3(0.);\n vec3 color1 = vec3(.98, 0.98, 1.);\n vec3 color2 = vec3(.1, .1, .1 + .1 * smoothstep(.7, 1.3, diagTLtoBR));\n\n vec2 grad_uv = uv - .5;\n\n float dist = length(grad_uv + vec2(0., .2 * diagBLtoTR));\n grad_uv = rotate(grad_uv, (.25 - .2 * diagBLtoTR) * PI);\n float direction = grad_uv.x;\n\n float bump = pow(1.8 * dist, 1.2);\n bump = 1. - bump;\n bump *= pow(uv.y, .3);\n\n\n float thin_strip_1_ratio = .12 / cycleWidth * (1. - .4 * bump);\n float thin_strip_2_ratio = .07 / cycleWidth * (1. + .4 * bump);\n float wide_strip_ratio = (1. - thin_strip_1_ratio - thin_strip_2_ratio);\n\n float thin_strip_1_width = cycleWidth * thin_strip_1_ratio;\n float thin_strip_2_width = cycleWidth * thin_strip_2_ratio;\n\n float noise = snoise(uv - t);\n\n mask += (1. - mask) * u_distortion * noise;\n\n direction += diagBLtoTR;\n\n float contour = u_contour * smoothstep(0., contOffset + .01, mask) * smoothstep(contOffset + .01, 0., mask);\n direction -= 14. * noise * contour;\n\n bump *= clamp(pow(uv.y, .1), .3, 1.);\n direction *= (.1 + (1.1 - mask) * bump);\n direction *= smoothstep(1., .2, mask);\n\n\n direction *= (.5 + .5 * pow(uv.y, 2.));\n direction *= cycleWidth;\n direction -= t;\n\n\n float colorDispersion = (1. - bump);\n float dispersionRed = colorDispersion;\n dispersionRed += bump * noise;\n float dispersionBlue = colorDispersion;\n\n dispersionRed *= (u_shiftRed / 20.);\n dispersionBlue *= (u_shiftBlue / 20.);\n\n float blur = u_softness / 15. + .3 * contour;\n\n vec3 w = vec3(thin_strip_1_width, thin_strip_2_width, wide_strip_ratio);\n w[1] -= .02 * smoothstep(.0, 1., mask + bump);\n float stripe_r = mod(direction + dispersionRed, 1.);\n float r = getColorChanges(color1.r, color2.r, stripe_r, w, blur + fwidth(stripe_r), bump, u_colorTint.r);\n float stripe_g = mod(direction, 1.);\n float g = getColorChanges(color1.g, color2.g, stripe_g, w, blur + fwidth(stripe_g), bump, u_colorTint.g);\n float stripe_b = mod(direction - dispersionBlue, 1.);\n float b = getColorChanges(color1.b, color2.b, stripe_b, w, blur + fwidth(stripe_b), bump, u_colorTint.b);\n\n color = vec3(r, g, b);\n color *= opacity;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface LiquidMetalUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorTint: [number, number, number, number];\n u_softness: number;\n u_repetition: number;\n u_shiftRed: number;\n u_shiftBlue: number;\n u_distortion: number;\n u_contour: number;\n u_shape: (typeof LiquidMetalShapes)[LiquidMetalShape];\n}\n\nexport interface LiquidMetalParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorTint?: string;\n softness?: number;\n repetition?: number;\n shiftRed?: number;\n shiftBlue?: number;\n distortion?: number;\n contour?: number;\n shape?: LiquidMetalShape;\n}\n\nexport const LiquidMetalShapes = {\n none: 0,\n circle: 1,\n daisy: 2,\n metaballs: 3,\n} as const;\n\nexport type LiquidMetalShape = keyof typeof LiquidMetalShapes;\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,cAAc,uBAAuB;AAuB7D,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgLV,eAAe;AAAA;AAAA;AAAA;AAAA;AA8BZ,MAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AACb;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
5
|
|
|
6
6
|
import { sizingVariablesDeclaration } from "../shader-sizing.js";
|
|
7
|
-
import { declarePI,
|
|
7
|
+
import { declarePI, rotation2, colorBandingFix } from "../shader-utils.js";
|
|
8
8
|
const meshGradientMeta = {
|
|
9
9
|
maxColorCount: 10
|
|
10
10
|
};
|
|
@@ -24,7 +24,7 @@ ${sizingVariablesDeclaration}
|
|
|
24
24
|
out vec4 fragColor;
|
|
25
25
|
|
|
26
26
|
${declarePI}
|
|
27
|
-
${
|
|
27
|
+
${rotation2}
|
|
28
28
|
|
|
29
29
|
vec2 getPosition(int i, float t) {
|
|
30
30
|
float a = float(i) * .37;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/mesh-gradient.ts"],
|
|
4
|
-
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI,
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,
|
|
4
|
+
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, colorBandingFix } from '../shader-utils.js';\n\nexport const meshGradientMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * A composition of N color spots (one per color) with 2 types of\n * distortions applied to the coordinate space\n *\n * Uniforms:\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_distortion: warp distortion\n * - u_swirl: vortex distortion\n *\n */\n\n// language=GLSL\nexport const meshGradientFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colors[${meshGradientMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_distortion;\nuniform float u_swirl;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n\nvec2 getPosition(int i, float t) {\n float a = float(i) * .37;\n float b = .6 + mod(float(i), 3.) * .3;\n float c = .8 + mod(float(i + 1), 4.) * 0.25;\n\n float x = sin(t * b + a);\n float y = cos(t * c + a * 1.5);\n\n return .5 + .5 * vec2(x, y);\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n shape_uv += .5;\n\n float t = .5 * u_time;\n\n float radius = smoothstep(0., 1., length(shape_uv - .5));\n float center = 1. - radius;\n for (float i = 1.; i <= 2.; i++) {\n shape_uv.x += u_distortion * center / i * sin(t + i * .4 * smoothstep(.0, 1., shape_uv.y)) * cos(.2 * t + i * 2.4 * smoothstep(.0, 1., shape_uv.y));\n shape_uv.y += u_distortion * center / i * cos(t + i * 2. * smoothstep(.0, 1., shape_uv.x));\n }\n\n vec2 uvRotated = shape_uv;\n uvRotated -= vec2(.5);\n float angle = 3. * u_swirl * radius;\n uvRotated = rotate(uvRotated, -angle);\n uvRotated += vec2(.5);\n\n vec3 color = vec3(0.);\n float opacity = 0.;\n float totalWeight = 0.;\n\n for (int i = 0; i < ${meshGradientMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 pos = getPosition(i, t);\n vec3 colorFraction = u_colors[i].rgb * u_colors[i].a;\n float opacityFraction = u_colors[i].a;\n\n float dist = length(uvRotated - pos);\n\n dist = pow(dist, 3.5);\n float weight = 1. / (dist + 1e-3);\n color += colorFraction * weight;\n opacity += opacityFraction * weight;\n totalWeight += weight;\n }\n\n color /= totalWeight;\n opacity /= totalWeight;\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface MeshGradientUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_distortion: number;\n u_swirl: number;\n}\n\nexport interface MeshGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n distortion?: number;\n swirl?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,uBAAuB;AAE/C,MAAM,mBAAmB;AAAA,EAC9B,eAAe;AACjB;AAcO,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA,wBAK1B,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpD,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAqCa,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmBlD,eAAe;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,6 +15,8 @@ export declare const metaballsMeta: {
|
|
|
15
15
|
* - u_sizeRange (0..1): randomizes the size of balls between 0 and u_size
|
|
16
16
|
* - u_count: number of balls on the canvas
|
|
17
17
|
*
|
|
18
|
+
* - u_noiseTexture (sampler2D): pre-computed randomizer source
|
|
19
|
+
*
|
|
18
20
|
*/
|
|
19
21
|
export declare const metaballsFragmentShader: string;
|
|
20
22
|
export interface MetaballsUniforms extends ShaderSizingUniforms {
|
|
@@ -23,6 +25,7 @@ export interface MetaballsUniforms extends ShaderSizingUniforms {
|
|
|
23
25
|
u_colorsCount: number;
|
|
24
26
|
u_count: number;
|
|
25
27
|
u_size: number;
|
|
28
|
+
u_noiseTexture?: HTMLImageElement;
|
|
26
29
|
}
|
|
27
30
|
export interface MetaballsParams extends ShaderSizingParams, ShaderMotionParams {
|
|
28
31
|
colorBack?: string;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
5
|
|
|
6
6
|
import { sizingVariablesDeclaration } from "../shader-sizing.js";
|
|
7
|
-
import { declarePI, colorBandingFix } from "../shader-utils.js";
|
|
7
|
+
import { declarePI, textureRandomizerR, colorBandingFix } from "../shader-utils.js";
|
|
8
8
|
const metaballsMeta = {
|
|
9
9
|
maxColorCount: 8,
|
|
10
10
|
maxBallsCount: 20
|
|
@@ -14,6 +14,8 @@ precision mediump float;
|
|
|
14
14
|
|
|
15
15
|
uniform float u_time;
|
|
16
16
|
|
|
17
|
+
uniform sampler2D u_noiseTexture;
|
|
18
|
+
|
|
17
19
|
uniform vec4 u_colorBack;
|
|
18
20
|
uniform vec4 u_colors[${metaballsMeta.maxColorCount}];
|
|
19
21
|
uniform float u_colorsCount;
|
|
@@ -26,15 +28,14 @@ ${sizingVariablesDeclaration}
|
|
|
26
28
|
out vec4 fragColor;
|
|
27
29
|
|
|
28
30
|
${declarePI}
|
|
29
|
-
|
|
30
|
-
float hash(float x) {
|
|
31
|
-
return fract(sin(x) * 43758.5453123);
|
|
32
|
-
}
|
|
31
|
+
${textureRandomizerR}
|
|
33
32
|
float noise(float x) {
|
|
34
33
|
float i = floor(x);
|
|
35
34
|
float f = fract(x);
|
|
36
35
|
float u = f * f * (3.0 - 2.0 * f);
|
|
37
|
-
|
|
36
|
+
vec2 p0 = vec2(i, 0.0);
|
|
37
|
+
vec2 p1 = vec2(i + 1.0, 0.0);
|
|
38
|
+
return mix(randomR(p0), randomR(p1), u);
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
float getBallShape(vec2 uv, vec2 c, float p) {
|
|
@@ -49,7 +50,7 @@ void main() {
|
|
|
49
50
|
|
|
50
51
|
shape_uv += .5;
|
|
51
52
|
|
|
52
|
-
float t = .2 * u_time +
|
|
53
|
+
float t = .2 * u_time + 500.;
|
|
53
54
|
|
|
54
55
|
vec3 totalColor = vec3(0.);
|
|
55
56
|
float totalShape = 0.;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/metaballs.ts"],
|
|
4
|
-
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, colorBandingFix } from '../shader-utils.js';\n\nexport const metaballsMeta = {\n maxColorCount: 8,\n maxBallsCount: 20,\n} as const;\n\n/**\n * N circular shapes moving around the center, blending and merging based on distance\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_size: ball base size\n * - u_sizeRange (0..1): randomizes the size of balls between 0 and u_size\n * - u_count: number of balls on the canvas\n *\n */\n\n// language=GLSL\nexport const metaballsFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${metaballsMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_size;\nuniform float u_sizeRange;\nuniform float u_count;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;
|
|
4
|
+
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, textureRandomizerR, colorBandingFix } from '../shader-utils.js';\n\nexport const metaballsMeta = {\n maxColorCount: 8,\n maxBallsCount: 20,\n} as const;\n\n/**\n * N circular shapes moving around the center, blending and merging based on distance\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_size: ball base size\n * - u_sizeRange (0..1): randomizes the size of balls between 0 and u_size\n * - u_count: number of balls on the canvas\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n */\n\n// language=GLSL\nexport const metaballsFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${metaballsMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_size;\nuniform float u_sizeRange;\nuniform float u_count;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${textureRandomizerR}\nfloat noise(float x) {\n float i = floor(x);\n float f = fract(x);\n float u = f * f * (3.0 - 2.0 * f);\n vec2 p0 = vec2(i, 0.0);\n vec2 p1 = vec2(i + 1.0, 0.0);\n return mix(randomR(p0), randomR(p1), u);\n}\n\nfloat getBallShape(vec2 uv, vec2 c, float p) {\n float s = .5 * length(uv - c);\n s = 1. - clamp(s, 0., 1.);\n s = pow(s, p);\n return s;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n shape_uv += .5;\n\n float t = .2 * u_time + 500.;\n\n vec3 totalColor = vec3(0.);\n float totalShape = 0.;\n float totalOpacity = 0.;\n\n for (int i = 0; i < ${metaballsMeta.maxBallsCount}; i++) {\n if (i >= int(ceil(u_count))) break;\n\n float idxFract = float(i) / float(${metaballsMeta.maxBallsCount});\n float angle = TWO_PI * idxFract;\n\n float speed = 1. - .2 * idxFract;\n float noiseX = noise(angle * 10. + float(i) + t * speed);\n float noiseY = noise(angle * 20. + float(i) - t * speed);\n\n vec2 pos = vec2(.5) + 1e-4 + .9 * (vec2(noiseX, noiseY) - .5);\n\n int safeIndex = i % int(u_colorsCount + 0.5);\n vec4 ballColor = u_colors[safeIndex];\n ballColor.rgb *= ballColor.a;\n\n float sizeFrac = 1.;\n if (float(i) > floor(u_count - 1.)) {\n sizeFrac *= fract(u_count);\n }\n\n float shape = getBallShape(shape_uv, pos, 45. - 30. * u_size * sizeFrac);\n shape *= pow(u_size, .2);\n shape = smoothstep(0., 1., shape);\n\n totalColor += ballColor.rgb * shape;\n totalShape += shape;\n totalOpacity += ballColor.a * shape;\n }\n\n totalColor /= max(totalShape, 1e-4);\n totalOpacity /= max(totalShape, 1e-4);\n\n float edge_width = fwidth(totalShape);\n float finalShape = smoothstep(.4, .4 + edge_width, totalShape);\n\n vec3 color = totalColor * finalShape;\n float opacity = totalOpacity * finalShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface MetaballsUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_count: number;\n u_size: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface MetaballsParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n count?: number;\n size?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,oBAAoB,uBAAuB;AAExD,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,eAAe;AACjB;AAiBO,MAAM,0BAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQvB,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjD,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA4BI,cAAc,aAAa;AAAA;AAAA;AAAA,wCAGX,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwC/D,eAAe;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,7 +2,7 @@ import type { ShaderMotionParams } from '../shader-mount.js';
|
|
|
2
2
|
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
|
-
* Fractal-like structure made of several layers of
|
|
5
|
+
* Fractal-like structure made of several layers of sine arches
|
|
6
6
|
* Original algorithm: https://x.com/zozuar/status/1625182758745128981/
|
|
7
7
|
*
|
|
8
8
|
* Uniforms:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
5
|
|
|
6
6
|
import { sizingVariablesDeclaration } from "../shader-sizing.js";
|
|
7
|
-
import {
|
|
7
|
+
import { rotation2, colorBandingFix } from "../shader-utils.js";
|
|
8
8
|
const neuroNoiseFragmentShader = `#version 300 es
|
|
9
9
|
precision mediump float;
|
|
10
10
|
|
|
@@ -23,7 +23,7 @@ ${sizingVariablesDeclaration}
|
|
|
23
23
|
|
|
24
24
|
out vec4 fragColor;
|
|
25
25
|
|
|
26
|
-
${
|
|
26
|
+
${rotation2}
|
|
27
27
|
|
|
28
28
|
float neuroShape(vec2 uv, float t) {
|
|
29
29
|
vec2 sine_acc = vec2(0.);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/neuro-noise.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport {
|
|
5
|
-
"mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { rotation2, colorBandingFix } from '../shader-utils.js';\n\n/**\n *\n * Fractal-like structure made of several layers of sine arches\n * Original algorithm: https://x.com/zozuar/status/1625182758745128981/\n *\n * Uniforms:\n * - u_colorBack, u_colorMid, u_colorFront (RGBA)\n * - u_brightness, u_contrast\n *\n */\n\n// language=GLSL\nexport const neuroNoiseFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform vec4 u_colorFront;\nuniform vec4 u_colorMid;\nuniform vec4 u_colorBack;\nuniform float u_brightness;\nuniform float u_contrast;\n\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${rotation2}\n\nfloat neuroShape(vec2 uv, float t) {\n vec2 sine_acc = vec2(0.);\n vec2 res = vec2(0.);\n float scale = 8.;\n\n for (int j = 0; j < 15; j++) {\n uv = rotate(uv, 1.);\n sine_acc = rotate(sine_acc, 1.);\n vec2 layer = uv * scale + float(j) + sine_acc - t;\n sine_acc += sin(layer);\n res += (.5 + .5 * cos(layer)) / scale;\n scale *= (1.2);\n }\n return res.x + res.y;\n}\n\nvoid main() {\n vec2 shape_uv = v_patternUV;\n shape_uv *= .13;\n\n float t = .5 * u_time;\n\n float noise = neuroShape(shape_uv, t);\n\n noise = (1. + u_brightness) * pow(noise, 2.);\n noise = pow(noise, .7 + 6. * u_contrast);\n noise = min(1.4, noise);\n\n float blend = smoothstep(0.7, 1.4, noise);\n\n vec4 frontC = u_colorFront;\n frontC.rgb *= frontC.a;\n vec4 midC = u_colorMid;\n midC.rgb *= midC.a;\n vec4 blendFront = mix(midC, frontC, blend);\n\n float safeNoise = max(noise, 0.0);\n vec3 color = blendFront.rgb * safeNoise;\n float opacity = clamp(blendFront.a * safeNoise, 0., 1.);\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1. - opacity);\n opacity = opacity + u_colorBack.a * (1. - opacity);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface NeuroNoiseUniforms extends ShaderSizingUniforms {\n u_colorFront: [number, number, number, number];\n u_colorMid: [number, number, number, number];\n u_colorBack: [number, number, number, number];\n u_brightness: number;\n u_contrast: number;\n}\n\nexport interface NeuroNoiseParams extends ShaderSizingParams, ShaderMotionParams {\n colorFront?: string;\n colorMid?: string;\n colorBack?: string;\n brightness?: number;\n contrast?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,uBAAuB;AAcpC,MAAM,2BAAmC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc9C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8CP,eAAe;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ShaderMotionParams } from '../shader-mount.js';
|
|
2
|
+
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
3
|
+
/**
|
|
4
|
+
* Mimicking paper texture with a combination of noises
|
|
5
|
+
*
|
|
6
|
+
* Uniforms:
|
|
7
|
+
* - u_colorFront, u_colorBack (RGBA)
|
|
8
|
+
* - u_contrast - mixing front and back colors
|
|
9
|
+
* - u_roughness - pixel noise, related to canvas => not scalable
|
|
10
|
+
* - u_fiber, u_fiberScale - curly shaped noise
|
|
11
|
+
* - u_crumples, u_crumplesScale - cell-based pattern
|
|
12
|
+
* - u_folds, u_foldsNumber - lines pattern, 15 max
|
|
13
|
+
* - u_drops - metaballs-like pattern
|
|
14
|
+
* - u_seed - applied to folds, crumples and dots
|
|
15
|
+
* - u_blur - big-scale noise mask applied to everything but roughness
|
|
16
|
+
*
|
|
17
|
+
* - u_noiseTexture (sampler2D): pre-computed randomizer source
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
export declare const paperTextureFragmentShader: string;
|
|
21
|
+
export interface PaperTextureUniforms extends ShaderSizingUniforms {
|
|
22
|
+
u_image: HTMLImageElement | string | undefined;
|
|
23
|
+
u_noiseTexture?: HTMLImageElement;
|
|
24
|
+
u_colorFront: [number, number, number, number];
|
|
25
|
+
u_colorBack: [number, number, number, number];
|
|
26
|
+
u_contrast: number;
|
|
27
|
+
u_roughness: number;
|
|
28
|
+
u_fiber: number;
|
|
29
|
+
u_fiberScale: number;
|
|
30
|
+
u_crumples: number;
|
|
31
|
+
u_foldsNumber: number;
|
|
32
|
+
u_folds: number;
|
|
33
|
+
u_blur: number;
|
|
34
|
+
u_crumplesScale: number;
|
|
35
|
+
u_drops: number;
|
|
36
|
+
u_seed: number;
|
|
37
|
+
}
|
|
38
|
+
export interface PaperTextureParams extends ShaderSizingParams, ShaderMotionParams {
|
|
39
|
+
image?: HTMLImageElement | string | undefined;
|
|
40
|
+
colorFront?: string;
|
|
41
|
+
colorBack?: string;
|
|
42
|
+
contrast?: number;
|
|
43
|
+
roughness?: number;
|
|
44
|
+
fiber?: number;
|
|
45
|
+
fiberScale?: number;
|
|
46
|
+
crumples?: number;
|
|
47
|
+
foldsNumber?: number;
|
|
48
|
+
folds?: number;
|
|
49
|
+
blur?: number;
|
|
50
|
+
crumplesScale?: number;
|
|
51
|
+
drops?: number;
|
|
52
|
+
seed?: number;
|
|
53
|
+
}
|