@paper-design/shaders 0.0.38 → 0.0.40
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 +3 -24
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +2 -2
- package/dist/shader-mount.d.ts +2 -2
- package/dist/shader-mount.js +26 -11
- package/dist/shader-mount.js.map +2 -2
- package/dist/shader-utils.d.ts +1 -0
- package/dist/shader-utils.js +38 -0
- package/dist/shader-utils.js.map +2 -2
- package/dist/shaders/color-panels.d.ts +3 -0
- package/dist/shaders/color-panels.js +29 -16
- package/dist/shaders/color-panels.js.map +2 -2
- package/dist/shaders/dot-grid.js +3 -2
- package/dist/shaders/dot-grid.js.map +2 -2
- package/dist/shaders/dot-orbit.js +1 -2
- package/dist/shaders/dot-orbit.js.map +2 -2
- package/dist/shaders/grain-gradient.js +5 -5
- package/dist/shaders/grain-gradient.js.map +1 -1
- package/dist/shaders/liquid-metal.js +11 -11
- package/dist/shaders/liquid-metal.js.map +1 -1
- package/dist/shaders/mesh-gradient.js +1 -6
- package/dist/shaders/mesh-gradient.js.map +2 -2
- package/dist/shaders/neuro-noise.js +1 -2
- package/dist/shaders/neuro-noise.js.map +2 -2
- package/dist/shaders/perlin-noise.js +2 -2
- package/dist/shaders/perlin-noise.js.map +1 -1
- package/dist/shaders/pulsing-border.d.ts +8 -7
- package/dist/shaders/pulsing-border.js +119 -103
- package/dist/shaders/pulsing-border.js.map +2 -2
- package/dist/shaders/simplex-noise.js +13 -17
- package/dist/shaders/simplex-noise.js.map +2 -2
- package/dist/shaders/spiral.d.ts +3 -3
- package/dist/shaders/spiral.js +27 -30
- package/dist/shaders/spiral.js.map +2 -2
- package/dist/shaders/static-mesh-gradient.d.ts +43 -0
- package/dist/shaders/static-mesh-gradient.js +114 -0
- package/dist/shaders/static-mesh-gradient.js.map +7 -0
- package/dist/shaders/static-radial-gradient.d.ts +51 -0
- package/dist/shaders/static-radial-gradient.js +155 -0
- package/dist/shaders/static-radial-gradient.js.map +7 -0
- package/dist/shaders/swirl.d.ts +3 -3
- package/dist/shaders/swirl.js +18 -17
- package/dist/shaders/swirl.js.map +2 -2
- package/dist/shaders/voronoi.js +2 -2
- package/dist/shaders/voronoi.js.map +1 -1
- package/dist/shaders/warp.js +16 -11
- package/dist/shaders/warp.js.map +2 -2
- package/dist/shaders/waves.js +6 -10
- package/dist/shaders/waves.js.map +2 -2
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import type { ShaderMotionParams } from '../shader-mount.js';
|
|
|
3
3
|
import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';
|
|
4
4
|
export declare const pulsingBorderMeta: {
|
|
5
5
|
readonly maxColorCount: 5;
|
|
6
|
-
readonly
|
|
6
|
+
readonly maxSpots: 4;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Color spots traveling around rectangular stroke (border)
|
|
@@ -12,13 +12,13 @@ export declare const pulsingBorderMeta: {
|
|
|
12
12
|
* - u_colorBack (RGBA)
|
|
13
13
|
* - u_colors (vec4[]), u_colorsCount (float used as integer)
|
|
14
14
|
* - u_roundness, u_thickness, u_softness: border parameters
|
|
15
|
-
* - u_intensity:
|
|
15
|
+
* - u_intensity: thickness of individual spots
|
|
16
|
+
* - u_bloom: normal / additive color blending
|
|
16
17
|
* - u_spotSize: angular size of spots
|
|
17
|
-
* -
|
|
18
|
+
* - u_spots (float used as int): number of spots rendered per color
|
|
18
19
|
* - u_pulse: optional pulsing animation
|
|
19
20
|
* - u_smoke, u_smokeSize: optional noisy shapes around the border
|
|
20
21
|
*
|
|
21
|
-
* - u_pulseTexture (sampler2D): pulsing signal source
|
|
22
22
|
* - u_noiseTexture (sampler2D): pre-computed randomizer source
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
@@ -31,12 +31,12 @@ export interface PulsingBorderUniforms extends ShaderSizingUniforms {
|
|
|
31
31
|
u_thickness: number;
|
|
32
32
|
u_softness: number;
|
|
33
33
|
u_intensity: number;
|
|
34
|
-
|
|
34
|
+
u_bloom: number;
|
|
35
|
+
u_spots: number;
|
|
35
36
|
u_spotSize: number;
|
|
36
37
|
u_pulse: number;
|
|
37
38
|
u_smoke: number;
|
|
38
39
|
u_smokeSize: number;
|
|
39
|
-
u_pulseTexture?: HTMLImageElement;
|
|
40
40
|
}
|
|
41
41
|
export interface PulsingBorderParams extends ShaderSizingParams, ShaderMotionParams {
|
|
42
42
|
colorBack?: string;
|
|
@@ -45,7 +45,8 @@ export interface PulsingBorderParams extends ShaderSizingParams, ShaderMotionPar
|
|
|
45
45
|
thickness?: number;
|
|
46
46
|
softness?: number;
|
|
47
47
|
intensity?: number;
|
|
48
|
-
|
|
48
|
+
bloom?: number;
|
|
49
|
+
spots?: number;
|
|
49
50
|
spotSize?: number;
|
|
50
51
|
pulse?: number;
|
|
51
52
|
smoke?: number;
|
|
@@ -7,7 +7,7 @@ import { sizingVariablesDeclaration } from "../shader-sizing.js";
|
|
|
7
7
|
import { declarePI, declareValueNoise, colorBandingFix } from "../shader-utils.js";
|
|
8
8
|
const pulsingBorderMeta = {
|
|
9
9
|
maxColorCount: 5,
|
|
10
|
-
|
|
10
|
+
maxSpots: 4
|
|
11
11
|
};
|
|
12
12
|
const pulsingBorderFragmentShader = `#version 300 es
|
|
13
13
|
precision lowp float;
|
|
@@ -21,13 +21,13 @@ uniform float u_roundness;
|
|
|
21
21
|
uniform float u_thickness;
|
|
22
22
|
uniform float u_softness;
|
|
23
23
|
uniform float u_intensity;
|
|
24
|
+
uniform float u_bloom;
|
|
24
25
|
uniform float u_spotSize;
|
|
25
|
-
uniform float
|
|
26
|
+
uniform float u_spots;
|
|
26
27
|
uniform float u_pulse;
|
|
27
28
|
uniform float u_smoke;
|
|
28
29
|
uniform float u_smokeSize;
|
|
29
30
|
|
|
30
|
-
uniform sampler2D u_pulseTexture;
|
|
31
31
|
uniform sampler2D u_noiseTexture;
|
|
32
32
|
|
|
33
33
|
${sizingVariablesDeclaration}
|
|
@@ -36,60 +36,27 @@ out vec4 fragColor;
|
|
|
36
36
|
|
|
37
37
|
${declarePI}
|
|
38
38
|
|
|
39
|
-
float
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
float border = 1. - smoothstep(-.5 * edgeSoftness, .5 * edgeSoftness, borderDistance);
|
|
43
|
-
border *= border;
|
|
44
|
-
|
|
45
|
-
vec2 v0 = uv + halfSize;
|
|
46
|
-
vec2 v1 = uv - vec2(-halfSize.x, halfSize.y);
|
|
47
|
-
vec2 v2 = uv - vec2(halfSize.x, -halfSize.y);
|
|
48
|
-
vec2 v3 = uv - halfSize;
|
|
49
|
-
|
|
50
|
-
float mult = (.07 - .25 * radius);
|
|
51
|
-
float m0 = mult * clamp(pow(1. - abs(v0.x - v0.y), 20.), 0., 1.);
|
|
52
|
-
float m1 = mult * clamp(pow(1. - abs(v1.x + v1.y), 20.), 0., 1.);
|
|
53
|
-
float m2 = mult * clamp(pow(1. - abs(v2.x + v2.y), 20.), 0., 1.);
|
|
54
|
-
float m3 = mult * clamp(pow(1. - abs(v3.x - v3.y), 20.), 0., 1.);
|
|
55
|
-
|
|
56
|
-
float l = edgeSoftness * .5 + .75 * u_thickness;
|
|
57
|
-
float fade0 = 1. - clamp(length(v0) / l, 0., 1.);
|
|
58
|
-
float fade1 = 1. - clamp(length(v1) / l, 0., 1.);
|
|
59
|
-
float fade2 = 1. - clamp(length(v2) / l, 0., 1.);
|
|
60
|
-
float fade3 = 1. - clamp(length(v3) / l, 0., 1.);
|
|
61
|
-
|
|
62
|
-
m0 *= fade0;
|
|
63
|
-
m1 *= fade1;
|
|
64
|
-
m2 *= fade2;
|
|
65
|
-
m3 *= fade3;
|
|
66
|
-
|
|
67
|
-
float fillFix = m0 + m1 + m2 + m3;
|
|
68
|
-
fillFix *= step(distance, 0.);
|
|
69
|
-
fillFix *= (1. + 3. * u_thickness);
|
|
70
|
-
fillFix *= (1.5 - .5 * smoothstep(0., .5, edgeSoftness));
|
|
71
|
-
fillFix = clamp(fillFix, 0., 1.);
|
|
72
|
-
|
|
73
|
-
return border + fillFix;
|
|
74
|
-
}
|
|
39
|
+
float beat(float time) {
|
|
40
|
+
float first = pow(sin(time * TWO_PI), 10.);
|
|
41
|
+
float second = pow(sin((time - 0.15) * TWO_PI), 10.);
|
|
75
42
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
float border = 1. - smoothstep(-.75 * size, .75 * size, borderDistance);
|
|
79
|
-
border *= border;
|
|
43
|
+
return clamp(first + 0.6 * second, 0.0, 1.0);
|
|
44
|
+
}
|
|
80
45
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
46
|
+
float roundedBox(vec2 uv, float distance) {
|
|
47
|
+
float thickness = .5 * u_thickness;
|
|
48
|
+
float borderDistance = abs(distance);
|
|
49
|
+
float border = 1. - smoothstep(-u_softness * thickness - 2. * fwidth(borderDistance), .5 * u_softness * thickness, borderDistance - .5 * thickness);
|
|
50
|
+
border = pow(border, 2.);
|
|
85
51
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
mask *= smoothstep(0., 1., length(v1) / l_mask);
|
|
89
|
-
mask *= smoothstep(0., 1., length(v2) / l_mask);
|
|
90
|
-
mask *= smoothstep(0., 1., length(v3) / l_mask);
|
|
52
|
+
return border;
|
|
53
|
+
}
|
|
91
54
|
|
|
92
|
-
|
|
55
|
+
float roundedBoxSmoke(vec2 uv, float distance, float size) {
|
|
56
|
+
float borderDistance = abs(distance);
|
|
57
|
+
float border = 1. - smoothstep(-.75 * size, .75 * size, borderDistance);
|
|
58
|
+
border *= border;
|
|
59
|
+
return border;
|
|
93
60
|
}
|
|
94
61
|
|
|
95
62
|
float random(vec2 p) {
|
|
@@ -103,22 +70,19 @@ vec2 rand2(vec2 p) {
|
|
|
103
70
|
|
|
104
71
|
${declareValueNoise}
|
|
105
72
|
|
|
106
|
-
float
|
|
107
|
-
|
|
108
|
-
float wrappedTime = mod(time, dur);
|
|
109
|
-
float normalizedTime = wrappedTime / dur;
|
|
110
|
-
float value = texture(u_pulseTexture, vec2(normalizedTime, 0.5)).r;
|
|
111
|
-
return value * 2. - 1.;
|
|
73
|
+
float linearstep(float edge0, float edge1, float x) {
|
|
74
|
+
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
112
75
|
}
|
|
113
76
|
|
|
114
77
|
void main() {
|
|
115
78
|
|
|
116
|
-
float t = .
|
|
79
|
+
float t = 1.2 * u_time;
|
|
117
80
|
|
|
118
81
|
vec2 borderUV = v_responsiveUV;
|
|
119
82
|
|
|
120
83
|
float angle = atan(borderUV.y, borderUV.x) / TWO_PI;
|
|
121
84
|
|
|
85
|
+
float pulse = u_pulse * beat(.18 * u_time);
|
|
122
86
|
|
|
123
87
|
float borderRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;
|
|
124
88
|
borderUV.x *= borderRatio;
|
|
@@ -130,80 +94,132 @@ void main() {
|
|
|
130
94
|
float insideDistance = min(max(d.x, d.y), 0.0);
|
|
131
95
|
float distance = outsideDistance + insideDistance;
|
|
132
96
|
|
|
133
|
-
float border = roundedBox(borderUV,
|
|
134
|
-
|
|
135
|
-
|
|
97
|
+
float border = roundedBox(borderUV, distance);
|
|
98
|
+
|
|
99
|
+
vec2 v0 = borderUV + halfSize;
|
|
100
|
+
vec2 v1 = borderUV - vec2(-halfSize.x, halfSize.y);
|
|
101
|
+
vec2 v2 = borderUV - vec2(halfSize.x, -halfSize.y);
|
|
102
|
+
vec2 v3 = borderUV - halfSize;
|
|
103
|
+
|
|
104
|
+
float cornerFade = 1. - abs(v0.x - v0.y);
|
|
105
|
+
cornerFade = max(cornerFade, 1. - abs(v1.x + v1.y));
|
|
106
|
+
cornerFade = max(cornerFade, 1. - abs(v2.x + v2.y));
|
|
107
|
+
cornerFade = max(cornerFade, 1. - abs(v3.x - v3.y));
|
|
108
|
+
cornerFade = .75 * pow(cornerFade, 20.);
|
|
109
|
+
|
|
110
|
+
float cornerFadeMask = 0.;
|
|
111
|
+
float maskR = (.35 * u_thickness - .25 * radius);
|
|
112
|
+
float maskHL = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, borderUV.x);
|
|
113
|
+
float maskHR = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, -borderUV.x);
|
|
114
|
+
float maskVT = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, -borderUV.y);
|
|
115
|
+
float maskVB = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, borderUV.y);
|
|
116
|
+
float maskOffset = .25 * (u_thickness + radius);
|
|
117
|
+
{
|
|
118
|
+
float m = maskHR;
|
|
119
|
+
m *= maskVT;
|
|
120
|
+
m *= (1. - clamp(length((v0 - maskOffset) / maskR), 0., 1.));
|
|
121
|
+
cornerFadeMask += m;
|
|
122
|
+
}
|
|
123
|
+
{
|
|
124
|
+
float m = maskHR;
|
|
125
|
+
m *= maskVB;
|
|
126
|
+
m *= (1. - clamp(length((v1 - vec2(1., -1.) * maskOffset) / maskR), 0., 1.));
|
|
127
|
+
cornerFadeMask += m;
|
|
128
|
+
}
|
|
129
|
+
{
|
|
130
|
+
float m = maskHL;
|
|
131
|
+
m *= maskVT;
|
|
132
|
+
m *= (1. - clamp(length((v2 - vec2(-1., 1.) * maskOffset) / maskR), 0., 1.));
|
|
133
|
+
cornerFadeMask += m;
|
|
134
|
+
}
|
|
135
|
+
{
|
|
136
|
+
float m = maskHL;
|
|
137
|
+
m *= maskVB;
|
|
138
|
+
m *= (1. - clamp(length((v3 + maskOffset) / maskR), 0., 1.));
|
|
139
|
+
cornerFadeMask += m;
|
|
140
|
+
}
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
border
|
|
142
|
+
cornerFade *= cornerFadeMask;
|
|
143
|
+
border += cornerFade;
|
|
139
144
|
|
|
140
|
-
vec2 smokeUV = .
|
|
145
|
+
vec2 smokeUV = .2 * u_smokeSize * v_patternUV;
|
|
141
146
|
float smoke = clamp(3. * valueNoise(2.7 * smokeUV + .5 * t), 0., 1.);
|
|
142
147
|
smoke -= valueNoise(3.4 * smokeUV - .5 * t);
|
|
143
|
-
smoke *= roundedBoxSmoke(borderUV,
|
|
144
|
-
smoke =
|
|
148
|
+
smoke *= roundedBoxSmoke(borderUV, distance, u_smoke);
|
|
149
|
+
smoke = 30. * pow(smoke, 2.);
|
|
150
|
+
smoke += cornerFadeMask;
|
|
145
151
|
smoke *= u_smoke;
|
|
146
|
-
smoke *= (
|
|
152
|
+
smoke *= mix(1., pulse, u_pulse);
|
|
147
153
|
smoke = clamp(smoke, 0., 1.);
|
|
148
154
|
|
|
149
155
|
border += smoke;
|
|
156
|
+
border = clamp(border, 0., 1.);
|
|
157
|
+
|
|
158
|
+
vec3 blendColor = vec3(0.);
|
|
159
|
+
float blendAlpha = 0.0;
|
|
160
|
+
vec3 addColor = vec3(0.);
|
|
161
|
+
float addAlpha = 0.0;
|
|
162
|
+
|
|
163
|
+
float bloom = 4. * u_bloom;
|
|
164
|
+
float intensity = 1. + 4. * u_intensity;
|
|
150
165
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
float opacity = 0.;
|
|
166
|
+
for (int colorIdx = 0; colorIdx < ${pulsingBorderMeta.maxColorCount}; colorIdx++) {
|
|
167
|
+
if (colorIdx >= int(u_colorsCount)) break;
|
|
168
|
+
float colorIdxF = float(colorIdx);
|
|
155
169
|
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
vec3 c = u_colors[colorIdx].rgb * u_colors[colorIdx].a;
|
|
171
|
+
float a = u_colors[colorIdx].a;
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
for (int spotIdx = 0; spotIdx < ${pulsingBorderMeta.maxSpots}; spotIdx++) {
|
|
174
|
+
if (spotIdx >= int(u_spots)) break;
|
|
175
|
+
float spotIdxF = float(spotIdx);
|
|
162
176
|
|
|
163
|
-
|
|
164
|
-
if (j >= int(u_colorsCount)) break;
|
|
165
|
-
float colorIdx = float(j);
|
|
177
|
+
vec2 randVal = rand2(vec2(spotIdxF * 10. + 2., 40. + colorIdxF));
|
|
166
178
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
float time = (.1 + .15 * abs(sin(idx * (2. + colorIdx)) * cos(idx * (2. + 2.5 * colorIdx)))) * t + randVal.x * 3.;
|
|
179
|
+
float time = (.1 + .15 * abs(sin(spotIdxF * (2. + colorIdxF)) * cos(spotIdxF * (2. + 2.5 * colorIdxF)))) * t + randVal.x * 3.;
|
|
170
180
|
time *= mix(1., -1., step(.5, randVal.y));
|
|
171
181
|
|
|
172
|
-
float mask = .
|
|
173
|
-
sin(t +
|
|
174
|
-
cos(t +
|
|
175
|
-
step(mod(
|
|
182
|
+
float mask = .5 + .5 * mix(
|
|
183
|
+
sin(t + spotIdxF * (5. - 1.5 * colorIdxF)),
|
|
184
|
+
cos(t + spotIdxF * (3. + 1.3 * colorIdxF)),
|
|
185
|
+
step(mod(colorIdxF, 2.), .5)
|
|
176
186
|
);
|
|
177
187
|
|
|
178
|
-
|
|
179
|
-
|
|
188
|
+
float p = clamp(2. * u_pulse - randVal.x, 0., 1.);
|
|
189
|
+
mask = mix(mask, pulse, p);
|
|
180
190
|
|
|
181
191
|
float atg1 = fract(angle + time);
|
|
182
|
-
float
|
|
183
|
-
|
|
192
|
+
float spotSize = .05 + .6 * pow(u_spotSize, 2.) + .05 * randVal.x;
|
|
193
|
+
spotSize = mix(spotSize, .1, p);
|
|
194
|
+
float sector = smoothstep(.5 - spotSize, .5, atg1) * smoothstep(.5 + spotSize, .5, atg1);
|
|
195
|
+
|
|
184
196
|
sector *= mask;
|
|
197
|
+
sector *= border;
|
|
198
|
+
sector *= intensity;
|
|
185
199
|
sector = clamp(sector, 0., 1.);
|
|
186
200
|
|
|
187
|
-
|
|
201
|
+
vec3 srcColor = c * sector;
|
|
202
|
+
float srcAlpha = a * sector;
|
|
188
203
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
blendColor += ((1. - blendAlpha) * srcColor);
|
|
205
|
+
blendAlpha = blendAlpha + (1. - blendAlpha) * srcAlpha;
|
|
206
|
+
addColor += srcColor;
|
|
207
|
+
addAlpha += srcAlpha;
|
|
192
208
|
}
|
|
193
209
|
}
|
|
194
210
|
|
|
195
|
-
|
|
196
|
-
|
|
211
|
+
vec3 accumColor = mix(blendColor, addColor, bloom);
|
|
212
|
+
float accumAlpha = mix(blendAlpha, addAlpha, bloom);
|
|
213
|
+
accumAlpha = clamp(accumAlpha, 0., 1.);
|
|
197
214
|
|
|
198
215
|
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
199
|
-
color =
|
|
200
|
-
opacity =
|
|
201
|
-
|
|
216
|
+
vec3 color = accumColor + (1. - accumAlpha) * bgColor;
|
|
217
|
+
float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;
|
|
218
|
+
|
|
202
219
|
${colorBandingFix}
|
|
203
220
|
|
|
204
221
|
fragColor = vec4(color, opacity);
|
|
205
|
-
}
|
|
206
|
-
`;
|
|
222
|
+
}`;
|
|
207
223
|
export {
|
|
208
224
|
pulsingBorderFragmentShader,
|
|
209
225
|
pulsingBorderMeta
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/pulsing-border.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, declareValueNoise, colorBandingFix } from '../shader-utils.js';\n\nexport const pulsingBorderMeta = {\n maxColorCount: 5,\n
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,mBAAmB,uBAAuB;AAEvD,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AAAA,EACf,
|
|
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, declareValueNoise, colorBandingFix } from '../shader-utils.js';\n\nexport const pulsingBorderMeta = {\n maxColorCount: 5,\n maxSpots: 4,\n} as const;\n\n/**\n * Color spots traveling around rectangular stroke (border)\n *\n * Uniforms:\n * - u_colorBack (RGBA)\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_roundness, u_thickness, u_softness: border parameters\n * - u_intensity: thickness of individual spots\n * - u_bloom: normal / additive color blending\n * - u_spotSize: angular size of spots\n * - u_spots (float used as int): number of spots rendered per color\n * - u_pulse: optional pulsing animation\n * - u_smoke, u_smokeSize: optional noisy shapes around the border\n *\n * - u_noiseTexture (sampler2D): pre-computed randomizer source\n *\n */\n\n// language=GLSL\nexport const pulsingBorderFragmentShader: string = `#version 300 es\nprecision lowp float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colors[${pulsingBorderMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_roundness;\nuniform float u_thickness;\nuniform float u_softness;\nuniform float u_intensity;\nuniform float u_bloom;\nuniform float u_spotSize;\nuniform float u_spots;\nuniform float u_pulse;\nuniform float u_smoke;\nuniform float u_smokeSize;\n\nuniform sampler2D u_noiseTexture;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n\nfloat beat(float time) {\n float first = pow(sin(time * TWO_PI), 10.);\n float second = pow(sin((time - 0.15) * TWO_PI), 10.);\n\n return clamp(first + 0.6 * second, 0.0, 1.0);\n}\n\nfloat roundedBox(vec2 uv, float distance) {\n float thickness = .5 * u_thickness;\n float borderDistance = abs(distance);\n float border = 1. - smoothstep(-u_softness * thickness - 2. * fwidth(borderDistance), .5 * u_softness * thickness, borderDistance - .5 * thickness);\n border = pow(border, 2.);\n\n return border;\n}\n\nfloat roundedBoxSmoke(vec2 uv, float distance, float size) {\n float borderDistance = abs(distance);\n float border = 1. - smoothstep(-.75 * size, .75 * size, borderDistance);\n border *= border;\n return border;\n}\n\nfloat random(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).g;\n}\nvec2 rand2(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, uv).gb;\n}\n\n${declareValueNoise}\n\nfloat linearstep(float edge0, float edge1, float x) {\n return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n}\n\nvoid main() {\n\n float t = 1.2 * u_time;\n\n vec2 borderUV = v_responsiveUV;\n\n float angle = atan(borderUV.y, borderUV.x) / TWO_PI;\n\n float pulse = u_pulse * beat(.18 * u_time);\n\n float borderRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\n borderUV.x *= borderRatio;\n vec2 halfSize = vec2(.5);\n halfSize.x *= borderRatio;\n float radius = min(.5 * u_roundness, halfSize.x);\n vec2 d = abs(borderUV) - halfSize + radius;\n float outsideDistance = length(max(d, 0.)) - radius;\n float insideDistance = min(max(d.x, d.y), 0.0);\n float distance = outsideDistance + insideDistance;\n\n float border = roundedBox(borderUV, distance);\n \n vec2 v0 = borderUV + halfSize;\n vec2 v1 = borderUV - vec2(-halfSize.x, halfSize.y);\n vec2 v2 = borderUV - vec2(halfSize.x, -halfSize.y);\n vec2 v3 = borderUV - halfSize;\n \n float cornerFade = 1. - abs(v0.x - v0.y);\n cornerFade = max(cornerFade, 1. - abs(v1.x + v1.y));\n cornerFade = max(cornerFade, 1. - abs(v2.x + v2.y));\n cornerFade = max(cornerFade, 1. - abs(v3.x - v3.y));\n cornerFade = .75 * pow(cornerFade, 20.);\n\n float cornerFadeMask = 0.;\n float maskR = (.35 * u_thickness - .25 * radius);\n float maskHL = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, borderUV.x);\n float maskHR = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, -borderUV.x);\n float maskVT = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, -borderUV.y);\n float maskVB = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, borderUV.y);\n float maskOffset = .25 * (u_thickness + radius);\n {\n float m = maskHR;\n m *= maskVT;\n m *= (1. - clamp(length((v0 - maskOffset) / maskR), 0., 1.));\n cornerFadeMask += m;\n }\n {\n float m = maskHR;\n m *= maskVB;\n m *= (1. - clamp(length((v1 - vec2(1., -1.) * maskOffset) / maskR), 0., 1.));\n cornerFadeMask += m;\n }\n {\n float m = maskHL;\n m *= maskVT;\n m *= (1. - clamp(length((v2 - vec2(-1., 1.) * maskOffset) / maskR), 0., 1.));\n cornerFadeMask += m;\n }\n {\n float m = maskHL;\n m *= maskVB;\n m *= (1. - clamp(length((v3 + maskOffset) / maskR), 0., 1.));\n cornerFadeMask += m;\n }\n\n cornerFade *= cornerFadeMask;\n border += cornerFade;\n\n vec2 smokeUV = .2 * u_smokeSize * v_patternUV;\n float smoke = clamp(3. * valueNoise(2.7 * smokeUV + .5 * t), 0., 1.);\n smoke -= valueNoise(3.4 * smokeUV - .5 * t);\n smoke *= roundedBoxSmoke(borderUV, distance, u_smoke);\n smoke = 30. * pow(smoke, 2.);\n smoke += cornerFadeMask;\n smoke *= u_smoke;\n smoke *= mix(1., pulse, u_pulse);\n smoke = clamp(smoke, 0., 1.);\n\n border += smoke;\n border = clamp(border, 0., 1.);\n \n vec3 blendColor = vec3(0.);\n float blendAlpha = 0.0;\n vec3 addColor = vec3(0.);\n float addAlpha = 0.0;\n \n float bloom = 4. * u_bloom;\n float intensity = 1. + 4. * u_intensity;\n\n for (int colorIdx = 0; colorIdx < ${pulsingBorderMeta.maxColorCount}; colorIdx++) {\n if (colorIdx >= int(u_colorsCount)) break;\n float colorIdxF = float(colorIdx);\n\n vec3 c = u_colors[colorIdx].rgb * u_colors[colorIdx].a;\n float a = u_colors[colorIdx].a;\n\n for (int spotIdx = 0; spotIdx < ${pulsingBorderMeta.maxSpots}; spotIdx++) {\n if (spotIdx >= int(u_spots)) break;\n float spotIdxF = float(spotIdx);\n\n vec2 randVal = rand2(vec2(spotIdxF * 10. + 2., 40. + colorIdxF));\n\n float time = (.1 + .15 * abs(sin(spotIdxF * (2. + colorIdxF)) * cos(spotIdxF * (2. + 2.5 * colorIdxF)))) * t + randVal.x * 3.;\n time *= mix(1., -1., step(.5, randVal.y));\n\n float mask = .5 + .5 * mix(\n sin(t + spotIdxF * (5. - 1.5 * colorIdxF)),\n cos(t + spotIdxF * (3. + 1.3 * colorIdxF)),\n step(mod(colorIdxF, 2.), .5)\n );\n\n float p = clamp(2. * u_pulse - randVal.x, 0., 1.);\n mask = mix(mask, pulse, p);\n\n float atg1 = fract(angle + time);\n float spotSize = .05 + .6 * pow(u_spotSize, 2.) + .05 * randVal.x;\n spotSize = mix(spotSize, .1, p);\n float sector = smoothstep(.5 - spotSize, .5, atg1) * smoothstep(.5 + spotSize, .5, atg1);\n \n sector *= mask;\n sector *= border;\n sector *= intensity;\n sector = clamp(sector, 0., 1.);\n\n vec3 srcColor = c * sector;\n float srcAlpha = a * sector;\n\n blendColor += ((1. - blendAlpha) * srcColor);\n blendAlpha = blendAlpha + (1. - blendAlpha) * srcAlpha;\n addColor += srcColor;\n addAlpha += srcAlpha;\n }\n }\n\n vec3 accumColor = mix(blendColor, addColor, bloom);\n float accumAlpha = mix(blendAlpha, addAlpha, bloom);\n accumAlpha = clamp(accumAlpha, 0., 1.);\n\n vec3 bgColor = u_colorBack.rgb * u_colorBack.a;\n vec3 color = accumColor + (1. - accumAlpha) * bgColor;\n float opacity = accumAlpha + (1. - accumAlpha) * u_colorBack.a;\n \n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}`;\n\nexport interface PulsingBorderUniforms extends ShaderSizingUniforms {\n u_colorBack: [number, number, number, number];\n u_colors: vec4[];\n u_colorsCount: number;\n u_roundness: number;\n u_thickness: number;\n u_softness: number;\n u_intensity: number;\n u_bloom: number;\n u_spots: number;\n u_spotSize: number;\n u_pulse: number;\n u_smoke: number;\n u_smokeSize: number;\n}\n\nexport interface PulsingBorderParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n roundness?: number;\n thickness?: number;\n softness?: number;\n intensity?: number;\n bloom?: number;\n spots?: number;\n spotSize?: number;\n pulse?: number;\n smoke?: number;\n smokeSize?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,mBAAmB,uBAAuB;AAEvD,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AAAA,EACf,UAAU;AACZ;AAqBO,MAAM,8BAAsC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAM3B,kBAAkB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAerD,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,EAkCT,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCA+FmB,kBAAkB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAO/B,kBAAkB,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,IA8C5D,eAAe;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -32,20 +32,16 @@ float getNoise(vec2 uv, float t) {
|
|
|
32
32
|
return noise;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
float steppedSmooth(float
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
float smoothed = smoothstep(.5 - softness * .5 - fw, .5 + softness * .5 + fw, f);
|
|
41
|
-
|
|
42
|
-
return stepT + smoothed / steps;
|
|
35
|
+
float steppedSmooth(float m, float steps, float softness) {
|
|
36
|
+
float stepT = floor(m * steps) / steps;
|
|
37
|
+
float f = m * steps - floor(m * steps);
|
|
38
|
+
float smoothed = smoothstep(.5 - softness, .5 + softness, f);
|
|
39
|
+
return stepT + smoothed / steps;
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
void main() {
|
|
46
43
|
vec2 shape_uv = v_patternUV;
|
|
47
|
-
|
|
48
|
-
shape_uv *= .001;
|
|
44
|
+
shape_uv *= .1;
|
|
49
45
|
|
|
50
46
|
float t = .2 * u_time;
|
|
51
47
|
|
|
@@ -65,26 +61,26 @@ void main() {
|
|
|
65
61
|
for (int i = 1; i < ${simplexNoiseMeta.maxColorCount}; i++) {
|
|
66
62
|
if (i >= int(u_colorsCount)) break;
|
|
67
63
|
|
|
68
|
-
float
|
|
69
|
-
|
|
64
|
+
float localM = clamp(mixer - float(i - 1), 0., 1.);
|
|
65
|
+
localM = steppedSmooth(localM, steps, .5 * u_softness + steps * fwidth(localM));
|
|
70
66
|
|
|
71
67
|
vec4 c = u_colors[i];
|
|
72
68
|
c.rgb *= c.a;
|
|
73
|
-
gradient = mix(gradient, c,
|
|
69
|
+
gradient = mix(gradient, c, localM);
|
|
74
70
|
}
|
|
75
71
|
|
|
76
72
|
if (u_extraSides == true) {
|
|
77
73
|
if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {
|
|
78
|
-
float
|
|
74
|
+
float localM = mixer + 1.;
|
|
79
75
|
if (mixer > (u_colorsCount - 1.)) {
|
|
80
|
-
|
|
76
|
+
localM = mixer - (u_colorsCount - 1.);
|
|
81
77
|
}
|
|
82
|
-
|
|
78
|
+
localM = steppedSmooth(localM, steps, .5 * u_softness + steps * fwidth(localM));
|
|
83
79
|
vec4 cFst = u_colors[0];
|
|
84
80
|
cFst.rgb *= cFst.a;
|
|
85
81
|
vec4 cLast = u_colors[int(u_colorsCount - 1.)];
|
|
86
82
|
cLast.rgb *= cLast.a;
|
|
87
|
-
gradient = mix(cLast, cFst,
|
|
83
|
+
gradient = mix(cLast, cFst, localM);
|
|
88
84
|
}
|
|
89
85
|
}
|
|
90
86
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/simplex-noise.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 { declareSimplexNoise, colorBandingFix } from '../shader-utils.js';\n\nexport const simplexNoiseMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Color Gradient mapped over a combination of 2 Simplex noises\n *\n * Uniforms:\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_stepsPerColor (float, used as int): discrete color steps between u_colors\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n *\n * */\n\n// language=GLSL\nexport const simplexNoiseFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform float u_scale;\n\nuniform vec4 u_colors[${simplexNoiseMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_stepsPerColor;\nuniform float u_softness;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declareSimplexNoise}\n\nfloat getNoise(vec2 uv, float t) {\n float noise = .5 * snoise(uv - vec2(0., .3 * t));\n noise += .5 * snoise(2. * uv + vec2(0., .32 * t));\n\n return noise;\n}\n\nfloat steppedSmooth(float
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,uBAAuB;AAE9C,MAAM,mBAAmB;AAAA,EAC9B,eAAe;AACjB;AAaO,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAM1B,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpD,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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 { declareSimplexNoise, colorBandingFix } from '../shader-utils.js';\n\nexport const simplexNoiseMeta = {\n maxColorCount: 10,\n} as const;\n\n/**\n * Color Gradient mapped over a combination of 2 Simplex noises\n *\n * Uniforms:\n * - u_colors (vec4[]), u_colorsCount (float used as integer)\n * - u_stepsPerColor (float, used as int): discrete color steps between u_colors\n * - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)\n *\n * */\n\n// language=GLSL\nexport const simplexNoiseFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform float u_scale;\n\nuniform vec4 u_colors[${simplexNoiseMeta.maxColorCount}];\nuniform float u_colorsCount;\nuniform float u_stepsPerColor;\nuniform float u_softness;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declareSimplexNoise}\n\nfloat getNoise(vec2 uv, float t) {\n float noise = .5 * snoise(uv - vec2(0., .3 * t));\n noise += .5 * snoise(2. * uv + vec2(0., .32 * t));\n\n return noise;\n}\n\nfloat steppedSmooth(float m, float steps, float softness) { \n float stepT = floor(m * steps) / steps;\n float f = m * steps - floor(m * steps);\n float smoothed = smoothstep(.5 - softness, .5 + softness, f);\n return stepT + smoothed / steps;\n}\n\nvoid main() {\n vec2 shape_uv = v_patternUV;\n shape_uv *= .1;\n\n float t = .2 * u_time;\n\n float shape = .5 + .5 * getNoise(shape_uv, t);\n\n bool u_extraSides = true;\n\n float mixer = shape * (u_colorsCount - 1.);\n if (u_extraSides == true) {\n mixer = (shape - .5 / u_colorsCount) * u_colorsCount;\n }\n\n float steps = max(1., u_stepsPerColor);\n\n vec4 gradient = u_colors[0];\n gradient.rgb *= gradient.a;\n for (int i = 1; i < ${simplexNoiseMeta.maxColorCount}; i++) {\n if (i >= int(u_colorsCount)) break;\n\n float localM = clamp(mixer - float(i - 1), 0., 1.);\n localM = steppedSmooth(localM, steps, .5 * u_softness + steps * fwidth(localM));\n\n vec4 c = u_colors[i];\n c.rgb *= c.a;\n gradient = mix(gradient, c, localM);\n }\n\n if (u_extraSides == true) {\n if ((mixer < 0.) || (mixer > (u_colorsCount - 1.))) {\n float localM = mixer + 1.;\n if (mixer > (u_colorsCount - 1.)) {\n localM = mixer - (u_colorsCount - 1.);\n }\n localM = steppedSmooth(localM, steps, .5 * u_softness + steps * fwidth(localM));\n vec4 cFst = u_colors[0];\n cFst.rgb *= cFst.a;\n vec4 cLast = u_colors[int(u_colorsCount - 1.)];\n cLast.rgb *= cLast.a;\n gradient = mix(cLast, cFst, localM);\n }\n }\n\n vec3 color = gradient.rgb;\n float opacity = gradient.a;\n\n ${colorBandingFix}\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface SimplexNoiseUniforms extends ShaderSizingUniforms {\n u_colors: vec4[];\n u_colorsCount: number;\n u_stepsPerColor: number;\n u_softness: number;\n}\n\nexport interface SimplexNoiseParams extends ShaderSizingParams, ShaderMotionParams {\n colors?: string[];\n stepsPerColor?: number;\n softness?: number;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,qBAAqB,uBAAuB;AAE9C,MAAM,mBAAmB;AAAA,EAC9B,eAAe;AACjB;AAaO,MAAM,6BAAqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAM1B,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpD,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAmCG,iBAAiB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA6BlD,eAAe;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/shaders/spiral.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-si
|
|
|
10
10
|
* - u_strokeTaper: stroke loosing width further from center (0 for full visibility)
|
|
11
11
|
* - u_distortion: per-arch shift
|
|
12
12
|
* - u_strokeCap: extra width at the center (no effect on u_strokeWidth = 0.5)
|
|
13
|
-
* - u_noiseFrequency,
|
|
13
|
+
* - u_noiseFrequency, u_noise: simplex noise distortion over the shape
|
|
14
14
|
* - u_softness: color transition sharpness (0 = hard edge, 1 = smooth fade)
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
@@ -23,8 +23,8 @@ export interface SpiralUniforms extends ShaderSizingUniforms {
|
|
|
23
23
|
u_strokeWidth: number;
|
|
24
24
|
u_strokeTaper: number;
|
|
25
25
|
u_strokeCap: number;
|
|
26
|
+
u_noise: number;
|
|
26
27
|
u_noiseFrequency: number;
|
|
27
|
-
u_noisePower: number;
|
|
28
28
|
u_softness: number;
|
|
29
29
|
}
|
|
30
30
|
export interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {
|
|
@@ -35,7 +35,7 @@ export interface SpiralParams extends ShaderSizingParams, ShaderMotionParams {
|
|
|
35
35
|
strokeWidth?: number;
|
|
36
36
|
strokeTaper?: number;
|
|
37
37
|
strokeCap?: number;
|
|
38
|
+
noise?: number;
|
|
38
39
|
noiseFrequency?: number;
|
|
39
|
-
noisePower?: number;
|
|
40
40
|
softness?: number;
|
|
41
41
|
}
|
package/dist/shaders/spiral.js
CHANGED
|
@@ -17,9 +17,8 @@ uniform float u_distortion;
|
|
|
17
17
|
uniform float u_strokeWidth;
|
|
18
18
|
uniform float u_strokeCap;
|
|
19
19
|
uniform float u_strokeTaper;
|
|
20
|
-
|
|
20
|
+
uniform float u_noise;
|
|
21
21
|
uniform float u_noiseFrequency;
|
|
22
|
-
uniform float u_noisePower;
|
|
23
22
|
uniform float u_softness;
|
|
24
23
|
|
|
25
24
|
${sizingVariablesDeclaration}
|
|
@@ -30,48 +29,46 @@ ${declarePI}
|
|
|
30
29
|
${declareSimplexNoise}
|
|
31
30
|
|
|
32
31
|
void main() {
|
|
33
|
-
vec2
|
|
34
|
-
|
|
32
|
+
vec2 uv = 2. * v_patternUV;
|
|
33
|
+
|
|
35
34
|
float t = u_time;
|
|
35
|
+
float l = length(uv);
|
|
36
|
+
float density = clamp(u_density, 0., 1.);
|
|
37
|
+
l = pow(l, density);
|
|
38
|
+
float angle = atan(uv.y, uv.x) - t;
|
|
39
|
+
float angleNormalised = angle / TWO_PI;
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
float angle = atan(shape_uv.y, shape_uv.x) - 2. * t;
|
|
39
|
-
float angle_norm = angle / TWO_PI;
|
|
40
|
-
|
|
41
|
-
angle_norm += .125 * u_noisePower * snoise(.5 * u_noiseFrequency * shape_uv);
|
|
42
|
-
|
|
43
|
-
float offset = pow(l, 1. - clamp(u_density, 0., 1.)) + angle_norm;
|
|
44
|
-
|
|
45
|
-
float stripe_map = fract(offset);
|
|
46
|
-
stripe_map -= .5 * u_strokeTaper * l;
|
|
47
|
-
|
|
48
|
-
stripe_map += .25 * u_noisePower * snoise(u_noiseFrequency * shape_uv);
|
|
49
|
-
|
|
50
|
-
float shape = 2. * abs(stripe_map - .5);
|
|
51
|
-
float test = step(.5, stripe_map);
|
|
41
|
+
angleNormalised += .125 * u_noise * snoise(16. * pow(u_noiseFrequency, 3.) * uv);
|
|
52
42
|
|
|
53
|
-
|
|
43
|
+
float offset = l + angleNormalised;
|
|
44
|
+
offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t));
|
|
45
|
+
float stripe = fract(offset);
|
|
46
|
+
|
|
47
|
+
float shape = 2. * abs(stripe - .5);
|
|
48
|
+
float width = clamp(u_strokeWidth, .005 * u_strokeTaper, 1.);
|
|
54
49
|
|
|
55
|
-
float stroke_width = clamp(u_strokeWidth, fwidth(l), 1. - fwidth(l));
|
|
56
50
|
|
|
57
|
-
float
|
|
51
|
+
float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.)));
|
|
52
|
+
width = mix(width, wCap, u_strokeCap);
|
|
53
|
+
width *= (1. - clamp(u_strokeTaper, 0., 1.) * l);
|
|
58
54
|
|
|
59
|
-
float
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
float fw = fwidth(offset);
|
|
56
|
+
float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth)));
|
|
57
|
+
float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.));
|
|
58
|
+
pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.)));
|
|
62
59
|
|
|
63
|
-
float res = smoothstep(
|
|
60
|
+
float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape);
|
|
64
61
|
|
|
65
62
|
vec3 fgColor = u_colorFront.rgb * u_colorFront.a;
|
|
66
63
|
float fgOpacity = u_colorFront.a;
|
|
67
64
|
vec3 bgColor = u_colorBack.rgb * u_colorBack.a;
|
|
68
65
|
float bgOpacity = u_colorBack.a;
|
|
69
66
|
|
|
70
|
-
vec3 color =
|
|
71
|
-
float opacity =
|
|
67
|
+
vec3 color = fgColor * res;
|
|
68
|
+
float opacity = fgOpacity * res;
|
|
72
69
|
|
|
73
|
-
color +=
|
|
74
|
-
opacity +=
|
|
70
|
+
color += bgColor * (1. - opacity);
|
|
71
|
+
opacity += bgOpacity * (1. - opacity);
|
|
75
72
|
|
|
76
73
|
${colorBandingFix}
|
|
77
74
|
|