@paper-design/shaders 0.0.60 → 0.0.62
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/dist/shader-mount.d.ts +5 -1
- package/dist/shader-mount.js +5 -2
- package/dist/shader-mount.js.map +2 -2
- package/dist/shaders/color-panels.js +4 -3
- package/dist/shaders/color-panels.js.map +2 -2
- package/dist/shaders/dithering.js +4 -4
- package/dist/shaders/dithering.js.map +1 -1
- package/dist/shaders/dot-grid.js +5 -4
- package/dist/shaders/dot-grid.js.map +2 -2
- package/dist/shaders/dot-orbit.js +1 -1
- package/dist/shaders/dot-orbit.js.map +1 -1
- package/dist/shaders/fluted-glass.d.ts +19 -5
- package/dist/shaders/fluted-glass.js +250 -64
- package/dist/shaders/fluted-glass.js.map +2 -2
- package/dist/shaders/god-rays.js +4 -2
- package/dist/shaders/god-rays.js.map +2 -2
- package/dist/shaders/grain-gradient.js +4 -4
- package/dist/shaders/grain-gradient.js.map +1 -1
- package/dist/shaders/heatmap.js +13 -12
- package/dist/shaders/heatmap.js.map +2 -2
- package/dist/shaders/image-dithering.js +2 -2
- package/dist/shaders/image-dithering.js.map +1 -1
- package/dist/shaders/liquid-metal.js +2 -2
- package/dist/shaders/liquid-metal.js.map +1 -1
- package/dist/shaders/mesh-gradient.js +4 -4
- package/dist/shaders/mesh-gradient.js.map +1 -1
- package/dist/shaders/neuro-noise.js +1 -1
- package/dist/shaders/neuro-noise.js.map +1 -1
- package/dist/shaders/paper-texture.js +4 -4
- package/dist/shaders/paper-texture.js.map +1 -1
- package/dist/shaders/perlin-noise.js +2 -2
- package/dist/shaders/perlin-noise.js.map +1 -1
- package/dist/shaders/pulsing-border.js +7 -7
- package/dist/shaders/pulsing-border.js.map +1 -1
- package/dist/shaders/smoke-ring.js +8 -6
- package/dist/shaders/smoke-ring.js.map +2 -2
- package/dist/shaders/spiral.js +1 -1
- package/dist/shaders/spiral.js.map +1 -1
- package/dist/shaders/static-mesh-gradient.js +2 -2
- package/dist/shaders/static-mesh-gradient.js.map +1 -1
- package/dist/shaders/static-radial-gradient.js +17 -14
- package/dist/shaders/static-radial-gradient.js.map +2 -2
- package/dist/shaders/swirl.js +2 -1
- package/dist/shaders/swirl.js.map +2 -2
- package/dist/shaders/warp.js +4 -2
- package/dist/shaders/warp.js.map +2 -2
- package/dist/shaders/water.js +5 -5
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/waves.js +3 -1
- package/dist/shaders/waves.js.map +2 -2
- package/package.json +1 -1
|
@@ -3,22 +3,29 @@
|
|
|
3
3
|
* https://github.com/paper-design/shaders *
|
|
4
4
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { declarePI, rotation2 } from "../shader-utils.js";
|
|
6
|
+
import { sizingUniformsDeclaration } from "../shader-sizing.js";
|
|
7
|
+
import { declarePI, rotation2, proceduralHash21 } from "../shader-utils.js";
|
|
8
8
|
const flutedGlassFragmentShader = `#version 300 es
|
|
9
9
|
precision mediump float;
|
|
10
10
|
|
|
11
11
|
uniform vec2 u_resolution;
|
|
12
12
|
uniform float u_pixelRatio;
|
|
13
|
+
${sizingUniformsDeclaration}
|
|
14
|
+
|
|
15
|
+
uniform vec4 u_colorBack;
|
|
16
|
+
uniform vec4 u_colorShadow;
|
|
17
|
+
uniform vec4 u_colorHighlight;
|
|
13
18
|
|
|
14
19
|
uniform sampler2D u_image;
|
|
15
20
|
uniform float u_imageAspectRatio;
|
|
16
21
|
|
|
17
22
|
uniform float u_size;
|
|
23
|
+
uniform float u_shadows;
|
|
18
24
|
uniform float u_angle;
|
|
19
|
-
uniform float
|
|
25
|
+
uniform float u_stretch;
|
|
20
26
|
uniform float u_shape;
|
|
21
27
|
uniform float u_distortion;
|
|
28
|
+
uniform float u_highlights;
|
|
22
29
|
uniform float u_distortionShape;
|
|
23
30
|
uniform float u_shift;
|
|
24
31
|
uniform float u_blur;
|
|
@@ -26,28 +33,69 @@ uniform float u_marginLeft;
|
|
|
26
33
|
uniform float u_marginRight;
|
|
27
34
|
uniform float u_marginTop;
|
|
28
35
|
uniform float u_marginBottom;
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
uniform float u_grainMixer;
|
|
37
|
+
uniform float u_grainOverlay;
|
|
31
38
|
|
|
32
39
|
out vec4 fragColor;
|
|
33
40
|
|
|
34
41
|
${declarePI}
|
|
35
42
|
${rotation2}
|
|
43
|
+
${proceduralHash21}
|
|
44
|
+
|
|
45
|
+
float valueNoise(vec2 st) {
|
|
46
|
+
vec2 i = floor(st);
|
|
47
|
+
vec2 f = fract(st);
|
|
48
|
+
float a = hash21(i);
|
|
49
|
+
float b = hash21(i + vec2(1.0, 0.0));
|
|
50
|
+
float c = hash21(i + vec2(0.0, 1.0));
|
|
51
|
+
float d = hash21(i + vec2(1.0, 1.0));
|
|
52
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
53
|
+
float x1 = mix(a, b, u.x);
|
|
54
|
+
float x2 = mix(c, d, u.x);
|
|
55
|
+
return mix(x1, x2, u.y);
|
|
56
|
+
}
|
|
36
57
|
|
|
37
|
-
float getUvFrame(vec2 uv) {
|
|
38
|
-
float aax = 2. * fwidth(uv.x);
|
|
39
|
-
float aay = 2. * fwidth(uv.y);
|
|
40
58
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
float
|
|
44
|
-
|
|
59
|
+
vec2 getImageUV(vec2 uv, vec2 extraScale) {
|
|
60
|
+
vec2 boxOrigin = vec2(.5 - u_originX, u_originY - .5);
|
|
61
|
+
float r = u_rotation * PI / 180.;
|
|
62
|
+
mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));
|
|
63
|
+
vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);
|
|
64
|
+
|
|
65
|
+
vec2 imageBoxSize;
|
|
66
|
+
if (u_fit == 1.) {
|
|
67
|
+
imageBoxSize.x = min(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;
|
|
68
|
+
} else {
|
|
69
|
+
imageBoxSize.x = max(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;
|
|
70
|
+
}
|
|
71
|
+
imageBoxSize.y = imageBoxSize.x / u_imageAspectRatio;
|
|
72
|
+
vec2 imageBoxScale = u_resolution.xy / imageBoxSize;
|
|
73
|
+
|
|
74
|
+
vec2 imageUV = uv;
|
|
75
|
+
imageUV *= imageBoxScale;
|
|
76
|
+
imageUV += boxOrigin * (imageBoxScale - 1.);
|
|
77
|
+
imageUV += graphicOffset;
|
|
78
|
+
imageUV /= u_scale;
|
|
79
|
+
imageUV *= extraScale;
|
|
80
|
+
imageUV.x *= u_imageAspectRatio;
|
|
81
|
+
imageUV = graphicRotation * imageUV;
|
|
82
|
+
imageUV.x /= u_imageAspectRatio;
|
|
83
|
+
|
|
84
|
+
imageUV += .5;
|
|
85
|
+
imageUV.y = 1. - imageUV.y;
|
|
86
|
+
|
|
87
|
+
return imageUV;
|
|
88
|
+
}
|
|
45
89
|
|
|
90
|
+
float getUvFrame(vec2 uv, float aa) {
|
|
91
|
+
float left = smoothstep(0., aa, uv.x);
|
|
92
|
+
float right = 1. - smoothstep(1. - aa, 1., uv.x);
|
|
93
|
+
float bottom = smoothstep(0., aa, uv.y);
|
|
94
|
+
float top = 1. - smoothstep(1. - aa, 1., uv.y);
|
|
46
95
|
return left * right * bottom * top;
|
|
47
96
|
}
|
|
48
97
|
|
|
49
98
|
const int MAX_RADIUS = 50;
|
|
50
|
-
|
|
51
99
|
vec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {
|
|
52
100
|
if (sigma <= .5) return texture(tex, uv);
|
|
53
101
|
int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));
|
|
@@ -71,46 +119,82 @@ vec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {
|
|
|
71
119
|
sum += (s1 + s2) * w;
|
|
72
120
|
weightSum += 2.0 * w;
|
|
73
121
|
}
|
|
74
|
-
|
|
75
122
|
return sum / weightSum;
|
|
76
123
|
}
|
|
77
124
|
|
|
125
|
+
vec2 rotateAspect(vec2 p, float a, float aspect) {
|
|
126
|
+
p.x *= aspect;
|
|
127
|
+
p = rotate(p, a);
|
|
128
|
+
p.x /= aspect;
|
|
129
|
+
return p;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
float smoothFract(float x) {
|
|
133
|
+
float f = fract(x);
|
|
134
|
+
float w = fwidth(x);
|
|
135
|
+
|
|
136
|
+
float edge = abs(f - 0.5) - 0.5;
|
|
137
|
+
float band = smoothstep(-w, w, edge);
|
|
138
|
+
|
|
139
|
+
return mix(f, 1.0 - f, band);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
float blendOverlay(float base, float blend) {
|
|
143
|
+
return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
|
|
144
|
+
}
|
|
145
|
+
vec3 blendOverlay(vec3 base, vec3 blend) {
|
|
146
|
+
return vec3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
|
|
147
|
+
}
|
|
148
|
+
vec3 blendHardLight(vec3 base, vec3 blend) {
|
|
149
|
+
return blendOverlay(blend, base);
|
|
150
|
+
}
|
|
151
|
+
vec3 blendHardLight(vec3 base, vec3 blend, float opacity) {
|
|
152
|
+
return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
78
156
|
void main() {
|
|
79
|
-
vec2 imageUV = v_imageUV;
|
|
80
157
|
|
|
81
|
-
vec2
|
|
82
|
-
|
|
83
|
-
|
|
158
|
+
vec2 uvNormalised = (gl_FragCoord.xy - .5 * u_resolution) / u_resolution.xy;
|
|
159
|
+
vec2 uvOriginal = getImageUV(uvNormalised, vec2(1.));
|
|
160
|
+
float origFrameBox = getUvFrame(uvOriginal, .01);
|
|
161
|
+
|
|
162
|
+
float patternRotation = -u_angle * PI / 180.;
|
|
163
|
+
float patternSize = mix(200., 5., u_size);
|
|
84
164
|
|
|
85
|
-
|
|
165
|
+
vec2 uv = uvOriginal;
|
|
86
166
|
|
|
87
|
-
vec2
|
|
167
|
+
vec2 uvMask = gl_FragCoord.xy / u_resolution.xy;
|
|
168
|
+
vec2 sw = vec2(.005 * u_distortion);
|
|
169
|
+
vec4 margins = vec4(u_marginLeft, u_marginTop, u_marginRight, u_marginBottom);
|
|
88
170
|
float maskOuter =
|
|
89
|
-
smoothstep(
|
|
90
|
-
smoothstep(
|
|
91
|
-
smoothstep(
|
|
92
|
-
smoothstep(
|
|
171
|
+
smoothstep(margins[0] - sw.x, margins[0], uvMask.x + sw.x) *
|
|
172
|
+
smoothstep(margins[2] - sw.x, margins[2], 1.0 - uvMask.x + sw.x) *
|
|
173
|
+
smoothstep(margins[1] - sw.y, margins[1], uvMask.y + sw.y) *
|
|
174
|
+
smoothstep(margins[3] - sw.y, margins[3], 1.0 - uvMask.y + sw.y);
|
|
93
175
|
float mask =
|
|
94
|
-
smoothstep(
|
|
95
|
-
smoothstep(
|
|
96
|
-
smoothstep(
|
|
97
|
-
smoothstep(
|
|
98
|
-
float
|
|
176
|
+
smoothstep(margins[0], margins[0] + sw.x, uvMask.x + sw.x) *
|
|
177
|
+
smoothstep(margins[2], margins[2] + sw.x, 1.0 - uvMask.x + sw.x) *
|
|
178
|
+
smoothstep(margins[1], margins[1] + sw.y, uvMask.y + sw.y) *
|
|
179
|
+
smoothstep(margins[3], margins[3] + sw.y, 1.0 - uvMask.y + sw.y);
|
|
180
|
+
float maskStroke = (1. - mask) * maskOuter;
|
|
181
|
+
float maskStrokeInner = (1. - mask) * smoothstep(.95, 1., maskOuter);
|
|
99
182
|
|
|
100
|
-
|
|
101
|
-
uv
|
|
102
|
-
uv
|
|
183
|
+
uv -= .5;
|
|
184
|
+
uv *= patternSize;
|
|
185
|
+
uv = rotateAspect(uv, patternRotation, u_imageAspectRatio);
|
|
103
186
|
|
|
104
187
|
float curve = 0.;
|
|
188
|
+
float patternY = uv.y / u_imageAspectRatio;
|
|
105
189
|
if (u_shape > 4.5) {
|
|
106
190
|
// pattern
|
|
107
|
-
curve = .5 + .5 * sin(
|
|
191
|
+
curve = .5 + .5 * sin(.5 * PI * uv.x) * cos(.5 * PI * patternY);
|
|
108
192
|
} else if (u_shape > 3.5) {
|
|
109
193
|
// zigzag
|
|
110
|
-
curve = 10. * abs(fract(.1 *
|
|
194
|
+
curve = 10. * abs(fract(.1 * patternY) - .5);
|
|
111
195
|
} else if (u_shape > 2.5) {
|
|
112
196
|
// wave
|
|
113
|
-
curve = 4. * sin(.23 *
|
|
197
|
+
curve = 4. * sin(.23 * patternY);
|
|
114
198
|
} else if (u_shape > 1.5) {
|
|
115
199
|
// lines irregular
|
|
116
200
|
curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);
|
|
@@ -118,50 +202,152 @@ void main() {
|
|
|
118
202
|
// lines
|
|
119
203
|
}
|
|
120
204
|
|
|
121
|
-
vec2
|
|
122
|
-
|
|
205
|
+
vec2 UvToFract = uv + curve;
|
|
206
|
+
vec2 fractOrigUV = fract(uv);
|
|
207
|
+
vec2 floorOrigUV = floor(uv);
|
|
208
|
+
|
|
209
|
+
float x = smoothFract(UvToFract.x);
|
|
210
|
+
float xNonSmooth = fract(UvToFract.x);
|
|
211
|
+
|
|
212
|
+
float w = 2. * fwidth(UvToFract.x);
|
|
213
|
+
w *= mask;
|
|
214
|
+
w += maskStrokeInner;
|
|
215
|
+
float highlights = smoothstep(0., w, xNonSmooth);
|
|
216
|
+
highlights *= smoothstep(1., 1. - w, xNonSmooth);
|
|
217
|
+
highlights = mix(1., highlights, u_highlights);
|
|
123
218
|
|
|
124
|
-
|
|
125
|
-
|
|
219
|
+
float shadows = x;
|
|
220
|
+
float distortion = 0.;
|
|
221
|
+
float fadeX = 1.;
|
|
222
|
+
float frameFade = 0.;
|
|
126
223
|
|
|
127
|
-
|
|
128
|
-
|
|
224
|
+
float aa = fwidth(xNonSmooth);
|
|
225
|
+
aa = max(aa, fwidth(uv.x));
|
|
226
|
+
aa = max(aa, fwidth(UvToFract.x));
|
|
129
227
|
|
|
130
|
-
|
|
131
|
-
edges *= mask;
|
|
228
|
+
shadows = pow(x, 2.);
|
|
132
229
|
|
|
133
|
-
float xDistortion = 0.;
|
|
134
230
|
if (u_distortionShape == 1.) {
|
|
135
|
-
|
|
231
|
+
distortion = -pow(1.5 * x, 3.);
|
|
232
|
+
distortion += (.5 - u_shift);
|
|
233
|
+
|
|
234
|
+
frameFade = pow(1.5 * x, 3.);
|
|
235
|
+
aa = max(.2, aa);
|
|
236
|
+
aa += mix(.2, 0., u_size);
|
|
237
|
+
fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
|
|
238
|
+
distortion = mix(.5, distortion, fadeX);
|
|
136
239
|
} else if (u_distortionShape == 2.) {
|
|
137
|
-
|
|
240
|
+
distortion = 2. * pow(x, 2.);
|
|
241
|
+
distortion -= (.5 + u_shift);
|
|
242
|
+
|
|
243
|
+
frameFade = pow(abs(x - .5), 4.);
|
|
244
|
+
aa = max(.2, aa);
|
|
245
|
+
aa += mix(.2, 0., u_size);
|
|
246
|
+
fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
|
|
247
|
+
distortion = mix(.5, distortion, fadeX);
|
|
248
|
+
frameFade = mix(1., frameFade, .5 * fadeX);
|
|
138
249
|
} else if (u_distortionShape == 3.) {
|
|
139
|
-
|
|
250
|
+
distortion = pow(2. * (xNonSmooth - .5), 6.);
|
|
251
|
+
distortion -= .25;
|
|
252
|
+
distortion -= u_shift;
|
|
253
|
+
|
|
254
|
+
frameFade = 1. - 2. * pow(abs(x - .4), 2.);
|
|
255
|
+
aa = .15;
|
|
256
|
+
aa += mix(.1, 0., u_size);
|
|
257
|
+
fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
|
|
258
|
+
frameFade = mix(1., frameFade, fadeX);
|
|
259
|
+
|
|
140
260
|
} else if (u_distortionShape == 4.) {
|
|
141
|
-
|
|
142
|
-
|
|
261
|
+
x = xNonSmooth;
|
|
262
|
+
distortion = sin((x + .25) * TWO_PI);
|
|
263
|
+
shadows = .5 + .5 * distortion;
|
|
264
|
+
distortion *= .5;
|
|
265
|
+
distortion -= u_shift;
|
|
266
|
+
frameFade = .5 + .5 * sin(x * TWO_PI);
|
|
143
267
|
} else if (u_distortionShape == 5.) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
268
|
+
distortion -= pow(abs(x), .2) * x;
|
|
269
|
+
distortion += .33;
|
|
270
|
+
distortion -= 3. * u_shift;
|
|
271
|
+
distortion *= .33;
|
|
272
|
+
|
|
273
|
+
frameFade = .3 * (smoothstep(.0, 1., x));
|
|
274
|
+
shadows = pow(x, 6.);
|
|
275
|
+
|
|
276
|
+
aa = max(.1, aa);
|
|
277
|
+
aa += mix(.1, 0., u_size);
|
|
278
|
+
fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);
|
|
279
|
+
distortion *= fadeX;
|
|
147
280
|
}
|
|
148
281
|
|
|
149
|
-
|
|
282
|
+
vec2 dudx = dFdx(uvOriginal);
|
|
283
|
+
vec2 dudy = dFdy(uvOriginal);
|
|
284
|
+
vec2 grainUV = getImageUV(uvNormalised, .8 / vec2(length(dudx), length(dudy)));
|
|
285
|
+
float grain = valueNoise(grainUV);
|
|
286
|
+
grain = smoothstep(.4, .7, grain);
|
|
287
|
+
grain *= u_grainMixer;
|
|
288
|
+
distortion = mix(distortion, 0., grain);
|
|
289
|
+
|
|
290
|
+
shadows = min(shadows, 1.);
|
|
291
|
+
shadows *= mask;
|
|
292
|
+
shadows += .5 * maskStroke;
|
|
293
|
+
shadows = min(shadows, 1.);
|
|
294
|
+
|
|
295
|
+
distortion *= 3. * u_distortion;
|
|
296
|
+
frameFade *= u_distortion;
|
|
297
|
+
|
|
298
|
+
fractOrigUV.x += distortion;
|
|
299
|
+
floorOrigUV = rotateAspect(floorOrigUV, -patternRotation, u_imageAspectRatio);
|
|
300
|
+
fractOrigUV = rotateAspect(fractOrigUV, -patternRotation, u_imageAspectRatio);
|
|
301
|
+
|
|
302
|
+
uv = (floorOrigUV + fractOrigUV) / patternSize;
|
|
303
|
+
uv += pow(maskStroke, 4.);
|
|
304
|
+
|
|
305
|
+
uv += vec2(.5);
|
|
306
|
+
|
|
307
|
+
uv = mix(uvOriginal, uv, mask);
|
|
308
|
+
float blur = mix(0., mix(0., 50., u_blur), mask);
|
|
309
|
+
|
|
310
|
+
float frameBlur = mix(0., .04, u_blur);
|
|
311
|
+
frameBlur += .03 * frameFade;
|
|
312
|
+
frameBlur *= mask;
|
|
313
|
+
float frame = getUvFrame(uv, frameBlur);
|
|
314
|
+
|
|
315
|
+
float stretch = 1. - smoothstep(0., .5, xNonSmooth) * smoothstep(1., 1. - .5, xNonSmooth);
|
|
316
|
+
stretch = pow(stretch, 2.);
|
|
317
|
+
stretch *= mask;
|
|
318
|
+
stretch *= getUvFrame(uv, .1 + .05 * mask * frameFade);
|
|
319
|
+
uv.y = mix(uv.y, .5, u_stretch * stretch);
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
vec4 image = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);
|
|
323
|
+
vec4 backColor = u_colorBack;
|
|
324
|
+
backColor.rgb *= backColor.a;
|
|
325
|
+
vec4 highlightColor = u_colorHighlight;
|
|
326
|
+
highlightColor.rgb *= highlightColor.a;
|
|
327
|
+
vec4 shadowColor = u_colorShadow;
|
|
328
|
+
shadowColor.rgb *= shadowColor.a;
|
|
329
|
+
|
|
330
|
+
vec3 color = mix(backColor.rgb, image.rgb, image.a * frame);
|
|
331
|
+
float opacity = backColor.a + image.a * frame;
|
|
150
332
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
333
|
+
shadows *= pow(u_shadows, 2.);
|
|
334
|
+
shadows *= shadowColor.a;
|
|
335
|
+
color = mix(color, shadowColor.rgb, .5 * shadows);
|
|
336
|
+
color += .5 * pow(shadows, .5) * shadowColor.rgb;
|
|
155
337
|
|
|
156
|
-
|
|
338
|
+
opacity += shadows;
|
|
339
|
+
opacity = clamp(opacity, 0., 1.);
|
|
157
340
|
|
|
158
|
-
|
|
159
|
-
|
|
341
|
+
color = mix(highlightColor.rgb, color, highlights);
|
|
342
|
+
opacity = mix(highlightColor.a, opacity, highlights);
|
|
160
343
|
|
|
161
|
-
|
|
344
|
+
float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));
|
|
345
|
+
grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);
|
|
346
|
+
grainOverlay = pow(grainOverlay, 2.);
|
|
347
|
+
vec3 grainOverlayColor = vec3(grainOverlay);
|
|
348
|
+
color = mix(color, blendHardLight(color, grainOverlayColor, .5 * u_grainOverlay), mask);
|
|
162
349
|
|
|
163
|
-
|
|
164
|
-
fragColor = vec4(color.rgb, opacity);
|
|
350
|
+
fragColor = vec4(color, opacity);
|
|
165
351
|
}
|
|
166
352
|
`;
|
|
167
353
|
const GlassGridShapes = {
|
|
@@ -176,7 +362,7 @@ const GlassDistortionShapes = {
|
|
|
176
362
|
lens: 2,
|
|
177
363
|
contour: 3,
|
|
178
364
|
cascade: 4,
|
|
179
|
-
|
|
365
|
+
flat: 5
|
|
180
366
|
};
|
|
181
367
|
export {
|
|
182
368
|
GlassDistortionShapes,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/fluted-glass.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2 } from '../shader-utils.js';\n\n/**\n * Mimicking glass surface distortion over the image by distorting the texture\n * coordinates within line patterns\n *\n * Uniforms:\n * - u_size, u_angle - size and direction of grid relative to the image\n * - u_shape (float used as integer):\n * ---- 1: uniformly spaced stripes\n * ---- 2: randomly spaced stripes\n * ---- 3: sine wave stripes\n * ---- 4: zigzag stripes\n * ---- 5: wave-based pattern\n * - u_distortion - the power of distortion applied along within each stripe\n * - u_distortionShape (float used as integer):\n * ---- 5 shapes available\n * - u_shift - texture shift in direction opposite to the grid\n * - u_blur - one-directional blur applied over the main distortion\n * - u_edges - thin color lines along the grid (independent from distortion)\n * - u_marginLeft, u_marginRight, u_marginTop, u_marginBottom - paddings\n * within picture to be shown without any distortion\n *\n */\n\n// language=GLSL\nexport const flutedGlassFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_size;\nuniform float u_angle;\nuniform float u_edges;\nuniform float u_shape;\nuniform float u_distortion;\nuniform float u_distortionShape;\nuniform float u_shift;\nuniform float u_blur;\nuniform float u_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n\nfloat getUvFrame(vec2 uv) {\n float aax = 2. * fwidth(uv.x);\n float aay = 2. * fwidth(uv.y);\n\n float left = smoothstep(0., aax, uv.x);\n float right = smoothstep(1., 1. - aax, uv.x);\n float bottom = smoothstep(0., aay, uv.y);\n float top = smoothstep(1., 1. - aay, uv.y);\n\n return left * right * bottom * top;\n}\n\nconst int MAX_RADIUS = 50;\n\nvec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {\n if (sigma <= .5) return texture(tex, uv);\n int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));\n\n float twoSigma2 = 2.0 * sigma * sigma;\n float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);\n\n vec4 sum = texture(tex, uv) * gaussianNorm;\n float weightSum = gaussianNorm;\n\n for (int i = 1; i <= MAX_RADIUS; i++) {\n if (i > radius) break;\n\n float x = float(i);\n float w = exp(-(x * x) / twoSigma2) * gaussianNorm;\n\n vec2 offset = dir * texelSize * x;\n vec4 s1 = texture(tex, uv + offset);\n vec4 s2 = texture(tex, uv - offset);\n\n sum += (s1 + s2) * w;\n weightSum += 2.0 * w;\n }\n\n return sum / weightSum;\n}\n\nvoid main() {\n vec2 imageUV = v_imageUV;\n\n vec2 uv = imageUV;\n float frame = getUvFrame(imageUV);\n if (frame < .05) discard;\n\n float effectSize = 1. / pow(.7 * (u_size + .5), 6.);\n\n vec2 sw = vec2(.005 * u_distortion) * vec2(1., u_imageAspectRatio);\n float maskOuter =\n smoothstep(u_marginLeft - sw.x, u_marginLeft, imageUV.x + sw.x) *\n smoothstep(u_marginRight - sw.x, u_marginRight, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop - sw.y, u_marginTop, imageUV.y + sw.y) *\n smoothstep(u_marginBottom - sw.y, u_marginBottom, 1.0 - imageUV.y + sw.y);\n float mask =\n smoothstep(u_marginLeft, u_marginLeft + sw.x, imageUV.x + sw.x) *\n smoothstep(u_marginRight, u_marginRight + sw.x, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop, u_marginTop + sw.y, imageUV.y + sw.y) *\n smoothstep(u_marginBottom, u_marginBottom + sw.y, 1.0 - imageUV.y + sw.y);\n float stroke = (1. - mask) * maskOuter;\n\n float patternRotation = u_angle * PI / 180.;\n uv = rotate(uv - vec2(.5), patternRotation);\n uv *= effectSize;\n\n float curve = 0.;\n if (u_shape > 4.5) {\n // pattern\n curve = .5 + .5 * sin(1.5 * uv.x) * cos(1.5 * uv.y);\n } else if (u_shape > 3.5) {\n // zigzag\n curve = 10. * abs(fract(.1 * uv.y) - .5);\n } else if (u_shape > 2.5) {\n // wave\n curve = 4. * sin(.23 * uv.y);\n } else if (u_shape > 1.5) {\n // lines irregular\n curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);\n } else {\n // lines\n }\n\n vec2 uvOrig = uv;\n uv += curve;\n\n vec2 fractUV = fract(uv);\n vec2 floorUV = floor(uv);\n\n vec2 fractOrigUV = fract(uvOrig);\n vec2 floorOrigUV = floor(uvOrig);\n\n float edges = smoothstep(.85, .95, fractUV.x);\n edges *= mask;\n\n float xDistortion = 0.;\n if (u_distortionShape == 1.) {\n xDistortion = -pow(1.5 * fractUV.x, 3.) + (.5 + u_shift);\n } else if (u_distortionShape == 2.) {\n xDistortion = 2. * pow(fractUV.x, 2.) - (.5 + u_shift);\n } else if (u_distortionShape == 3.) {\n xDistortion = pow(2. * (fractUV.x - .5), 6.) + .5 - .5 + u_shift;\n } else if (u_distortionShape == 4.) {\n xDistortion = sin((fractUV.x + .25 + u_shift) * TWO_PI);\n xDistortion *= .5;\n } else if (u_distortionShape == 5.) {\n xDistortion += (.5 + u_shift);\n xDistortion -= pow(abs(fractUV.x), .2) * fractUV.x;\n xDistortion *= .33;\n }\n\n xDistortion *= 3. * u_distortion;\n\n uv = (floorOrigUV + fractOrigUV) / effectSize;\n uv.x += xDistortion / effectSize;\n uv += pow(stroke, 4.);\n uv.y = mix(uv.y, .0, .4 * u_edges * edges);\n\n uv = rotate(uv, -patternRotation) + vec2(.5);\n\n uv = mix(imageUV, uv, mask);\n float blur = mix(0., u_blur, mask);\n\n vec4 color = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);\n\n float opacity = color.a;\n fragColor = vec4(color.rgb, opacity);\n}\n`;\n\nexport interface FlutedGlassUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string;\n u_size: number;\n u_angle: number;\n u_distortion: number;\n u_shift: number;\n u_blur: number;\n u_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_edges: number;\n u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];\n u_shape: (typeof GlassGridShapes)[GlassGridShape];\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {\n image: HTMLImageElement | string;\n size?: number;\n angle?: number;\n distortion?: number;\n shift?: number;\n blur?: number;\n margin?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n edges?: number;\n distortionShape?: GlassDistortionShape;\n shape?: GlassGridShape;\n}\n\nexport const GlassGridShapes = {\n lines: 1,\n linesIrregular: 2,\n wave: 3,\n zigzag: 4,\n pattern: 5,\n} as const;\n\nexport const GlassDistortionShapes = {\n prism: 1,\n lens: 2,\n contour: 3,\n cascade: 4,\n facete: 5,\n} as const;\n\nexport type GlassDistortionShape = keyof typeof GlassDistortionShapes;\nexport type GlassGridShape = keyof typeof GlassGridShapes;\n"],
|
|
5
|
-
"mappings": ";;;;;AACA,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingUniformsDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, proceduralHash21 } from '../shader-utils.js';\n\n/**\n * Mimicking glass surface distortion over the image by distorting the texture\n * coordinates within line patterns\n *\n * Uniforms:\n * - u_size, u_angle - size and direction of grid relative to the image\n * - u_shape (float used as integer):\n * ---- 1: uniformly spaced stripes\n * ---- 2: randomly spaced stripes\n * ---- 3: sine wave stripes\n * ---- 4: zigzag stripes\n * ---- 5: wave-based pattern\n * - u_distortion - the power of distortion applied along within each stripe\n * - u_distortionShape (float used as integer):\n * ---- 5 shapes available\n * - u_shift - texture shift in direction opposite to the grid\n * - u_blur - one-directional blur applied over the main distortion\n * - u_edges - thin color lines along the grid (independent from distortion)\n * - u_marginLeft, u_marginRight, u_marginTop, u_marginBottom - paddings\n * within picture to be shown without any distortion\n *\n */\n\n// language=GLSL\nexport const flutedGlassFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n${sizingUniformsDeclaration}\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorShadow;\nuniform vec4 u_colorHighlight;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_size;\nuniform float u_shadows;\nuniform float u_angle;\nuniform float u_stretch;\nuniform float u_shape;\nuniform float u_distortion;\nuniform float u_highlights;\nuniform float u_distortionShape;\nuniform float u_shift;\nuniform float u_blur;\nuniform float u_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${proceduralHash21}\n\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = hash21(i);\n float b = hash21(i + vec2(1.0, 0.0));\n float c = hash21(i + vec2(0.0, 1.0));\n float d = hash21(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\n\n\nvec2 getImageUV(vec2 uv, vec2 extraScale) {\n vec2 boxOrigin = vec2(.5 - u_originX, u_originY - .5);\n float r = u_rotation * PI / 180.;\n mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n\n vec2 imageBoxSize;\n if (u_fit == 1.) {\n imageBoxSize.x = min(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;\n } else {\n imageBoxSize.x = max(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;\n }\n imageBoxSize.y = imageBoxSize.x / u_imageAspectRatio;\n vec2 imageBoxScale = u_resolution.xy / imageBoxSize;\n\n vec2 imageUV = uv;\n imageUV *= imageBoxScale;\n imageUV += boxOrigin * (imageBoxScale - 1.);\n imageUV += graphicOffset;\n imageUV /= u_scale;\n imageUV *= extraScale;\n imageUV.x *= u_imageAspectRatio;\n imageUV = graphicRotation * imageUV;\n imageUV.x /= u_imageAspectRatio;\n\n imageUV += .5;\n imageUV.y = 1. - imageUV.y;\n\n return imageUV;\n}\n\nfloat getUvFrame(vec2 uv, float aa) {\n float left = smoothstep(0., aa, uv.x);\n float right = 1. - smoothstep(1. - aa, 1., uv.x);\n float bottom = smoothstep(0., aa, uv.y);\n float top = 1. - smoothstep(1. - aa, 1., uv.y);\n return left * right * bottom * top;\n}\n\nconst int MAX_RADIUS = 50;\nvec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {\n if (sigma <= .5) return texture(tex, uv);\n int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));\n\n float twoSigma2 = 2.0 * sigma * sigma;\n float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);\n\n vec4 sum = texture(tex, uv) * gaussianNorm;\n float weightSum = gaussianNorm;\n\n for (int i = 1; i <= MAX_RADIUS; i++) {\n if (i > radius) break;\n\n float x = float(i);\n float w = exp(-(x * x) / twoSigma2) * gaussianNorm;\n\n vec2 offset = dir * texelSize * x;\n vec4 s1 = texture(tex, uv + offset);\n vec4 s2 = texture(tex, uv - offset);\n\n sum += (s1 + s2) * w;\n weightSum += 2.0 * w;\n }\n return sum / weightSum;\n}\n\nvec2 rotateAspect(vec2 p, float a, float aspect) {\n p.x *= aspect;\n p = rotate(p, a);\n p.x /= aspect;\n return p;\n}\n\nfloat smoothFract(float x) {\n float f = fract(x);\n float w = fwidth(x);\n\n float edge = abs(f - 0.5) - 0.5;\n float band = smoothstep(-w, w, edge);\n\n return mix(f, 1.0 - f, band);\n}\n\nfloat blendOverlay(float base, float blend) {\n return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));\n}\nvec3 blendOverlay(vec3 base, vec3 blend) {\n return vec3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));\n}\nvec3 blendHardLight(vec3 base, vec3 blend) {\n return blendOverlay(blend, base);\n}\nvec3 blendHardLight(vec3 base, vec3 blend, float opacity) {\n return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n\nvoid main() {\n\n vec2 uvNormalised = (gl_FragCoord.xy - .5 * u_resolution) / u_resolution.xy;\n vec2 uvOriginal = getImageUV(uvNormalised, vec2(1.));\n float origFrameBox = getUvFrame(uvOriginal, .01);\n\n float patternRotation = -u_angle * PI / 180.;\n float patternSize = mix(200., 5., u_size);\n\n vec2 uv = uvOriginal;\n\n vec2 uvMask = gl_FragCoord.xy / u_resolution.xy;\n vec2 sw = vec2(.005 * u_distortion);\n vec4 margins = vec4(u_marginLeft, u_marginTop, u_marginRight, u_marginBottom);\n float maskOuter =\n smoothstep(margins[0] - sw.x, margins[0], uvMask.x + sw.x) *\n smoothstep(margins[2] - sw.x, margins[2], 1.0 - uvMask.x + sw.x) *\n smoothstep(margins[1] - sw.y, margins[1], uvMask.y + sw.y) *\n smoothstep(margins[3] - sw.y, margins[3], 1.0 - uvMask.y + sw.y);\n float mask =\n smoothstep(margins[0], margins[0] + sw.x, uvMask.x + sw.x) *\n smoothstep(margins[2], margins[2] + sw.x, 1.0 - uvMask.x + sw.x) *\n smoothstep(margins[1], margins[1] + sw.y, uvMask.y + sw.y) *\n smoothstep(margins[3], margins[3] + sw.y, 1.0 - uvMask.y + sw.y);\n float maskStroke = (1. - mask) * maskOuter;\n float maskStrokeInner = (1. - mask) * smoothstep(.95, 1., maskOuter);\n\n uv -= .5;\n uv *= patternSize;\n uv = rotateAspect(uv, patternRotation, u_imageAspectRatio);\n\n float curve = 0.;\n float patternY = uv.y / u_imageAspectRatio;\n if (u_shape > 4.5) {\n // pattern\n curve = .5 + .5 * sin(.5 * PI * uv.x) * cos(.5 * PI * patternY);\n } else if (u_shape > 3.5) {\n // zigzag\n curve = 10. * abs(fract(.1 * patternY) - .5);\n } else if (u_shape > 2.5) {\n // wave\n curve = 4. * sin(.23 * patternY);\n } else if (u_shape > 1.5) {\n // lines irregular\n curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);\n } else {\n // lines\n }\n\n vec2 UvToFract = uv + curve;\n vec2 fractOrigUV = fract(uv);\n vec2 floorOrigUV = floor(uv);\n\n float x = smoothFract(UvToFract.x);\n float xNonSmooth = fract(UvToFract.x);\n\n float w = 2. * fwidth(UvToFract.x);\n w *= mask;\n w += maskStrokeInner;\n float highlights = smoothstep(0., w, xNonSmooth);\n highlights *= smoothstep(1., 1. - w, xNonSmooth);\n highlights = mix(1., highlights, u_highlights);\n\n float shadows = x;\n float distortion = 0.;\n float fadeX = 1.;\n float frameFade = 0.;\n\n float aa = fwidth(xNonSmooth);\n aa = max(aa, fwidth(uv.x));\n aa = max(aa, fwidth(UvToFract.x));\n\n shadows = pow(x, 2.);\n\n if (u_distortionShape == 1.) {\n distortion = -pow(1.5 * x, 3.);\n distortion += (.5 - u_shift);\n\n frameFade = pow(1.5 * x, 3.);\n aa = max(.2, aa);\n aa += mix(.2, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion = mix(.5, distortion, fadeX);\n } else if (u_distortionShape == 2.) {\n distortion = 2. * pow(x, 2.);\n distortion -= (.5 + u_shift);\n\n frameFade = pow(abs(x - .5), 4.);\n aa = max(.2, aa);\n aa += mix(.2, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion = mix(.5, distortion, fadeX);\n frameFade = mix(1., frameFade, .5 * fadeX);\n } else if (u_distortionShape == 3.) {\n distortion = pow(2. * (xNonSmooth - .5), 6.);\n distortion -= .25;\n distortion -= u_shift;\n\n frameFade = 1. - 2. * pow(abs(x - .4), 2.);\n aa = .15;\n aa += mix(.1, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n frameFade = mix(1., frameFade, fadeX);\n\n } else if (u_distortionShape == 4.) {\n x = xNonSmooth;\n distortion = sin((x + .25) * TWO_PI);\n shadows = .5 + .5 * distortion;\n distortion *= .5;\n distortion -= u_shift;\n frameFade = .5 + .5 * sin(x * TWO_PI);\n } else if (u_distortionShape == 5.) {\n distortion -= pow(abs(x), .2) * x;\n distortion += .33;\n distortion -= 3. * u_shift;\n distortion *= .33;\n\n frameFade = .3 * (smoothstep(.0, 1., x));\n shadows = pow(x, 6.);\n\n aa = max(.1, aa);\n aa += mix(.1, 0., u_size);\n fadeX = smoothstep(0., aa, xNonSmooth) * smoothstep(1., 1. - aa, xNonSmooth);\n distortion *= fadeX;\n }\n\n vec2 dudx = dFdx(uvOriginal);\n vec2 dudy = dFdy(uvOriginal);\n vec2 grainUV = getImageUV(uvNormalised, .8 / vec2(length(dudx), length(dudy)));\n float grain = valueNoise(grainUV);\n grain = smoothstep(.4, .7, grain);\n grain *= u_grainMixer;\n distortion = mix(distortion, 0., grain);\n\n shadows = min(shadows, 1.);\n shadows *= mask;\n shadows += .5 * maskStroke;\n shadows = min(shadows, 1.);\n\n distortion *= 3. * u_distortion;\n frameFade *= u_distortion;\n\n fractOrigUV.x += distortion;\n floorOrigUV = rotateAspect(floorOrigUV, -patternRotation, u_imageAspectRatio);\n fractOrigUV = rotateAspect(fractOrigUV, -patternRotation, u_imageAspectRatio);\n\n uv = (floorOrigUV + fractOrigUV) / patternSize;\n uv += pow(maskStroke, 4.);\n\n uv += vec2(.5);\n\n uv = mix(uvOriginal, uv, mask);\n float blur = mix(0., mix(0., 50., u_blur), mask);\n\n float frameBlur = mix(0., .04, u_blur);\n frameBlur += .03 * frameFade;\n frameBlur *= mask;\n float frame = getUvFrame(uv, frameBlur);\n\n float stretch = 1. - smoothstep(0., .5, xNonSmooth) * smoothstep(1., 1. - .5, xNonSmooth);\n stretch = pow(stretch, 2.);\n stretch *= mask;\n stretch *= getUvFrame(uv, .1 + .05 * mask * frameFade);\n uv.y = mix(uv.y, .5, u_stretch * stretch);\n\n\n vec4 image = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);\n vec4 backColor = u_colorBack;\n backColor.rgb *= backColor.a;\n vec4 highlightColor = u_colorHighlight;\n highlightColor.rgb *= highlightColor.a;\n vec4 shadowColor = u_colorShadow;\n shadowColor.rgb *= shadowColor.a;\n\n vec3 color = mix(backColor.rgb, image.rgb, image.a * frame);\n float opacity = backColor.a + image.a * frame;\n\n shadows *= pow(u_shadows, 2.);\n shadows *= shadowColor.a;\n color = mix(color, shadowColor.rgb, .5 * shadows);\n color += .5 * pow(shadows, .5) * shadowColor.rgb;\n\n opacity += shadows;\n opacity = clamp(opacity, 0., 1.);\n\n color = mix(highlightColor.rgb, color, highlights);\n opacity = mix(highlightColor.a, opacity, highlights);\n\n float grainOverlay = valueNoise(rotate(grainUV, 1.) + vec2(3.));\n grainOverlay = mix(grainOverlay, valueNoise(rotate(grainUV, 2.) + vec2(-1.)), .5);\n grainOverlay = pow(grainOverlay, 2.);\n vec3 grainOverlayColor = vec3(grainOverlay);\n color = mix(color, blendHardLight(color, grainOverlayColor, .5 * u_grainOverlay), mask);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface FlutedGlassUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_colorBack: [number, number, number, number];\n u_colorShadow: [number, number, number, number];\n u_colorHighlight: [number, number, number, number];\n u_shadows: number;\n u_size: number;\n u_angle: number;\n u_distortion: number;\n u_shift: number;\n u_blur: number;\n u_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_stretch: number;\n u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];\n u_highlights: number;\n u_shape: (typeof GlassGridShapes)[GlassGridShape];\n u_grainMixer: number;\n u_grainOverlay: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string;\n colorBack?: string;\n colorShadow?: string;\n colorHighlight?: string;\n shadows?: number;\n size?: number;\n angle?: number;\n distortion?: number;\n shift?: number;\n blur?: number;\n margin?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n stretch?: number;\n distortionShape?: GlassDistortionShape;\n highlights?: number;\n shape?: GlassGridShape;\n grainMixer?: number;\n grainOverlay?: number;\n}\n\nexport const GlassGridShapes = {\n lines: 1,\n linesIrregular: 2,\n wave: 3,\n zigzag: 4,\n pattern: 5,\n} as const;\n\nexport const GlassDistortionShapes = {\n prism: 1,\n lens: 2,\n contour: 3,\n cascade: 4,\n flat: 5,\n} as const;\n\nexport type GlassDistortionShape = keyof typeof GlassDistortionShapes;\nexport type GlassGridShape = keyof typeof GlassGridShapes;\n"],
|
|
5
|
+
"mappings": ";;;;;AACA,SAAS,iCAAqF;AAC9F,SAAS,WAAW,WAAW,wBAAwB;AA0BhD,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/C,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BzB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuWX,MAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,MAAM,wBAAwB;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/shaders/god-rays.js
CHANGED
|
@@ -52,7 +52,7 @@ ${proceduralHash11}
|
|
|
52
52
|
float raysShape(vec2 uv, float r, float freq, float intensity, float radius) {
|
|
53
53
|
float a = atan(uv.y, uv.x);
|
|
54
54
|
vec2 left = vec2(a * freq, r);
|
|
55
|
-
vec2 right = vec2(
|
|
55
|
+
vec2 right = vec2(fract(a / TWO_PI) * TWO_PI * freq, r);
|
|
56
56
|
float n_left = pow(valueNoise(left), intensity);
|
|
57
57
|
float n_right = pow(valueNoise(right), intensity);
|
|
58
58
|
float shape = mix(n_right, n_left, smoothstep(-.15, .15, uv.x));
|
|
@@ -72,7 +72,9 @@ void main() {
|
|
|
72
72
|
float delta = 1. - smoothstep(0., 1., radius);
|
|
73
73
|
|
|
74
74
|
float midSize = 10. * abs(u_midSize);
|
|
75
|
-
float
|
|
75
|
+
float ms_lo = 0.02 * midSize;
|
|
76
|
+
float ms_hi = max(midSize, 1e-6);
|
|
77
|
+
float middleShape = pow(u_midIntensity, 0.3) * (1. - smoothstep(ms_lo, ms_hi, 3.0 * radius));
|
|
76
78
|
middleShape = pow(middleShape, 5.0);
|
|
77
79
|
|
|
78
80
|
vec3 accumColor = vec3(0.0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/god-rays.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, rotation2, textureRandomizerR, colorBandingFix, proceduralHash11 } from '../shader-utils.js';\n\nexport const godRaysMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Radial rays animated from center\n *\n * Uniforms:\n * - u_colorBack, u_colorBloom (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_density: frequency of sector shapes\n * - u_intensity: rays visibility within sectors\n * - u_spotty: density of spots on the ray (higher = more spots)\n * - u_midSize, u_midIntensity: central shape over the rays\n * - u_bloom (0..1): normal to additive blending mix\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n */\n\n// language=GLSL\nexport const godRaysFragmentShader: 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_colorBloom;\nuniform vec4 u_colors[${godRaysMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_density;\nuniform float u_spotty;\nuniform float u_midSize;\nuniform float u_midIntensity;\nuniform float u_intensity;\nuniform float u_bloom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${textureRandomizerR}\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomR(i);\n float b = randomR(i + vec2(1.0, 0.0));\n float c = randomR(i + vec2(0.0, 1.0));\n float d = randomR(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\n\n${proceduralHash11}\n\nfloat raysShape(vec2 uv, float r, float freq, float intensity, float radius) {\n float a = atan(uv.y, uv.x);\n vec2 left = vec2(a * freq, r);\n vec2 right = vec2(
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,oBAAoB,iBAAiB,wBAAwB;AAErF,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAkBO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBASrB,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclB,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,
|
|
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, textureRandomizerR, colorBandingFix, proceduralHash11 } from '../shader-utils.js';\n\nexport const godRaysMeta = {\n maxColorCount: 5,\n} as const;\n\n/**\n * Radial rays animated from center\n *\n * Uniforms:\n * - u_colorBack, u_colorBloom (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_density: frequency of sector shapes\n * - u_intensity: rays visibility within sectors\n * - u_spotty: density of spots on the ray (higher = more spots)\n * - u_midSize, u_midIntensity: central shape over the rays\n * - u_bloom (0..1): normal to additive blending mix\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n */\n\n// language=GLSL\nexport const godRaysFragmentShader: 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_colorBloom;\nuniform vec4 u_colors[${godRaysMeta.maxColorCount}];\nuniform float u_colorsCount;\n\nuniform float u_density;\nuniform float u_spotty;\nuniform float u_midSize;\nuniform float u_midIntensity;\nuniform float u_intensity;\nuniform float u_bloom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${textureRandomizerR}\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomR(i);\n float b = randomR(i + vec2(1.0, 0.0));\n float c = randomR(i + vec2(0.0, 1.0));\n float d = randomR(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\n\n${proceduralHash11}\n\nfloat raysShape(vec2 uv, float r, float freq, float intensity, float radius) {\n float a = atan(uv.y, uv.x);\n vec2 left = vec2(a * freq, r);\n vec2 right = vec2(fract(a / TWO_PI) * TWO_PI * freq, r);\n float n_left = pow(valueNoise(left), intensity);\n float n_right = pow(valueNoise(right), intensity);\n float shape = mix(n_right, n_left, smoothstep(-.15, .15, uv.x));\n return shape;\n}\n\nvoid main() {\n vec2 shape_uv = v_objectUV;\n\n float t = .2 * u_time;\n\n float radius = length(shape_uv);\n float spots = 6.5 * abs(u_spotty);\n\n float intensity = 4. - 3. * clamp(u_intensity, 0., 1.);\n\n float delta = 1. - smoothstep(0., 1., radius);\n\n float midSize = 10. * abs(u_midSize);\n float ms_lo = 0.02 * midSize;\n float ms_hi = max(midSize, 1e-6);\n float middleShape = pow(u_midIntensity, 0.3) * (1. - smoothstep(ms_lo, ms_hi, 3.0 * radius));\n middleShape = pow(middleShape, 5.0);\n\n vec3 accumColor = vec3(0.0);\n float accumAlpha = 0.0;\n\n for (int i = 0; i < ${godRaysMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n vec2 rotatedUV = rotate(shape_uv, float(i) + 1.0);\n\n float r1 = radius * (1.0 + 0.4 * float(i)) - 3.0 * t;\n float r2 = 0.5 * radius * (1.0 + spots) - 2.0 * t;\n float density = 6. * u_density + step(.5, u_density) * pow(4.5 * (u_density - .5), 4.);\n float f = mix(1.0, 3.0 + 0.5 * float(i), hash11(float(i) * 15.)) * density;\n\n float ray = raysShape(rotatedUV, r1, 5.0 * f, intensity, radius);\n ray *= raysShape(rotatedUV, r2, 4.0 * f, intensity, radius);\n ray += (1. + 4. * ray) * middleShape;\n ray = clamp(ray, 0.0, 1.0);\n\n float srcAlpha = u_colors[i].a * ray;\n vec3 srcColor = u_colors[i].rgb * srcAlpha;\n\n vec3 alphaBlendColor = accumColor + (1.0 - accumAlpha) * srcColor;\n float alphaBlendAlpha = accumAlpha + (1.0 - accumAlpha) * srcAlpha;\n\n vec3 addBlendColor = accumColor + srcColor;\n float addBlendAlpha = accumAlpha + srcAlpha;\n\n accumColor = mix(alphaBlendColor, addBlendColor, u_bloom);\n accumAlpha = mix(alphaBlendAlpha, addBlendAlpha, u_bloom);\n }\n\n float overlayAlpha = u_colorBloom.a;\n vec3 overlayColor = u_colorBloom.rgb * overlayAlpha;\n\n vec3 colorWithOverlay = accumColor + accumAlpha * overlayColor;\n accumColor = mix(accumColor, colorWithOverlay, u_bloom);\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n\n vec3 color = accumColor + (1. - accumAlpha) * bgColor;\n float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;\n color = clamp(color, 0., 1.);\n opacity = clamp(opacity, 0., 1.);\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface GodRaysUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colorBloom: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_spotty: number;\n u_midSize: number;\n u_midIntensity: number;\n u_density: number;\n u_intensity: number;\n u_bloom: number;\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface GodRaysParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colorBloom?: string;\n colors?: string[];\n spotty?: number;\n midSize?: number;\n midIntensity?: number;\n density?: number;\n intensity?: number;\n bloom?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,oBAAoB,iBAAiB,wBAAwB;AAErF,MAAM,cAAc;AAAA,EACzB,eAAe;AACjB;AAkBO,MAAM,wBAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBASrB,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclB,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,wBAiCM,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,IAyC7C,eAAe;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -159,7 +159,7 @@ void main() {
|
|
|
159
159
|
float rand = hash11(stripeIdx * 100.);
|
|
160
160
|
rand = sign(rand - .5) * pow(4. * abs(rand), .3);
|
|
161
161
|
shape = sin(shape_uv.x) * cos(shape_uv.y - 5. * rand * t);
|
|
162
|
-
shape = pow(shape, 4.);
|
|
162
|
+
shape = pow(abs(shape), 4.);
|
|
163
163
|
|
|
164
164
|
} else if (u_shape < 3.5) {
|
|
165
165
|
// Truchet pattern
|
|
@@ -175,8 +175,8 @@ void main() {
|
|
|
175
175
|
|
|
176
176
|
n2 -= .5;
|
|
177
177
|
n2 *= .1;
|
|
178
|
-
shape = smoothstep(.2, .55, distance1 + n2) * smoothstep(.
|
|
179
|
-
shape += smoothstep(.2, .55, distance2 + n2) * smoothstep(.
|
|
178
|
+
shape = smoothstep(.2, .55, distance1 + n2) * (1. - smoothstep(.45, .8, distance1 - n2));
|
|
179
|
+
shape += smoothstep(.2, .55, distance2 + n2) * (1. - smoothstep(.45, .8, distance2 - n2));
|
|
180
180
|
|
|
181
181
|
shape = pow(shape, 1.5);
|
|
182
182
|
|
|
@@ -229,7 +229,7 @@ void main() {
|
|
|
229
229
|
|
|
230
230
|
shape_uv *= 2.;
|
|
231
231
|
float d = 1. - pow(length(shape_uv), 2.);
|
|
232
|
-
vec3 pos = vec3(shape_uv, sqrt(d));
|
|
232
|
+
vec3 pos = vec3(shape_uv, sqrt(max(d, 0.)));
|
|
233
233
|
vec3 lightPos = normalize(vec3(cos(1.5 * t), .8, sin(1.25 * t)));
|
|
234
234
|
shape = .5 + .5 * dot(lightPos, pos);
|
|
235
235
|
shape *= step(0., d);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/grain-gradient.ts"],
|
|
4
|
-
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingVariablesDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n sizingDebugVariablesDeclaration,\n} from '../shader-sizing.js';\nimport {\n simplexNoise,\n declarePI,\n rotation2,\n textureRandomizerR,\n proceduralHash21,\n proceduralHash11,\n} from '../shader-utils.js';\n\nexport const grainGradientMeta = {\n maxColorCount: 7,\n} as const;\n\n/**\n * Multi-color gradient with noise & grain over animated abstract shapes\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_softness (0..1): blur between color bands\n * - u_intensity (0..1): distortion between color bands\n * - u_noise (0..1): grainy noise independent of softness\n * - u_shape (float used as integer):\n * ---- 1: single sine wave\n * ---- 2: dots pattern\n * ---- 3: truchet pattern\n * ---- 4: corners (2 rounded rectangles)\n * ---- 5: ripple\n * ---- 6: blob (metaballs)\n * ---- 7: circle imitating 3d look\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n * Note: grains are calculated using gl_FragCoord & u_resolution, meaning grains don't react to scaling and fit\n *\n */\n\n// language=GLSL\nexport const grainGradientFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform mediump float u_time;\nuniform mediump vec2 u_resolution;\nuniform mediump float u_pixelRatio;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${grainGradientMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_softness;\nuniform float u_intensity;\nuniform float u_noise;\nuniform float u_shape;\n\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\n${sizingVariablesDeclaration}\n${ sizingDebugVariablesDeclaration }\n\nout vec4 fragColor;\n\n${declarePI}\n${simplexNoise}\n${rotation2}\n${proceduralHash21}\n${textureRandomizerR}\n\nfloat valueNoiseR(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomR(i);\n float b = randomR(i + vec2(1.0, 0.0));\n float c = randomR(i + vec2(0.0, 1.0));\n float d = randomR(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\nfloat fbmR(vec2 n) {\n float total = 0.;\n float amplitude = .2;\n for (int i = 0; i < 3; i++) {\n n = rotate(n, .3);\n total += valueNoiseR(n) * amplitude;\n n *= 1.99;\n amplitude *= 0.6;\n }\n return total;\n}\n\n${proceduralHash11}\n\nvec2 truchet(vec2 uv, float idx){\n idx = fract(((idx - .5) * 2.));\n if (idx > 0.75) {\n uv = vec2(1.0) - uv;\n } else if (idx > 0.5) {\n uv = vec2(1.0 - uv.x, uv.y);\n } else if (idx > 0.25) {\n uv = 1.0 - vec2(1.0 - uv.x, uv.y);\n }\n return uv;\n}\n\nvoid main() {\n\n const float firstFrameOffset = 7.;\n float t = .1 * (u_time + firstFrameOffset);\n\n vec2 shape_uv = vec2(0.);\n vec2 grain_uv = vec2(0.);\n\n if (u_shape > 3.5) {\n shape_uv = v_objectUV;\n grain_uv = shape_uv;\n\n // apply inverse transform to grain_uv so it respects the originXY\n float r = u_rotation * 3.14159265358979323846 / 180.;\n mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n grain_uv = transpose(graphicRotation) * grain_uv;\n grain_uv *= u_scale;\n grain_uv -= graphicOffset;\n grain_uv *= v_objectBoxSize;\n grain_uv *= .7;\n } else {\n shape_uv = .5 * v_patternUV;\n grain_uv = 100. * v_patternUV;\n\n // apply inverse transform to grain_uv so it respects the originXY\n float r = u_rotation * 3.14159265358979323846 / 180.;\n mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n grain_uv = transpose(graphicRotation) * grain_uv;\n grain_uv *= u_scale;\n if (u_fit > 0.) {\n vec2 givenBoxSize = vec2(u_worldWidth, u_worldHeight);\n givenBoxSize = max(givenBoxSize, vec2(1.)) * u_pixelRatio;\n float patternBoxRatio = givenBoxSize.x / givenBoxSize.y;\n vec2 patternBoxGivenSize = vec2(\n (u_worldWidth == 0.) ? u_resolution.x : givenBoxSize.x,\n (u_worldHeight == 0.) ? u_resolution.y : givenBoxSize.y\n );\n patternBoxRatio = patternBoxGivenSize.x / patternBoxGivenSize.y;\n float patternBoxNoFitBoxWidth = patternBoxRatio * min(patternBoxGivenSize.x / patternBoxRatio, patternBoxGivenSize.y);\n grain_uv /= (patternBoxNoFitBoxWidth / v_patternBoxSize.x);\n }\n vec2 patternBoxScale = u_resolution.xy / v_patternBoxSize;\n grain_uv -= graphicOffset / patternBoxScale;\n grain_uv *= 1.6;\n }\n\n\n float shape = 0.;\n\n if (u_shape < 1.5) {\n // Sine wave\n\n float wave = cos(.5 * shape_uv.x - 4. * t) * sin(1.5 * shape_uv.x + 2. * t) * (.75 + .25 * cos(6. * t));\n shape = 1. - smoothstep(-1., 1., shape_uv.y + wave);\n\n } else if (u_shape < 2.5) {\n // Grid (dots)\n\n float stripeIdx = floor(2. * shape_uv.x / TWO_PI);\n float rand = hash11(stripeIdx * 100.);\n rand = sign(rand - .5) * pow(4. * abs(rand), .3);\n shape = sin(shape_uv.x) * cos(shape_uv.y - 5. * rand * t);\n shape = pow(shape, 4.);\n\n } else if (u_shape < 3.5) {\n // Truchet pattern\n\n float n2 = valueNoiseR(shape_uv * .4 - 3.75 * t);\n shape_uv.x += 10.;\n shape_uv *= .6;\n\n vec2 tile = truchet(fract(shape_uv), randomR(floor(shape_uv)));\n\n float distance1 = length(tile);\n float distance2 = length(tile - vec2(1.));\n\n n2 -= .5;\n n2 *= .1;\n shape = smoothstep(.2, .55, distance1 + n2) * smoothstep(.8, .45, distance1 - n2);\n shape += smoothstep(.2, .55, distance2 + n2) * smoothstep(.8, .45, distance2 - n2);\n\n shape = pow(shape, 1.5);\n\n } else if (u_shape < 4.5) {\n // Corners\n\n shape_uv *= .6;\n vec2 outer = vec2(.5);\n\n vec2 bl = smoothstep(vec2(0.), outer, shape_uv + vec2(.1 + .1 * sin(3. * t), .2 - .1 * sin(5.25 * t)));\n vec2 tr = smoothstep(vec2(0.), outer, 1. - shape_uv);\n shape = 1. - bl.x * bl.y * tr.x * tr.y;\n\n shape_uv = -shape_uv;\n bl = smoothstep(vec2(0.), outer, shape_uv + vec2(.1 + .1 * sin(3. * t), .2 - .1 * cos(5.25 * t)));\n tr = smoothstep(vec2(0.), outer, 1. - shape_uv);\n shape -= bl.x * bl.y * tr.x * tr.y;\n\n shape = 1. - smoothstep(0., 1., shape);\n\n } else if (u_shape < 5.5) {\n // Ripple\n\n shape_uv *= 2.;\n float dist = length(.4 * shape_uv);\n float waves = sin(pow(dist, 1.2) * 5. - 3. * t) * .5 + .5;\n shape = waves;\n\n } else if (u_shape < 6.5) {\n // Blob\n\n t *= 2.;\n\n vec2 f1_traj = .25 * vec2(1.3 * sin(t), .2 + 1.3 * cos(.6 * t + 4.));\n vec2 f2_traj = .2 * vec2(1.2 * sin(-t), 1.3 * sin(1.6 * t));\n vec2 f3_traj = .25 * vec2(1.7 * cos(-.6 * t), cos(-1.6 * t));\n vec2 f4_traj = .3 * vec2(1.4 * cos(.8 * t), 1.2 * sin(-.6 * t - 3.));\n\n shape = .5 * pow(1. - clamp(0., 1., length(shape_uv + f1_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f2_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f3_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f4_traj)), 5.);\n\n shape = smoothstep(.0, .9, shape);\n float edge = smoothstep(.25, .3, shape);\n shape = mix(.0, shape, edge);\n\n } else {\n // Sphere\n\n shape_uv *= 2.;\n float d = 1. - pow(length(shape_uv), 2.);\n vec3 pos = vec3(shape_uv, sqrt(d));\n vec3 lightPos = normalize(vec3(cos(1.5 * t), .8, sin(1.25 * t)));\n shape = .5 + .5 * dot(lightPos, pos);\n shape *= step(0., d);\n }\n\n float simplex = snoise(grain_uv * .5);\n float grainDist = simplex * snoise(grain_uv * .2) - fbmR(.002 * grain_uv + 10.) - fbmR(.003 * grain_uv);\n float rawNoise = .75 * simplex - fbmR(rotate(.4 * grain_uv, 2.)) - fbmR(.001 * grain_uv);\n float noise = clamp(rawNoise, 0., 1.);\n\n shape += u_intensity * 2. / u_colorsCount * (grainDist + .5);\n shape += u_noise * 10. / u_colorsCount * noise;\n\n float aa = fwidth(shape);\n\n shape = clamp(shape - .5 / u_colorsCount, 0., 1.);\n float totalShape = smoothstep(0., u_softness + 2. * aa, clamp(shape * u_colorsCount, 0., 1.));\n float mixer = shape * (u_colorsCount - 1.);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${grainGradientMeta.maxColorCount}; i++) {\n if (i > int(u_colorsCount) - 1) break;\n\n float localT = clamp(mixer - float(i - 1), 0., 1.);\n localT = smoothstep(.5 - .5 * u_softness - aa, .5 + .5 * u_softness + aa, localT);\n\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n vec3 color = gradient.rgb * totalShape;\n float opacity = gradient.a * totalShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface GrainGradientUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_softness: number;\n u_intensity: number;\n u_noise: number;\n u_shape: (typeof GrainGradientShapes)[GrainGradientShape];\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface GrainGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n softness?: number;\n intensity?: number;\n noise?: number;\n shape?: GrainGradientShape;\n}\n\nexport const GrainGradientShapes = {\n wave: 1,\n dots: 2,\n truchet: 3,\n corners: 4,\n ripple: 5,\n blob: 6,\n sphere: 7,\n};\n\nexport type GrainGradientShape = keyof typeof GrainGradientShapes;\n"],
|
|
4
|
+
"sourcesContent": ["import type { vec4 } from '../types.js';\nimport type { ShaderMotionParams } from '../shader-mount.js';\nimport {\n sizingVariablesDeclaration,\n type ShaderSizingParams,\n type ShaderSizingUniforms,\n sizingDebugVariablesDeclaration,\n} from '../shader-sizing.js';\nimport {\n simplexNoise,\n declarePI,\n rotation2,\n textureRandomizerR,\n proceduralHash21,\n proceduralHash11,\n} from '../shader-utils.js';\n\nexport const grainGradientMeta = {\n maxColorCount: 7,\n} as const;\n\n/**\n * Multi-color gradient with noise & grain over animated abstract shapes\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_softness (0..1): blur between color bands\n * - u_intensity (0..1): distortion between color bands\n * - u_noise (0..1): grainy noise independent of softness\n * - u_shape (float used as integer):\n * ---- 1: single sine wave\n * ---- 2: dots pattern\n * ---- 3: truchet pattern\n * ---- 4: corners (2 rounded rectangles)\n * ---- 5: ripple\n * ---- 6: blob (metaballs)\n * ---- 7: circle imitating 3d look\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n * Note: grains are calculated using gl_FragCoord & u_resolution, meaning grains don't react to scaling and fit\n *\n */\n\n// language=GLSL\nexport const grainGradientFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform mediump float u_time;\nuniform mediump vec2 u_resolution;\nuniform mediump float u_pixelRatio;\n\nuniform sampler2D u_noiseTexture;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${grainGradientMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_softness;\nuniform float u_intensity;\nuniform float u_noise;\nuniform float u_shape;\n\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\n${sizingVariablesDeclaration}\n${ sizingDebugVariablesDeclaration }\n\nout vec4 fragColor;\n\n${declarePI}\n${simplexNoise}\n${rotation2}\n${proceduralHash21}\n${textureRandomizerR}\n\nfloat valueNoiseR(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomR(i);\n float b = randomR(i + vec2(1.0, 0.0));\n float c = randomR(i + vec2(0.0, 1.0));\n float d = randomR(i + vec2(1.0, 1.0));\n vec2 u = f * f * (3.0 - 2.0 * f);\n float x1 = mix(a, b, u.x);\n float x2 = mix(c, d, u.x);\n return mix(x1, x2, u.y);\n}\nfloat fbmR(vec2 n) {\n float total = 0.;\n float amplitude = .2;\n for (int i = 0; i < 3; i++) {\n n = rotate(n, .3);\n total += valueNoiseR(n) * amplitude;\n n *= 1.99;\n amplitude *= 0.6;\n }\n return total;\n}\n\n${proceduralHash11}\n\nvec2 truchet(vec2 uv, float idx){\n idx = fract(((idx - .5) * 2.));\n if (idx > 0.75) {\n uv = vec2(1.0) - uv;\n } else if (idx > 0.5) {\n uv = vec2(1.0 - uv.x, uv.y);\n } else if (idx > 0.25) {\n uv = 1.0 - vec2(1.0 - uv.x, uv.y);\n }\n return uv;\n}\n\nvoid main() {\n\n const float firstFrameOffset = 7.;\n float t = .1 * (u_time + firstFrameOffset);\n\n vec2 shape_uv = vec2(0.);\n vec2 grain_uv = vec2(0.);\n\n if (u_shape > 3.5) {\n shape_uv = v_objectUV;\n grain_uv = shape_uv;\n\n // apply inverse transform to grain_uv so it respects the originXY\n float r = u_rotation * 3.14159265358979323846 / 180.;\n mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n grain_uv = transpose(graphicRotation) * grain_uv;\n grain_uv *= u_scale;\n grain_uv -= graphicOffset;\n grain_uv *= v_objectBoxSize;\n grain_uv *= .7;\n } else {\n shape_uv = .5 * v_patternUV;\n grain_uv = 100. * v_patternUV;\n\n // apply inverse transform to grain_uv so it respects the originXY\n float r = u_rotation * 3.14159265358979323846 / 180.;\n mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n grain_uv = transpose(graphicRotation) * grain_uv;\n grain_uv *= u_scale;\n if (u_fit > 0.) {\n vec2 givenBoxSize = vec2(u_worldWidth, u_worldHeight);\n givenBoxSize = max(givenBoxSize, vec2(1.)) * u_pixelRatio;\n float patternBoxRatio = givenBoxSize.x / givenBoxSize.y;\n vec2 patternBoxGivenSize = vec2(\n (u_worldWidth == 0.) ? u_resolution.x : givenBoxSize.x,\n (u_worldHeight == 0.) ? u_resolution.y : givenBoxSize.y\n );\n patternBoxRatio = patternBoxGivenSize.x / patternBoxGivenSize.y;\n float patternBoxNoFitBoxWidth = patternBoxRatio * min(patternBoxGivenSize.x / patternBoxRatio, patternBoxGivenSize.y);\n grain_uv /= (patternBoxNoFitBoxWidth / v_patternBoxSize.x);\n }\n vec2 patternBoxScale = u_resolution.xy / v_patternBoxSize;\n grain_uv -= graphicOffset / patternBoxScale;\n grain_uv *= 1.6;\n }\n\n\n float shape = 0.;\n\n if (u_shape < 1.5) {\n // Sine wave\n\n float wave = cos(.5 * shape_uv.x - 4. * t) * sin(1.5 * shape_uv.x + 2. * t) * (.75 + .25 * cos(6. * t));\n shape = 1. - smoothstep(-1., 1., shape_uv.y + wave);\n\n } else if (u_shape < 2.5) {\n // Grid (dots)\n\n float stripeIdx = floor(2. * shape_uv.x / TWO_PI);\n float rand = hash11(stripeIdx * 100.);\n rand = sign(rand - .5) * pow(4. * abs(rand), .3);\n shape = sin(shape_uv.x) * cos(shape_uv.y - 5. * rand * t);\n shape = pow(abs(shape), 4.);\n\n } else if (u_shape < 3.5) {\n // Truchet pattern\n\n float n2 = valueNoiseR(shape_uv * .4 - 3.75 * t);\n shape_uv.x += 10.;\n shape_uv *= .6;\n\n vec2 tile = truchet(fract(shape_uv), randomR(floor(shape_uv)));\n\n float distance1 = length(tile);\n float distance2 = length(tile - vec2(1.));\n\n n2 -= .5;\n n2 *= .1;\n shape = smoothstep(.2, .55, distance1 + n2) * (1. - smoothstep(.45, .8, distance1 - n2));\n shape += smoothstep(.2, .55, distance2 + n2) * (1. - smoothstep(.45, .8, distance2 - n2));\n\n shape = pow(shape, 1.5);\n\n } else if (u_shape < 4.5) {\n // Corners\n\n shape_uv *= .6;\n vec2 outer = vec2(.5);\n\n vec2 bl = smoothstep(vec2(0.), outer, shape_uv + vec2(.1 + .1 * sin(3. * t), .2 - .1 * sin(5.25 * t)));\n vec2 tr = smoothstep(vec2(0.), outer, 1. - shape_uv);\n shape = 1. - bl.x * bl.y * tr.x * tr.y;\n\n shape_uv = -shape_uv;\n bl = smoothstep(vec2(0.), outer, shape_uv + vec2(.1 + .1 * sin(3. * t), .2 - .1 * cos(5.25 * t)));\n tr = smoothstep(vec2(0.), outer, 1. - shape_uv);\n shape -= bl.x * bl.y * tr.x * tr.y;\n\n shape = 1. - smoothstep(0., 1., shape);\n\n } else if (u_shape < 5.5) {\n // Ripple\n\n shape_uv *= 2.;\n float dist = length(.4 * shape_uv);\n float waves = sin(pow(dist, 1.2) * 5. - 3. * t) * .5 + .5;\n shape = waves;\n\n } else if (u_shape < 6.5) {\n // Blob\n\n t *= 2.;\n\n vec2 f1_traj = .25 * vec2(1.3 * sin(t), .2 + 1.3 * cos(.6 * t + 4.));\n vec2 f2_traj = .2 * vec2(1.2 * sin(-t), 1.3 * sin(1.6 * t));\n vec2 f3_traj = .25 * vec2(1.7 * cos(-.6 * t), cos(-1.6 * t));\n vec2 f4_traj = .3 * vec2(1.4 * cos(.8 * t), 1.2 * sin(-.6 * t - 3.));\n\n shape = .5 * pow(1. - clamp(0., 1., length(shape_uv + f1_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f2_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f3_traj)), 5.);\n shape += .5 * pow(1. - clamp(0., 1., length(shape_uv + f4_traj)), 5.);\n\n shape = smoothstep(.0, .9, shape);\n float edge = smoothstep(.25, .3, shape);\n shape = mix(.0, shape, edge);\n\n } else {\n // Sphere\n\n shape_uv *= 2.;\n float d = 1. - pow(length(shape_uv), 2.);\n vec3 pos = vec3(shape_uv, sqrt(max(d, 0.)));\n vec3 lightPos = normalize(vec3(cos(1.5 * t), .8, sin(1.25 * t)));\n shape = .5 + .5 * dot(lightPos, pos);\n shape *= step(0., d);\n }\n\n float simplex = snoise(grain_uv * .5);\n float grainDist = simplex * snoise(grain_uv * .2) - fbmR(.002 * grain_uv + 10.) - fbmR(.003 * grain_uv);\n float rawNoise = .75 * simplex - fbmR(rotate(.4 * grain_uv, 2.)) - fbmR(.001 * grain_uv);\n float noise = clamp(rawNoise, 0., 1.);\n\n shape += u_intensity * 2. / u_colorsCount * (grainDist + .5);\n shape += u_noise * 10. / u_colorsCount * noise;\n\n float aa = fwidth(shape);\n\n shape = clamp(shape - .5 / u_colorsCount, 0., 1.);\n float totalShape = smoothstep(0., u_softness + 2. * aa, clamp(shape * u_colorsCount, 0., 1.));\n float mixer = shape * (u_colorsCount - 1.);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${grainGradientMeta.maxColorCount}; i++) {\n if (i > int(u_colorsCount) - 1) break;\n\n float localT = clamp(mixer - float(i - 1), 0., 1.);\n localT = smoothstep(.5 - .5 * u_softness - aa, .5 + .5 * u_softness + aa, localT);\n\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localT);\n }\n\n vec3 color = gradient.rgb * totalShape;\n float opacity = gradient.a * totalShape;\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n color = color + bgColor * (1.0 - opacity);\n opacity = opacity + u_colorBack.a * (1.0 - opacity);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface GrainGradientUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_softness: number;\n u_intensity: number;\n u_noise: number;\n u_shape: (typeof GrainGradientShapes)[GrainGradientShape];\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface GrainGradientParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n softness?: number;\n intensity?: number;\n noise?: number;\n shape?: GrainGradientShape;\n}\n\nexport const GrainGradientShapes = {\n wave: 1,\n dots: 2,\n truchet: 3,\n corners: 4,\n ripple: 5,\n blob: 6,\n sphere: 7,\n};\n\nexport type GrainGradientShape = keyof typeof GrainGradientShapes;\n"],
|
|
5
5
|
"mappings": ";;;;;AAEA;AAAA,EACE;AAAA,EAGA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AACjB;AA2BO,MAAM,8BAAsC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAU3B,kBAAkB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBrD,0BAA0B;AAAA,EACzB,+BAAgC;AAAA;AAAA;AAAA;AAAA,EAIjC,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,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,EA0BlB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBA0KM,kBAAkB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0ChD,MAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AACV;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|