@paper-design/shaders 0.0.54 → 0.0.56
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/get-shader-noise-texture.js +1 -1
- package/dist/get-shader-noise-texture.js.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +2 -2
- package/dist/shader-mount.d.ts +3 -3
- package/dist/shader-mount.js +5 -3
- package/dist/shader-mount.js.map +2 -2
- package/dist/shaders/dithering.d.ts +1 -1
- package/dist/shaders/dithering.js.map +1 -1
- package/dist/shaders/fluted-glass.d.ts +3 -2
- package/dist/shaders/fluted-glass.js +4 -4
- package/dist/shaders/fluted-glass.js.map +2 -2
- package/dist/shaders/heatmap.d.ts +2 -2
- package/dist/shaders/heatmap.js +3 -3
- package/dist/shaders/heatmap.js.map +1 -1
- package/dist/shaders/image-dithering.d.ts +3 -3
- package/dist/shaders/image-dithering.js +1 -1
- package/dist/shaders/image-dithering.js.map +1 -1
- package/dist/shaders/paper-texture.d.ts +13 -13
- package/dist/shaders/paper-texture.js +26 -16
- package/dist/shaders/paper-texture.js.map +2 -2
- package/dist/shaders/pulsing-border.d.ts +17 -0
- package/dist/shaders/pulsing-border.js +82 -83
- package/dist/shaders/pulsing-border.js.map +2 -2
- package/dist/shaders/water.d.ts +1 -1
- package/dist/shaders/water.js +10 -10
- package/dist/shaders/water.js.map +1 -1
- package/package.json +1 -1
|
@@ -19,6 +19,11 @@ uniform vec4 u_colors[${pulsingBorderMeta.maxColorCount}];
|
|
|
19
19
|
uniform float u_colorsCount;
|
|
20
20
|
uniform float u_roundness;
|
|
21
21
|
uniform float u_thickness;
|
|
22
|
+
uniform float u_marginLeft;
|
|
23
|
+
uniform float u_marginRight;
|
|
24
|
+
uniform float u_marginTop;
|
|
25
|
+
uniform float u_marginBottom;
|
|
26
|
+
uniform float u_aspectRatio;
|
|
22
27
|
uniform float u_softness;
|
|
23
28
|
uniform float u_intensity;
|
|
24
29
|
uniform float u_bloom;
|
|
@@ -43,19 +48,23 @@ float beat(float time) {
|
|
|
43
48
|
return clamp(first + 0.6 * second, 0.0, 1.0);
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
float
|
|
47
|
-
|
|
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.);
|
|
51
|
-
|
|
52
|
-
return border;
|
|
51
|
+
float sst(float edge0, float edge1, float x) {
|
|
52
|
+
return smoothstep(edge0, edge1, x);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
float
|
|
55
|
+
float roundedBox(vec2 uv, vec2 halfSize, float distance, float cornerDistance, float thickness, float softness) {
|
|
56
56
|
float borderDistance = abs(distance);
|
|
57
|
-
float
|
|
58
|
-
border
|
|
57
|
+
float aa = 2. * fwidth(distance);
|
|
58
|
+
float border = 1. - sst(mix(thickness, -thickness, softness), thickness + aa, borderDistance);
|
|
59
|
+
float cornerFadeCircles = 0.;
|
|
60
|
+
cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv + halfSize) / thickness)));
|
|
61
|
+
cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(-halfSize.x, halfSize.y)) / thickness)));
|
|
62
|
+
cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(halfSize.x, -halfSize.y)) / thickness)));
|
|
63
|
+
cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - halfSize) / thickness)));
|
|
64
|
+
aa = fwidth(cornerDistance);
|
|
65
|
+
float cornerFade = sst(0., mix(aa, thickness, softness), cornerDistance);
|
|
66
|
+
cornerFade *= cornerFadeCircles;
|
|
67
|
+
border += cornerFade;
|
|
59
68
|
return border;
|
|
60
69
|
}
|
|
61
70
|
|
|
@@ -78,101 +87,86 @@ float valueNoise(vec2 st) {
|
|
|
78
87
|
return mix(x1, x2, u.y);
|
|
79
88
|
}
|
|
80
89
|
|
|
81
|
-
float linearstep(float edge0, float edge1, float x) {
|
|
82
|
-
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
90
|
void main() {
|
|
86
|
-
|
|
87
|
-
const float firstFrameOffset = 4.;
|
|
91
|
+
const float firstFrameOffset = 109.;
|
|
88
92
|
float t = 1.2 * (u_time + firstFrameOffset);
|
|
89
93
|
|
|
90
94
|
vec2 borderUV = v_responsiveUV;
|
|
91
|
-
|
|
92
|
-
float angle = atan(borderUV.y, borderUV.x) / TWO_PI;
|
|
93
|
-
|
|
94
95
|
float pulse = u_pulse * beat(.18 * u_time);
|
|
95
96
|
|
|
96
|
-
float
|
|
97
|
-
borderUV.x *= borderRatio;
|
|
97
|
+
float canvasRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;
|
|
98
98
|
vec2 halfSize = vec2(.5);
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
borderUV.x *= max(canvasRatio, 1.);
|
|
100
|
+
borderUV.y /= min(canvasRatio, 1.);
|
|
101
|
+
halfSize.x *= max(canvasRatio, 1.);
|
|
102
|
+
halfSize.y /= min(canvasRatio, 1.);
|
|
103
|
+
|
|
104
|
+
float mL = u_marginLeft;
|
|
105
|
+
float mR = u_marginRight;
|
|
106
|
+
float mT = u_marginTop;
|
|
107
|
+
float mB = u_marginBottom;
|
|
108
|
+
float mX = mL + mR;
|
|
109
|
+
float mY = mT + mB;
|
|
110
|
+
|
|
111
|
+
if (u_aspectRatio > 0.) {
|
|
112
|
+
float shapeRatio = canvasRatio * (1. - mX) / (1. - mY);
|
|
113
|
+
float freeX = shapeRatio > 1. ? (1. - mX) * (1. - 1. / shapeRatio) : 0.;
|
|
114
|
+
float freeY = shapeRatio < 1. ? (1. - mY) * (1. - shapeRatio) : 0.;
|
|
115
|
+
mL += freeX * 0.5;
|
|
116
|
+
mR += freeX * 0.5;
|
|
117
|
+
mT += freeY * 0.5;
|
|
118
|
+
mB += freeY * 0.5;
|
|
119
|
+
mX = mL + mR;
|
|
120
|
+
mY = mT + mB;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
float thickness = .5 * u_thickness * min(halfSize.x, halfSize.y);
|
|
124
|
+
|
|
125
|
+
halfSize.x *= (1. - mX);
|
|
126
|
+
halfSize.y *= (1. - mY);
|
|
127
|
+
|
|
128
|
+
vec2 centerShift = vec2(
|
|
129
|
+
(mL - mR) * max(canvasRatio, 1.) * 0.5,
|
|
130
|
+
(mB - mT) / min(canvasRatio, 1.) * 0.5
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
borderUV -= centerShift;
|
|
134
|
+
halfSize -= mix(thickness, 0., u_softness);
|
|
135
|
+
|
|
136
|
+
float radius = mix(0., min(halfSize.x, halfSize.y), u_roundness);
|
|
101
137
|
vec2 d = abs(borderUV) - halfSize + radius;
|
|
102
|
-
float outsideDistance = length(max(d,
|
|
103
|
-
float insideDistance = min(max(d.x, d.y),
|
|
138
|
+
float outsideDistance = length(max(d, .0001)) - radius;
|
|
139
|
+
float insideDistance = min(max(d.x, d.y), .0001);
|
|
140
|
+
float cornerDistance = abs(min(max(d.x, d.y) - .45 * radius, .0));
|
|
104
141
|
float distance = outsideDistance + insideDistance;
|
|
105
142
|
|
|
106
|
-
float
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
vec2 v1 = borderUV - vec2(-halfSize.x, halfSize.y);
|
|
110
|
-
vec2 v2 = borderUV - vec2(halfSize.x, -halfSize.y);
|
|
111
|
-
vec2 v3 = borderUV - halfSize;
|
|
112
|
-
|
|
113
|
-
float cornerFade = 1. - abs(v0.x - v0.y);
|
|
114
|
-
cornerFade = max(cornerFade, 1. - abs(v1.x + v1.y));
|
|
115
|
-
cornerFade = max(cornerFade, 1. - abs(v2.x + v2.y));
|
|
116
|
-
cornerFade = max(cornerFade, 1. - abs(v3.x - v3.y));
|
|
117
|
-
cornerFade = .75 * pow(cornerFade, 20.);
|
|
118
|
-
|
|
119
|
-
float cornerFadeMask = 0.;
|
|
120
|
-
float maskR = (.35 * u_thickness - .25 * radius);
|
|
121
|
-
float maskHL = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, borderUV.x);
|
|
122
|
-
float maskHR = linearstep(halfSize.x - .25 * u_thickness, halfSize.x, -borderUV.x);
|
|
123
|
-
float maskVT = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, -borderUV.y);
|
|
124
|
-
float maskVB = linearstep(halfSize.y - .25 * u_thickness, halfSize.y, borderUV.y);
|
|
125
|
-
float maskOffset = .25 * (u_thickness + radius);
|
|
126
|
-
{
|
|
127
|
-
float m = maskHR;
|
|
128
|
-
m *= maskVT;
|
|
129
|
-
m *= (1. - clamp(length((v0 - maskOffset) / maskR), 0., 1.));
|
|
130
|
-
cornerFadeMask += m;
|
|
131
|
-
}
|
|
132
|
-
{
|
|
133
|
-
float m = maskHR;
|
|
134
|
-
m *= maskVB;
|
|
135
|
-
m *= (1. - clamp(length((v1 - vec2(1., -1.) * maskOffset) / maskR), 0., 1.));
|
|
136
|
-
cornerFadeMask += m;
|
|
137
|
-
}
|
|
138
|
-
{
|
|
139
|
-
float m = maskHL;
|
|
140
|
-
m *= maskVT;
|
|
141
|
-
m *= (1. - clamp(length((v2 - vec2(-1., 1.) * maskOffset) / maskR), 0., 1.));
|
|
142
|
-
cornerFadeMask += m;
|
|
143
|
-
}
|
|
144
|
-
{
|
|
145
|
-
float m = maskHL;
|
|
146
|
-
m *= maskVB;
|
|
147
|
-
m *= (1. - clamp(length((v3 + maskOffset) / maskR), 0., 1.));
|
|
148
|
-
cornerFadeMask += m;
|
|
149
|
-
}
|
|
150
|
-
cornerFade = clamp(cornerFade, 0., 1.);
|
|
151
|
-
cornerFade *= cornerFadeMask;
|
|
152
|
-
border += cornerFade;
|
|
143
|
+
float borderThickness = mix(thickness, 3. * thickness, u_softness);
|
|
144
|
+
float border = roundedBox(borderUV, halfSize, distance, cornerDistance, borderThickness, u_softness);
|
|
145
|
+
border = pow(border, 1. + u_softness);
|
|
153
146
|
|
|
154
|
-
vec2 smokeUV = .
|
|
147
|
+
vec2 smokeUV = .3 * u_smokeSize * v_patternUV;
|
|
155
148
|
float smoke = clamp(3. * valueNoise(2.7 * smokeUV + .5 * t), 0., 1.);
|
|
156
149
|
smoke -= valueNoise(3.4 * smokeUV - .5 * t);
|
|
157
|
-
|
|
150
|
+
float smokeThickness = thickness + .2;
|
|
151
|
+
smokeThickness = min(.4, max(smokeThickness, .1));
|
|
152
|
+
smoke *= roundedBox(borderUV, halfSize, distance, cornerDistance, smokeThickness, 1.);
|
|
158
153
|
smoke = 30. * pow(smoke, 2.);
|
|
159
|
-
smoke
|
|
160
|
-
smoke *= u_smoke;
|
|
154
|
+
smoke *= mix(0., .5, pow(u_smoke, 2.));
|
|
161
155
|
smoke *= mix(1., pulse, u_pulse);
|
|
162
156
|
smoke = clamp(smoke, 0., 1.);
|
|
163
|
-
|
|
164
157
|
border += smoke;
|
|
165
|
-
|
|
166
|
-
border *= borderBounds;
|
|
158
|
+
|
|
167
159
|
border = clamp(border, 0., 1.);
|
|
168
160
|
|
|
169
161
|
vec3 blendColor = vec3(0.);
|
|
170
|
-
float blendAlpha = 0
|
|
162
|
+
float blendAlpha = 0.;
|
|
171
163
|
vec3 addColor = vec3(0.);
|
|
172
|
-
float addAlpha = 0
|
|
164
|
+
float addAlpha = 0.;
|
|
173
165
|
|
|
174
166
|
float bloom = 4. * u_bloom;
|
|
175
|
-
float intensity = 1. + 4. * u_intensity;
|
|
167
|
+
float intensity = 1. + (1. + 4. * u_softness) * u_intensity;
|
|
168
|
+
|
|
169
|
+
float angle = atan(borderUV.y, borderUV.x) / TWO_PI;
|
|
176
170
|
|
|
177
171
|
for (int colorIdx = 0; colorIdx < ${pulsingBorderMeta.maxColorCount}; colorIdx++) {
|
|
178
172
|
if (colorIdx >= int(u_colorsCount)) break;
|
|
@@ -202,7 +196,7 @@ void main() {
|
|
|
202
196
|
float atg1 = fract(angle + time);
|
|
203
197
|
float spotSize = .05 + .6 * pow(u_spotSize, 2.) + .05 * randVal.x;
|
|
204
198
|
spotSize = mix(spotSize, .1, p);
|
|
205
|
-
float sector =
|
|
199
|
+
float sector = sst(.5 - spotSize, .5, atg1) * sst(.5 + spotSize, .5, atg1);
|
|
206
200
|
|
|
207
201
|
sector *= mask;
|
|
208
202
|
sector *= border;
|
|
@@ -231,7 +225,12 @@ void main() {
|
|
|
231
225
|
|
|
232
226
|
fragColor = vec4(color, opacity);
|
|
233
227
|
}`;
|
|
228
|
+
const PulsingBorderAspectRatios = {
|
|
229
|
+
auto: 0,
|
|
230
|
+
square: 1
|
|
231
|
+
};
|
|
234
232
|
export {
|
|
233
|
+
PulsingBorderAspectRatios,
|
|
235
234
|
pulsingBorderFragmentShader,
|
|
236
235
|
pulsingBorderMeta
|
|
237
236
|
};
|
|
@@ -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, textureRandomizerGB, 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
|
|
5
|
-
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,qBAAqB,uBAAuB;AAEzD,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AAAA,EACf,UAAU;AACZ;
|
|
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, textureRandomizerGB, 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_aspectRatio\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_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\nuniform float u_aspectRatio;\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 sst(float edge0, float edge1, float x) {\n return smoothstep(edge0, edge1, x);\n}\n\nfloat roundedBox(vec2 uv, vec2 halfSize, float distance, float cornerDistance, float thickness, float softness) {\n float borderDistance = abs(distance);\n float aa = 2. * fwidth(distance);\n float border = 1. - sst(mix(thickness, -thickness, softness), thickness + aa, borderDistance);\n float cornerFadeCircles = 0.;\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv + halfSize) / thickness)));\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(-halfSize.x, halfSize.y)) / thickness)));\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - vec2(halfSize.x, -halfSize.y)) / thickness)));\n cornerFadeCircles = mix(1., cornerFadeCircles, sst(0., 1., length((uv - halfSize) / thickness)));\n aa = fwidth(cornerDistance);\n float cornerFade = sst(0., mix(aa, thickness, softness), cornerDistance);\n cornerFade *= cornerFadeCircles;\n border += cornerFade;\n return border;\n}\n\n${textureRandomizerGB}\n\nfloat randomG(vec2 p) {\n vec2 uv = floor(p) / 100. + .5;\n return texture(u_noiseTexture, fract(uv)).g;\n}\nfloat valueNoise(vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n float a = randomG(i);\n float b = randomG(i + vec2(1.0, 0.0));\n float c = randomG(i + vec2(0.0, 1.0));\n float d = randomG(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\nvoid main() {\n const float firstFrameOffset = 109.;\n float t = 1.2 * (u_time + firstFrameOffset);\n\n vec2 borderUV = v_responsiveUV;\n float pulse = u_pulse * beat(.18 * u_time);\n\n float canvasRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\n vec2 halfSize = vec2(.5);\n borderUV.x *= max(canvasRatio, 1.);\n borderUV.y /= min(canvasRatio, 1.);\n halfSize.x *= max(canvasRatio, 1.);\n halfSize.y /= min(canvasRatio, 1.);\n\n float mL = u_marginLeft;\n float mR = u_marginRight;\n float mT = u_marginTop;\n float mB = u_marginBottom;\n float mX = mL + mR;\n float mY = mT + mB;\n\n if (u_aspectRatio > 0.) {\n float shapeRatio = canvasRatio * (1. - mX) / (1. - mY);\n float freeX = shapeRatio > 1. ? (1. - mX) * (1. - 1. / shapeRatio) : 0.;\n float freeY = shapeRatio < 1. ? (1. - mY) * (1. - shapeRatio) : 0.;\n mL += freeX * 0.5;\n mR += freeX * 0.5;\n mT += freeY * 0.5;\n mB += freeY * 0.5;\n mX = mL + mR;\n mY = mT + mB;\n }\n\n float thickness = .5 * u_thickness * min(halfSize.x, halfSize.y);\n\n halfSize.x *= (1. - mX);\n halfSize.y *= (1. - mY);\n\n vec2 centerShift = vec2(\n (mL - mR) * max(canvasRatio, 1.) * 0.5,\n (mB - mT) / min(canvasRatio, 1.) * 0.5\n );\n\n borderUV -= centerShift;\n halfSize -= mix(thickness, 0., u_softness);\n\n float radius = mix(0., min(halfSize.x, halfSize.y), u_roundness);\n vec2 d = abs(borderUV) - halfSize + radius;\n float outsideDistance = length(max(d, .0001)) - radius;\n float insideDistance = min(max(d.x, d.y), .0001);\n float cornerDistance = abs(min(max(d.x, d.y) - .45 * radius, .0));\n float distance = outsideDistance + insideDistance;\n\n float borderThickness = mix(thickness, 3. * thickness, u_softness);\n float border = roundedBox(borderUV, halfSize, distance, cornerDistance, borderThickness, u_softness);\n border = pow(border, 1. + u_softness);\n\n vec2 smokeUV = .3 * 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 float smokeThickness = thickness + .2;\n smokeThickness = min(.4, max(smokeThickness, .1));\n smoke *= roundedBox(borderUV, halfSize, distance, cornerDistance, smokeThickness, 1.);\n smoke = 30. * pow(smoke, 2.);\n smoke *= mix(0., .5, pow(u_smoke, 2.));\n smoke *= mix(1., pulse, u_pulse);\n smoke = clamp(smoke, 0., 1.);\n border += smoke;\n\n border = clamp(border, 0., 1.);\n\n vec3 blendColor = vec3(0.);\n float blendAlpha = 0.;\n vec3 addColor = vec3(0.);\n float addAlpha = 0.;\n\n float bloom = 4. * u_bloom;\n float intensity = 1. + (1. + 4. * u_softness) * u_intensity;\n\n float angle = atan(borderUV.y, borderUV.x) / TWO_PI;\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 = randomGB(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 = sst(.5 - spotSize, .5, atg1) * sst(.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_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_aspectRatio: (typeof PulsingBorderAspectRatios)[PulsingBorderAspectRatio];\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 u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface PulsingBorderParams extends ShaderSizingParams, ShaderMotionParams {\n colorBack?: string;\n colors?: string[];\n roundness?: number;\n thickness?: number;\n margin?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n aspectRatio?: PulsingBorderAspectRatio;\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\nexport const PulsingBorderAspectRatios = {\n auto: 0,\n square: 1,\n} as const;\n\nexport type PulsingBorderAspectRatio = keyof typeof PulsingBorderAspectRatios;\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,qBAAqB,uBAAuB;AAEzD,MAAM,oBAAoB;AAAA,EAC/B,eAAe;AAAA,EACf,UAAU;AACZ;AAsBO,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;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBrD,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,EA6BT,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAoGiB,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;AAgDZ,MAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,QAAQ;AACV;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/shaders/water.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface WaterUniforms extends ShaderSizingUniforms {
|
|
|
27
27
|
u_size: number;
|
|
28
28
|
}
|
|
29
29
|
export interface WaterParams extends ShaderSizingParams, ShaderMotionParams {
|
|
30
|
-
image?: HTMLImageElement | string
|
|
30
|
+
image?: HTMLImageElement | string;
|
|
31
31
|
colorBack?: string;
|
|
32
32
|
colorHighlight?: string;
|
|
33
33
|
highlights?: number;
|
package/dist/shaders/water.js
CHANGED
|
@@ -67,26 +67,26 @@ void main() {
|
|
|
67
67
|
vec2 patternUV = v_imageUV - .5;
|
|
68
68
|
patternUV = (patternUV * vec2(u_imageAspectRatio, 1.));
|
|
69
69
|
patternUV /= (.01 + .09 * u_size);
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
float t = u_time;
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
float wavesNoise = snoise((.3 + .1 * sin(t)) * .1 * patternUV + vec2(0., .4 * t));
|
|
74
74
|
|
|
75
75
|
float causticNoise = getCausticNoise(patternUV + u_waves * vec2(1., -1.) * wavesNoise, 2. * t, 1.5);
|
|
76
76
|
|
|
77
77
|
causticNoise += u_layering * getCausticNoise(patternUV + 2. * u_waves * vec2(1., -1.) * wavesNoise, 1.5 * t, 2.);
|
|
78
78
|
causticNoise = pow(causticNoise, 2.);
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
float edgesDistortion = smoothstep(0., .1, imageUV.x);
|
|
81
81
|
edgesDistortion *= smoothstep(0., .1, imageUV.y);
|
|
82
82
|
edgesDistortion *= (smoothstep(1., 1.1, imageUV.x) + smoothstep(.95, .8, imageUV.x));
|
|
83
83
|
edgesDistortion *= smoothstep(1., .9, imageUV.y);
|
|
84
84
|
edgesDistortion = mix(edgesDistortion, 1., u_edges);
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
float causticNoiseDistortion = .02 * causticNoise * edgesDistortion;
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
float wavesDistortion = .1 * u_waves * wavesNoise;
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
imageUV += vec2(wavesDistortion, -wavesDistortion);
|
|
91
91
|
imageUV += (u_caustic * causticNoiseDistortion);
|
|
92
92
|
|
|
@@ -95,20 +95,20 @@ void main() {
|
|
|
95
95
|
vec4 image = texture(u_image, imageUV);
|
|
96
96
|
vec4 backColor = u_colorBack;
|
|
97
97
|
backColor.rgb *= backColor.a;
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
vec3 color = mix(backColor.rgb, image.rgb, image.a * frame);
|
|
100
100
|
float opacity = backColor.a + image.a * frame;
|
|
101
101
|
|
|
102
102
|
causticNoise = max(-.2, causticNoise);
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
float hightlight = .025 * u_highlights * causticNoise;
|
|
105
105
|
hightlight *= u_colorHighlight.a;
|
|
106
106
|
color = mix(color, u_colorHighlight.rgb, .05 * u_highlights * causticNoise);
|
|
107
107
|
opacity += hightlight;
|
|
108
|
-
|
|
108
|
+
|
|
109
109
|
color += hightlight * (.5 + .5 * wavesNoise);
|
|
110
110
|
opacity += hightlight * (.5 + .5 * wavesNoise);
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
opacity = clamp(opacity, 0., 1.);
|
|
113
113
|
|
|
114
114
|
fragColor = vec4(color, opacity);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shaders/water.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, simplexNoise } from '../shader-utils.js';\n\n/**\n * Mimicking water surface distortion with a combination of noises;\n * Can be applied over the texture or just be used as an animated pattern\n *\n * Uniforms:\n * - u_colorBack, u_colorHighlight (RGBA)\n * - u_size: pattern scale relative to the image\n * - u_caustic: power of caustic distortion\n * - u_layering: the power of 2nd layer of caustic distortion\n * - u_edges: caustic distortion power on the image edges\n * - u_waves: additional distortion based in Simplex noise, independent from caustic\n * - u_highlights: a coloring added over the image/background, following the caustic shape\n *\n */\n\n// language=GLSL\nexport const waterFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorHighlight;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_size;\nuniform float u_highlights;\nuniform float u_layering;\nuniform float u_edges;\nuniform float u_caustic;\nuniform float u_waves;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${simplexNoise}\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\nmat2 rotate2D(float r) {\n return mat2(cos(r), sin(r), -sin(r), cos(r));\n}\n\nfloat getCausticNoise(vec2 uv, float t, float scale) {\n vec2 n = vec2(.1);\n vec2 N = vec2(.1);\n mat2 m = rotate2D(.5);\n for (int j = 0; j < 6; j++) {\n uv *= m;\n n *= m;\n vec2 q = uv * scale + float(j) + n + (.5 + .5 * float(j)) * (mod(float(j), 2.) - 1.) * t;\n n += sin(q);\n N += cos(q) / scale;\n scale *= 1.1;\n }\n return (N.x + N.y + 1.);\n}\n\nvoid main() {\n vec2 imageUV = v_imageUV;\n vec2 patternUV = v_imageUV - .5;\n patternUV = (patternUV * vec2(u_imageAspectRatio, 1.));\n patternUV /= (.01 + .09 * u_size);\n
|
|
4
|
+
"sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2, simplexNoise } from '../shader-utils.js';\n\n/**\n * Mimicking water surface distortion with a combination of noises;\n * Can be applied over the texture or just be used as an animated pattern\n *\n * Uniforms:\n * - u_colorBack, u_colorHighlight (RGBA)\n * - u_size: pattern scale relative to the image\n * - u_caustic: power of caustic distortion\n * - u_layering: the power of 2nd layer of caustic distortion\n * - u_edges: caustic distortion power on the image edges\n * - u_waves: additional distortion based in Simplex noise, independent from caustic\n * - u_highlights: a coloring added over the image/background, following the caustic shape\n *\n */\n\n// language=GLSL\nexport const waterFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\n\nuniform vec4 u_colorBack;\nuniform vec4 u_colorHighlight;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_size;\nuniform float u_highlights;\nuniform float u_layering;\nuniform float u_edges;\nuniform float u_caustic;\nuniform float u_waves;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n${simplexNoise}\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\nmat2 rotate2D(float r) {\n return mat2(cos(r), sin(r), -sin(r), cos(r));\n}\n\nfloat getCausticNoise(vec2 uv, float t, float scale) {\n vec2 n = vec2(.1);\n vec2 N = vec2(.1);\n mat2 m = rotate2D(.5);\n for (int j = 0; j < 6; j++) {\n uv *= m;\n n *= m;\n vec2 q = uv * scale + float(j) + n + (.5 + .5 * float(j)) * (mod(float(j), 2.) - 1.) * t;\n n += sin(q);\n N += cos(q) / scale;\n scale *= 1.1;\n }\n return (N.x + N.y + 1.);\n}\n\nvoid main() {\n vec2 imageUV = v_imageUV;\n vec2 patternUV = v_imageUV - .5;\n patternUV = (patternUV * vec2(u_imageAspectRatio, 1.));\n patternUV /= (.01 + .09 * u_size);\n\n float t = u_time;\n\n float wavesNoise = snoise((.3 + .1 * sin(t)) * .1 * patternUV + vec2(0., .4 * t));\n\n float causticNoise = getCausticNoise(patternUV + u_waves * vec2(1., -1.) * wavesNoise, 2. * t, 1.5);\n\n causticNoise += u_layering * getCausticNoise(patternUV + 2. * u_waves * vec2(1., -1.) * wavesNoise, 1.5 * t, 2.);\n causticNoise = pow(causticNoise, 2.);\n\n float edgesDistortion = smoothstep(0., .1, imageUV.x);\n edgesDistortion *= smoothstep(0., .1, imageUV.y);\n edgesDistortion *= (smoothstep(1., 1.1, imageUV.x) + smoothstep(.95, .8, imageUV.x));\n edgesDistortion *= smoothstep(1., .9, imageUV.y);\n edgesDistortion = mix(edgesDistortion, 1., u_edges);\n\n float causticNoiseDistortion = .02 * causticNoise * edgesDistortion;\n\n float wavesDistortion = .1 * u_waves * wavesNoise;\n\n imageUV += vec2(wavesDistortion, -wavesDistortion);\n imageUV += (u_caustic * causticNoiseDistortion);\n\n float frame = getUvFrame(imageUV);\n\n vec4 image = texture(u_image, imageUV);\n vec4 backColor = u_colorBack;\n backColor.rgb *= backColor.a;\n\n vec3 color = mix(backColor.rgb, image.rgb, image.a * frame);\n float opacity = backColor.a + image.a * frame;\n\n causticNoise = max(-.2, causticNoise);\n\n float hightlight = .025 * u_highlights * causticNoise;\n hightlight *= u_colorHighlight.a;\n color = mix(color, u_colorHighlight.rgb, .05 * u_highlights * causticNoise);\n opacity += hightlight;\n\n color += hightlight * (.5 + .5 * wavesNoise);\n opacity += hightlight * (.5 + .5 * wavesNoise);\n\n opacity = clamp(opacity, 0., 1.);\n\n fragColor = vec4(color, opacity);\n}\n`;\n\nexport interface WaterUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_colorBack: [number, number, number, number];\n u_colorHighlight: [number, number, number, number];\n u_highlights: number;\n u_layering: number;\n u_edges: number;\n u_caustic: number;\n u_waves: number;\n u_size: number;\n}\n\nexport interface WaterParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string;\n colorBack?: string;\n colorHighlight?: string;\n highlights?: number;\n layering?: number;\n edges?: number;\n caustic?: number;\n waves?: number;\n size?: number;\n}\n"],
|
|
5
5
|
"mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,WAAW,oBAAoB;AAkB5C,MAAM,sBAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBzC,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|