@remotion/effects 4.0.538 → 4.0.540
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/THIRD_PARTY_LICENSES.md +19 -0
- package/dist/barrel-distortion/webgpu-shader.d.ts +1 -0
- package/dist/bevel-alpha/webgpu-shaders.d.ts +2 -0
- package/dist/burlap-webgpu-shader.d.ts +1 -0
- package/dist/checkerboard-webgpu-shader.d.ts +1 -0
- package/dist/chromatic-aberration/webgpu-shader.d.ts +1 -0
- package/dist/color-correction-webgpu-shader-utils.d.ts +4 -0
- package/dist/color-key-webgpu-shader.d.ts +1 -0
- package/dist/color-matrix-runtime.d.ts +4 -0
- package/dist/contour-lines-webgpu-shader.d.ts +1 -0
- package/dist/corner-pin/webgpu-shader.d.ts +1 -0
- package/dist/curves.d.ts +65 -0
- package/dist/cylinder/webgl-shader.d.ts +1 -0
- package/dist/dot-grid-webgpu-shader.d.ts +1 -0
- package/dist/drop-shadow/webgpu-shaders.d.ts +2 -0
- package/dist/emboss-webgpu-shader.d.ts +1 -0
- package/dist/esm/barrel-distortion.mjs +67 -118
- package/dist/esm/bevel-alpha.mjs +247 -196
- package/dist/esm/blur.mjs +101 -115
- package/dist/esm/brightness.mjs +65 -132
- package/dist/esm/burlap.mjs +178 -151
- package/dist/esm/checkerboard.mjs +6 -514
- package/dist/esm/chromatic-aberration.mjs +72 -119
- package/dist/esm/color-correction.mjs +186 -224
- package/dist/esm/color-key.mjs +149 -136
- package/dist/esm/contour-lines.mjs +201 -160
- package/dist/esm/contrast.mjs +65 -132
- package/dist/esm/corner-pin.mjs +4 -390
- package/dist/esm/curves.mjs +357 -0
- package/dist/esm/cylinder.mjs +108 -225
- package/dist/esm/dot-grid.mjs +184 -213
- package/dist/esm/drop-shadow.mjs +162 -180
- package/dist/esm/duotone.mjs +110 -143
- package/dist/esm/emboss.mjs +153 -151
- package/dist/esm/evolve.mjs +228 -154
- package/dist/esm/exposure.mjs +93 -201
- package/dist/esm/film-burn.mjs +298 -0
- package/dist/esm/fisheye.mjs +97 -126
- package/dist/esm/flannel.mjs +158 -156
- package/dist/esm/fractal-noise.mjs +186 -232
- package/dist/esm/glow.mjs +164 -179
- package/dist/esm/grayscale.mjs +56 -122
- package/dist/esm/gridlines.mjs +6 -575
- package/dist/esm/halftone-linear-gradient.mjs +246 -245
- package/dist/esm/halftone.mjs +267 -243
- package/dist/esm/hue.mjs +55 -122
- package/dist/esm/index-00v3hr66.mjs +299 -0
- package/dist/esm/index-0w4eqht8.mjs +351 -0
- package/dist/esm/index-18y0zcy2.mjs +440 -0
- package/dist/esm/index-1m1b1ad7.mjs +520 -0
- package/dist/esm/index-34fxm3ax.mjs +518 -0
- package/dist/esm/index-4fvp93ps.mjs +32 -0
- package/dist/esm/index-4scpn12x.mjs +224 -0
- package/dist/esm/index-4z6pt3ka.mjs +104 -0
- package/dist/esm/index-618ky75w.mjs +51 -0
- package/dist/esm/index-6agxdrvr.mjs +411 -0
- package/dist/esm/index-6jkps947.mjs +120 -0
- package/dist/esm/index-8agtsbw4.mjs +617 -0
- package/dist/esm/index-8jx11jyn.mjs +29 -0
- package/dist/esm/index-8p04sssx.mjs +123 -0
- package/dist/esm/index-afdtmrh2.mjs +596 -0
- package/dist/esm/index-b86qstcs.mjs +18 -0
- package/dist/esm/index-cb77qg3g.mjs +587 -0
- package/dist/esm/index-cdp7tr8x.mjs +122 -0
- package/dist/esm/index-evy8hyah.mjs +55 -0
- package/dist/esm/index-gnsce796.mjs +6 -0
- package/dist/esm/index-kkvzt8b7.mjs +199 -0
- package/dist/esm/index-r0v18b2n.mjs +425 -0
- package/dist/esm/index-rswpzmm5.mjs +926 -0
- package/dist/esm/index-s9mrx750.mjs +97 -0
- package/dist/esm/index-tvfexb7s.mjs +164 -0
- package/dist/esm/index-vp56k1gj.mjs +215 -0
- package/dist/esm/index-wxhvgv2s.mjs +79 -0
- package/dist/esm/index-wy95a41r.mjs +407 -0
- package/dist/esm/index-ysnwfc4t.mjs +306 -0
- package/dist/esm/index.mjs +49 -4053
- package/dist/esm/invert.mjs +54 -122
- package/dist/esm/iris-wipe.mjs +315 -0
- package/dist/esm/lens-blur.mjs +169 -156
- package/dist/esm/levels.mjs +204 -151
- package/dist/esm/light-leak.mjs +6 -416
- package/dist/esm/light-trail.mjs +124 -128
- package/dist/esm/linear-gradient-tint.mjs +4 -424
- package/dist/esm/linear-gradient.mjs +4 -370
- package/dist/esm/linear-progressive-blur.mjs +92 -118
- package/dist/esm/linear-progressive-pixelate.mjs +83 -378
- package/dist/esm/lines.mjs +167 -162
- package/dist/esm/liquid-contours.mjs +192 -153
- package/dist/esm/long-shadows.mjs +278 -251
- package/dist/esm/lut.mjs +123 -23
- package/dist/esm/mirror.mjs +78 -120
- package/dist/esm/noise-displacement.mjs +156 -151
- package/dist/esm/noise.mjs +107 -143
- package/dist/esm/outline.mjs +192 -170
- package/dist/esm/page-turn.mjs +141 -244
- package/dist/esm/paper.mjs +522 -194
- package/dist/esm/pattern.mjs +4 -568
- package/dist/esm/pixel-dissolve.mjs +158 -186
- package/dist/esm/pixelate.mjs +92 -149
- package/dist/esm/radial-progressive-blur.mjs +96 -118
- package/dist/esm/radial-progressive-pixelate.mjs +91 -384
- package/dist/esm/radial-wipe.mjs +224 -0
- package/dist/esm/rain-fall.mjs +114 -0
- package/dist/esm/region-blur.mjs +138 -192
- package/dist/esm/rings.mjs +6 -512
- package/dist/esm/roughen-edges.mjs +180 -156
- package/dist/esm/saturation.mjs +56 -122
- package/dist/esm/scale.mjs +50 -60
- package/dist/esm/scanlines.mjs +115 -149
- package/dist/esm/shadows-highlights.mjs +103 -205
- package/dist/esm/shatter.mjs +868 -0
- package/dist/esm/shine.mjs +192 -227
- package/dist/esm/shrinkwrap.mjs +388 -225
- package/dist/esm/skew.mjs +100 -145
- package/dist/esm/snow-fall.mjs +170 -0
- package/dist/esm/speckle.mjs +192 -210
- package/dist/esm/sphere.mjs +101 -225
- package/dist/esm/starburst.mjs +6 -345
- package/dist/esm/tear.mjs +138 -155
- package/dist/esm/thermal-vision.mjs +135 -152
- package/dist/esm/tile.mjs +5 -184
- package/dist/esm/tint.mjs +80 -132
- package/dist/esm/translate.mjs +55 -137
- package/dist/esm/turbulent-displace.mjs +182 -221
- package/dist/esm/tv-signal-off.mjs +140 -149
- package/dist/esm/venetian-blinds.mjs +91 -140
- package/dist/esm/vibrance.mjs +95 -204
- package/dist/esm/vignette.mjs +136 -155
- package/dist/esm/wave.mjs +88 -47
- package/dist/esm/waves.mjs +181 -169
- package/dist/esm/white-balance.mjs +100 -204
- package/dist/esm/white-noise.mjs +98 -146
- package/dist/esm/zigzag.mjs +6 -575
- package/dist/esm/zoom-blur.mjs +90 -121
- package/dist/evolve.d.ts +46 -10
- package/dist/film-burn-webgpu-shader.d.ts +1 -0
- package/dist/film-burn.d.ts +40 -0
- package/dist/fisheye/webgpu-shader.d.ts +1 -0
- package/dist/flannel-webgpu-shader.d.ts +1 -0
- package/dist/fractal-noise/shader.d.ts +1 -1
- package/dist/fractal-noise/webgpu-shader.d.ts +1 -0
- package/dist/gaussian-blur-webgpu-shader.d.ts +1 -0
- package/dist/glow/webgpu-shaders.d.ts +2 -0
- package/dist/gridlines-webgpu-shader.d.ts +1 -0
- package/dist/halftone-linear-gradient-webgpu-shader.d.ts +1 -0
- package/dist/halftone-webgpu-shader.d.ts +1 -0
- package/dist/iris-wipe.d.ts +78 -0
- package/dist/lens-blur/webgpu-shader.d.ts +1 -0
- package/dist/levels.d.ts +69 -2
- package/dist/light-leak-webgpu-shader.d.ts +1 -0
- package/dist/light-trail/webgpu-shader.d.ts +1 -0
- package/dist/linear-gradient-tint-webgpu-shader.d.ts +1 -0
- package/dist/linear-gradient-webgpu-shader.d.ts +1 -0
- package/dist/lines-webgpu-shader.d.ts +1 -0
- package/dist/liquid-contours-webgpu-shader.d.ts +1 -0
- package/dist/long-shadows-webgpu-shaders.d.ts +2 -0
- package/dist/lut/webgpu-shader.d.ts +1 -0
- package/dist/mirror/webgpu-shader.d.ts +1 -0
- package/dist/noise-displacement-webgpu-shader.d.ts +1 -0
- package/dist/noise-webgpu-shader.d.ts +1 -0
- package/dist/outline/webgpu-shader.d.ts +1 -0
- package/dist/page-turn/webgl-shader.d.ts +1 -0
- package/dist/paper-webgpu-shader.d.ts +2 -0
- package/dist/pattern-webgpu-shader.d.ts +1 -0
- package/dist/pixel-dissolve-webgpu-shader.d.ts +1 -0
- package/dist/progressive-pixelate-runtime.d.ts +1 -0
- package/dist/radial-wipe.d.ts +19 -0
- package/dist/rain-fall.d.ts +143 -0
- package/dist/rect-transform-runtime.d.ts +11 -0
- package/dist/region-blur/webgpu-shader.d.ts +1 -0
- package/dist/rings-webgpu-shader.d.ts +1 -0
- package/dist/roughen-edges-webgpu-shader.d.ts +1 -0
- package/dist/shatter/geometry.d.ts +19 -0
- package/dist/shatter/index.d.ts +39 -0
- package/dist/shatter/runtime.d.ts +19 -0
- package/dist/shatter/webgpu-shader.d.ts +1 -0
- package/dist/shatter.d.ts +1 -0
- package/dist/shine-webgpu-shader.d.ts +1 -0
- package/dist/shrinkwrap-webgpu-shader.d.ts +1 -0
- package/dist/single-pass-runtime.d.ts +18 -0
- package/dist/skew-webgpu-shader.d.ts +1 -0
- package/dist/snow-fall.d.ts +208 -0
- package/dist/speckle-webgpu-shader.d.ts +1 -0
- package/dist/sphere/webgl-shader.d.ts +1 -0
- package/dist/starburst-webgpu-shader.d.ts +1 -0
- package/dist/tear-webgpu-shader.d.ts +1 -0
- package/dist/thermal-vision-webgpu-shader.d.ts +1 -0
- package/dist/tile-gpu-runtime.d.ts +24 -0
- package/dist/turbulent-displace/webgpu-shader.d.ts +1 -0
- package/dist/value-noise-webgpu-shader.d.ts +1 -0
- package/dist/vignette-webgpu-shader.d.ts +1 -0
- package/dist/wave/wave-runtime.d.ts +2 -1
- package/dist/wave/webgpu-shader.d.ts +1 -0
- package/dist/waves-webgpu-shader.d.ts +1 -0
- package/dist/weather/params.d.ts +149 -0
- package/dist/weather/runtime.d.ts +52 -0
- package/dist/weather/shaders.d.ts +4 -0
- package/dist/weather/webgpu-runtime.d.ts +36 -0
- package/dist/weather/webgpu-shader.d.ts +1 -0
- package/dist/webgl-projection-runtime.d.ts +18 -0
- package/dist/webgpu-color-state.d.ts +10 -0
- package/dist/webgpu-mesh-runtime.d.ts +46 -0
- package/dist/webgpu-multipass-runtime.d.ts +50 -0
- package/dist/webgpu-projection-runtime.d.ts +9 -5
- package/dist/webgpu-single-pass-runtime.d.ts +47 -0
- package/dist/white-noise-webgpu-shader.d.ts +1 -0
- package/dist/zigzag-webgpu-shader.d.ts +1 -0
- package/dist/zoom-blur/webgpu-shader.d.ts +1 -0
- package/package.json +59 -3
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { type WeatherCommonParams } from './weather/params.js';
|
|
2
|
+
export type SnowFallParams = WeatherCommonParams & {
|
|
3
|
+
/** Number of flakes, an integer from `0` to `200000`. Defaults to `10000`. */
|
|
4
|
+
readonly flakes?: number;
|
|
5
|
+
/** Size variation, from `0` to `1`. Defaults to `0.5`. */
|
|
6
|
+
readonly sizeVariation?: number;
|
|
7
|
+
/** Speed variation, from `0` to `1`. Defaults to `0.5`. */
|
|
8
|
+
readonly speedVariation?: number;
|
|
9
|
+
/** Sideways oscillation strength, from `0` to `100`. Defaults to `2`. */
|
|
10
|
+
readonly wiggleAmount?: number;
|
|
11
|
+
/** Wiggle amplitude variation, from `0` to `1`. Defaults to `0.5`. */
|
|
12
|
+
readonly wiggleAmountVariation?: number;
|
|
13
|
+
/** Sideways oscillations per second, from `0` to `20`. Defaults to `1`. */
|
|
14
|
+
readonly wiggleFrequency?: number;
|
|
15
|
+
/** Wiggle frequency variation, from `0` to `1`. Defaults to `0.5`. */
|
|
16
|
+
readonly wiggleFrequencyVariation?: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const snowFallSchema: {
|
|
19
|
+
readonly time: {
|
|
20
|
+
readonly type: 'number';
|
|
21
|
+
readonly min: 0;
|
|
22
|
+
readonly max: 10;
|
|
23
|
+
readonly step: 0.01;
|
|
24
|
+
readonly default: number;
|
|
25
|
+
readonly description: 'Time';
|
|
26
|
+
readonly hiddenFromList: false;
|
|
27
|
+
};
|
|
28
|
+
readonly size: {
|
|
29
|
+
readonly type: 'number';
|
|
30
|
+
readonly min: 0;
|
|
31
|
+
readonly max: 50;
|
|
32
|
+
readonly step: 0.01;
|
|
33
|
+
readonly default: number;
|
|
34
|
+
readonly description: 'Size';
|
|
35
|
+
readonly hiddenFromList: false;
|
|
36
|
+
};
|
|
37
|
+
readonly sceneDepth: {
|
|
38
|
+
readonly type: 'number';
|
|
39
|
+
readonly min: 0;
|
|
40
|
+
readonly max: 20000;
|
|
41
|
+
readonly step: 1;
|
|
42
|
+
readonly default: number;
|
|
43
|
+
readonly description: 'Scene depth';
|
|
44
|
+
readonly hiddenFromList: false;
|
|
45
|
+
};
|
|
46
|
+
readonly speed: {
|
|
47
|
+
readonly type: 'number';
|
|
48
|
+
readonly min: 0;
|
|
49
|
+
readonly max: number;
|
|
50
|
+
readonly step: 1;
|
|
51
|
+
readonly default: number;
|
|
52
|
+
readonly description: 'Speed';
|
|
53
|
+
readonly hiddenFromList: false;
|
|
54
|
+
};
|
|
55
|
+
readonly wind: {
|
|
56
|
+
readonly type: 'number';
|
|
57
|
+
readonly min: number;
|
|
58
|
+
readonly max: number;
|
|
59
|
+
readonly step: 1;
|
|
60
|
+
readonly default: number;
|
|
61
|
+
readonly description: 'Wind';
|
|
62
|
+
readonly hiddenFromList: false;
|
|
63
|
+
};
|
|
64
|
+
readonly windVariation: {
|
|
65
|
+
readonly type: 'number';
|
|
66
|
+
readonly min: 0;
|
|
67
|
+
readonly max: 1;
|
|
68
|
+
readonly step: 0.01;
|
|
69
|
+
readonly default: number;
|
|
70
|
+
readonly description: 'Wind variation';
|
|
71
|
+
readonly hiddenFromList: false;
|
|
72
|
+
};
|
|
73
|
+
readonly spread: {
|
|
74
|
+
readonly type: 'number';
|
|
75
|
+
readonly min: 0;
|
|
76
|
+
readonly max: 1000;
|
|
77
|
+
readonly step: 1;
|
|
78
|
+
readonly default: number;
|
|
79
|
+
readonly description: 'Spread';
|
|
80
|
+
readonly hiddenFromList: false;
|
|
81
|
+
};
|
|
82
|
+
readonly opacity: {
|
|
83
|
+
readonly type: 'number';
|
|
84
|
+
readonly min: 0;
|
|
85
|
+
readonly max: 1;
|
|
86
|
+
readonly step: 0.01;
|
|
87
|
+
readonly default: number;
|
|
88
|
+
readonly description: 'Opacity';
|
|
89
|
+
readonly hiddenFromList: false;
|
|
90
|
+
};
|
|
91
|
+
readonly color: {
|
|
92
|
+
readonly type: 'color';
|
|
93
|
+
readonly default: string;
|
|
94
|
+
readonly description: 'Color';
|
|
95
|
+
};
|
|
96
|
+
readonly transferMode: {
|
|
97
|
+
readonly type: 'enum';
|
|
98
|
+
readonly variants: {
|
|
99
|
+
readonly composite: {};
|
|
100
|
+
readonly lighten: {};
|
|
101
|
+
};
|
|
102
|
+
readonly default: "composite" | "lighten";
|
|
103
|
+
readonly description: 'Transfer mode';
|
|
104
|
+
};
|
|
105
|
+
readonly compositeWithOriginal: {
|
|
106
|
+
readonly type: 'boolean';
|
|
107
|
+
readonly default: boolean;
|
|
108
|
+
readonly description: 'Composite with original';
|
|
109
|
+
};
|
|
110
|
+
readonly offset: {
|
|
111
|
+
readonly type: 'uv-coordinate';
|
|
112
|
+
readonly step: 0.01;
|
|
113
|
+
readonly default: readonly [number, number];
|
|
114
|
+
readonly description: 'Offset';
|
|
115
|
+
};
|
|
116
|
+
readonly seed: {
|
|
117
|
+
readonly type: 'number';
|
|
118
|
+
readonly min: 0;
|
|
119
|
+
readonly max: 4294967295;
|
|
120
|
+
readonly step: 1;
|
|
121
|
+
readonly integer: true;
|
|
122
|
+
readonly default: number;
|
|
123
|
+
readonly description: 'Seed';
|
|
124
|
+
readonly hiddenFromList: false;
|
|
125
|
+
};
|
|
126
|
+
readonly flakes: {
|
|
127
|
+
readonly type: 'number';
|
|
128
|
+
readonly min: 0;
|
|
129
|
+
readonly max: 200000;
|
|
130
|
+
readonly step: 1;
|
|
131
|
+
readonly integer: true;
|
|
132
|
+
readonly default: 10000;
|
|
133
|
+
readonly description: 'Flakes';
|
|
134
|
+
readonly hiddenFromList: false;
|
|
135
|
+
};
|
|
136
|
+
readonly sizeVariation: {
|
|
137
|
+
readonly type: 'number';
|
|
138
|
+
readonly min: 0;
|
|
139
|
+
readonly max: 1;
|
|
140
|
+
readonly step: 0.01;
|
|
141
|
+
readonly default: 0.5;
|
|
142
|
+
readonly description: 'Size variation';
|
|
143
|
+
readonly hiddenFromList: false;
|
|
144
|
+
};
|
|
145
|
+
readonly speedVariation: {
|
|
146
|
+
readonly type: 'number';
|
|
147
|
+
readonly min: 0;
|
|
148
|
+
readonly max: 1;
|
|
149
|
+
readonly step: 0.01;
|
|
150
|
+
readonly default: 0.5;
|
|
151
|
+
readonly description: 'Speed variation';
|
|
152
|
+
readonly hiddenFromList: false;
|
|
153
|
+
};
|
|
154
|
+
readonly wiggleAmount: {
|
|
155
|
+
readonly type: 'number';
|
|
156
|
+
readonly min: 0;
|
|
157
|
+
readonly max: 100;
|
|
158
|
+
readonly step: 0.01;
|
|
159
|
+
readonly default: 2;
|
|
160
|
+
readonly description: 'Wiggle amount';
|
|
161
|
+
readonly hiddenFromList: false;
|
|
162
|
+
};
|
|
163
|
+
readonly wiggleAmountVariation: {
|
|
164
|
+
readonly type: 'number';
|
|
165
|
+
readonly min: 0;
|
|
166
|
+
readonly max: 1;
|
|
167
|
+
readonly step: 0.01;
|
|
168
|
+
readonly default: 0.5;
|
|
169
|
+
readonly description: 'Wiggle amount variation';
|
|
170
|
+
readonly hiddenFromList: false;
|
|
171
|
+
};
|
|
172
|
+
readonly wiggleFrequency: {
|
|
173
|
+
readonly type: 'number';
|
|
174
|
+
readonly min: 0;
|
|
175
|
+
readonly max: 20;
|
|
176
|
+
readonly step: 0.01;
|
|
177
|
+
readonly default: 1;
|
|
178
|
+
readonly description: 'Wiggle frequency';
|
|
179
|
+
readonly hiddenFromList: false;
|
|
180
|
+
};
|
|
181
|
+
readonly wiggleFrequencyVariation: {
|
|
182
|
+
readonly type: 'number';
|
|
183
|
+
readonly min: 0;
|
|
184
|
+
readonly max: 1;
|
|
185
|
+
readonly step: 0.01;
|
|
186
|
+
readonly default: 0.5;
|
|
187
|
+
readonly description: 'Wiggle frequency variation';
|
|
188
|
+
readonly hiddenFromList: false;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
export declare const snowFall: (params?: (WeatherCommonParams & {
|
|
192
|
+
/** Number of flakes, an integer from `0` to `200000`. Defaults to `10000`. */
|
|
193
|
+
readonly flakes?: number;
|
|
194
|
+
/** Size variation, from `0` to `1`. Defaults to `0.5`. */
|
|
195
|
+
readonly sizeVariation?: number;
|
|
196
|
+
/** Speed variation, from `0` to `1`. Defaults to `0.5`. */
|
|
197
|
+
readonly speedVariation?: number;
|
|
198
|
+
/** Sideways oscillation strength, from `0` to `100`. Defaults to `2`. */
|
|
199
|
+
readonly wiggleAmount?: number;
|
|
200
|
+
/** Wiggle amplitude variation, from `0` to `1`. Defaults to `0.5`. */
|
|
201
|
+
readonly wiggleAmountVariation?: number;
|
|
202
|
+
/** Sideways oscillations per second, from `0` to `20`. Defaults to `1`. */
|
|
203
|
+
readonly wiggleFrequency?: number;
|
|
204
|
+
/** Wiggle frequency variation, from `0` to `1`. Defaults to `0.5`. */
|
|
205
|
+
readonly wiggleFrequencyVariation?: number;
|
|
206
|
+
} & {
|
|
207
|
+
readonly disabled?: boolean;
|
|
208
|
+
}) | undefined) => import("remotion").EffectDescriptor<unknown>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SPECKLE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\nstruct Params { size: vec2f, density: f32, radius: f32, randomness: f32, }\n\nfn hash21(p: vec2f) -> f32 {\n var p3 = fract(p.xyx * vec3f(443.8975, 397.2973, 491.1871));\n p3 += vec3f(dot(p3, p3.yzx + vec3f(19.19)));\n return fract((p3.x + p3.y) * p3.z);\n}\n\nfn hash22(p: vec2f) -> vec2f { return vec2f(hash21(p + vec2f(17.13)), hash21(p + vec2f(83.71))); }\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSampleLevel(source, sourceSampler, input.uv, 0);\n if (params.density <= 0.0 || params.radius <= 0.0) { return color; }\n let fragPos = vec2f(input.uv.x, 1.0 - input.uv.y) * params.size;\n let cellSize = max(params.radius * 2.5, 1.0);\n let baseCell = floor(fragPos / cellSize);\n var hole = 0.0;\n for (var y = -1; y <= 1; y++) {\n for (var x = -1; x <= 1; x++) {\n let cell = baseCell + vec2f(f32(x), f32(y));\n if (hash21(cell) <= params.density) {\n let randomOffset = (hash22(cell + vec2f(11.7)) - vec2f(0.5)) * params.randomness;\n let center = (cell + vec2f(0.5) + randomOffset) * cellSize;\n let variation = mix(1.0, 0.35 + hash21(cell + vec2f(29.43)) * 0.65, params.randomness);\n let radius = params.radius * 0.5 * variation;\n let edge = min(1.0, max(radius * 0.5, 0.35));\n hole = max(hole, 1.0 - smoothstep(radius - edge, radius + edge, length(fragPos - center)));\n }\n }\n }\n return color * (1.0 - clamp(hole, 0.0, 1.0));\n}\n\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SPHERE_WEBGL_SHADER = "#version 300 es\nprecision highp float;\nuniform sampler2D uSource;\nuniform vec4 uParams[3];\nout vec4 fragColor;\nvec4 sampleFace(vec3 normal, mat3 inverseRotation) {\n vec3 local = inverseRotation * normal;\n // Longitude wraps at the seam; latitude spans the complete image height.\n vec2 uv = vec2(fract(atan(local.x, local.z) / 6.28318530718 + 0.5), asin(clamp(local.y, -1.0, 1.0)) / 3.14159265359 + 0.5);\n vec4 color = textureLod(uSource, vec2(uv.x, 1.0 - uv.y), 0.0);\n float shade = mix(1.0, abs(normal.z), uParams[1].z);\n return vec4(color.rgb * shade, color.a);\n}\n\nvec4 project(vec2 position) {\n vec2 p = (position - uParams[0].zw) / uParams[1].x;\n float distanceSquared = dot(p, p);\n float coverage = 1.0 - smoothstep(1.0 - fwidth(distanceSquared), 1.0, distanceSquared);\n if (distanceSquared >= 1.0) { return vec4(0); }\n float z = sqrt(1.0 - distanceSquared);\n vec3 s = sin(uParams[2].xyz);\n vec3 c = cos(uParams[2].xyz);\n mat3 rx = mat3(vec3(1, 0, 0), vec3(0, c.x, s.x), vec3(0, -s.x, c.x));\n mat3 ry = mat3(vec3(c.y, 0, -s.y), vec3(0, 1, 0), vec3(s.y, 0, c.y));\n mat3 rz = mat3(vec3(c.z, s.z, 0), vec3(-s.z, c.z, 0), vec3(0, 0, 1));\n mat3 inverseRotation = transpose(rz * ry * rx);\n vec4 front = sampleFace(vec3(p, z), inverseRotation);\n vec4 back = sampleFace(vec3(p, -z), inverseRotation);\n if (uParams[1].w == 1.0) { return front * coverage; }\n if (uParams[1].w == 2.0) { return back * coverage; }\n return (front + back * (1.0 - front.a)) * coverage;\n}\n\nvoid main() { fragColor = project(vec2(gl_FragCoord.x, uParams[0].y - gl_FragCoord.y)); }\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const STARBURST_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var sourceTexture: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var palette: texture_2d<f32>;\nstruct Params {\n geometry: vec4f,\n values: vec4f,\n}\nfn sampleSource(uv: vec2f) -> vec4f {\n return textureSampleLevel(sourceTexture, sourceSampler, vec2f(uv.x, 1.0 - uv.y), 0);\n}\nfn glslModulo(value: f32, divisor: f32) -> f32 { return value - divisor * floor(value / divisor); }\nfn paletteColor(index: f32) -> vec4f { return textureLoad(palette, vec2i(i32(index), 0), 0); }\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let vUv = vec2f(input.uv.x, 1.0 - input.uv.y);\n\n var center = vec2f(input.position.x, params.geometry.y - input.position.y) / params.geometry.xy - params.values.zw;\n center.x *= params.geometry.x / params.geometry.y;\n let angle = atan2(center.y, center.x) + params.values.x;\n let normalizedAngle = (angle + 3.14159265359) / (2.0 * 3.14159265359);\n let sector = normalizedAngle * params.geometry.z;\n let rayIndex = glslModulo(floor(sector), params.geometry.z);\n let colorIndex = glslModulo(rayIndex, params.geometry.w);\n var col = paletteColor(colorIndex).rgb;\n let fractSector = fract(sector);\n let edgeSmooth = params.values.y * 0.5;\n let nextColorIndex = glslModulo(rayIndex + 1.0, params.geometry.w);\n let nextCol = paletteColor(nextColorIndex).rgb;\n let blend = smoothstep(1.0 - edgeSmooth, 1.0, fractSector);\n col = mix(col, nextCol, blend);\n let blendStart = smoothstep(edgeSmooth, 0.0, fractSector);\n let prevColorIndex = glslModulo(rayIndex - 1.0 + params.geometry.w, params.geometry.w);\n let prevCol = paletteColor(prevColorIndex).rgb;\n col = mix(col, prevCol, blendStart);\n return vec4f(col, 1.0);\n\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TEAR_WEBGPU_SHADER = "\nstruct Params {resolution: vec2f, angle: f32, progress: f32, rotation: f32, jaggedness: f32,}\nstruct VertexOutput {@builtin(position) position: vec4f, @location(0) uv: vec2f,}\n@group(0) @binding(0) var sourceTexture: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@vertex fn vertex(@builtin(vertex_index) index: u32, @builtin(instance_index) instance: u32) -> VertexOutput {\n let aPos=vec2f(f32(index%2u),f32(index/2u)/192.0);\n let side=select(-1.0,1.0,instance!=0u);\n let direction=radians(params.angle);let dc=cos(direction);let ds=sin(direction);\n let toCanvas=mat2x2f(vec2f(dc,-ds),vec2f(ds,dc));\n let extent=vec2f(abs(dc)*params.resolution.x+abs(ds)*params.resolution.y,abs(ds)*params.resolution.x+abs(dc)*params.resolution.y);\n let outerEdge=select(0.0,extent.x,side>=0.0);\n let zigzag=1.0-4.0*abs(fract(aPos.y*6.0+0.25)-0.5);\n let seam=extent.x*0.5+zigzag*min(params.jaggedness,extent.x*0.45);\n let source=vec2f(mix(outerEdge,seam,aPos.x),aPos.y*extent.y);\n let sourceCanvas=toCanvas*(source-extent*0.5)+params.resolution*0.5;\n let tearProgress=min(params.progress,1.0);\n let tipY=tearProgress*extent.y;\n let pivot=vec2f(extent.x*0.5,tipY);\n let fullAngle=radians(params.rotation)*tearProgress;\n let bendHeight=max(extent.y*0.15,fullAngle*extent.x*1.5);\n let bend=smoothstep(0.0,bendHeight,tipY-source.y);\n let angle=side*fullAngle*bend;let c=cos(angle);let s=sin(angle);\n let delta=source-pivot;\n var position=pivot+vec2f(c*delta.x-s*delta.y,s*delta.x+c*delta.y);\n position.x+=side*max(params.progress-1.0,0.0)*extent.x*0.5;\n position=toCanvas*(position-extent*0.5)+params.resolution*0.5;\n var output: VertexOutput;\n // Mesh runtime restores orientation after resolving WebGL-compatible samples.\n output.position=vec4f(position.x/params.resolution.x*2.0-1.0,position.y/params.resolution.y*2.0-1.0,0,1);\n output.uv=sourceCanvas/params.resolution;\n return output;\n}\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n if (any(input.uv<vec2f(0)) || any(input.uv>vec2f(1))) {discard;}\n return textureSample(sourceTexture,sourceSampler,input.uv);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const THERMAL_VISION_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\nstruct Params { amount: f32, paletteLength: f32, }\n@group(0) @binding(3) var palette: texture_2d<f32>;\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let color=textureSampleLevel(source,sourceSampler,input.uv,0);\n if(color.a<=0.001) { return vec4f(0); }\n let rgb=color.rgb/color.a;\n let luminance=dot(rgb,vec3f(0.299,0.587,0.114));\n let position=clamp(luminance,0.0,1.0)*(max(params.paletteLength,2.0)-1.0);\n let index=i32(floor(position));\n let first=textureLoad(palette,vec2i(index,0),0).rgb;\n let last=textureLoad(palette,vec2i(min(index+1,i32(params.paletteLength)-1),0),0).rgb;\n let thermal=mix(first,last,fract(position));\n return vec4f(mix(rgb,thermal,clamp(params.amount,0.0,1.0))*color.a,color.a);\n}\n\n";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
type TileBounds = {
|
|
2
|
+
left: number;
|
|
3
|
+
top: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const createTileGpuImplementations: <P, S>({ setupBounds, getBounds, resolve, }: {
|
|
8
|
+
setupBounds: (target: HTMLCanvasElement) => S;
|
|
9
|
+
getBounds: (input: {
|
|
10
|
+
source: CanvasImageSource;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
params: P;
|
|
14
|
+
state: S;
|
|
15
|
+
}) => TileBounds | null;
|
|
16
|
+
resolve: (params: P) => {
|
|
17
|
+
horizontal: boolean;
|
|
18
|
+
vertical: boolean;
|
|
19
|
+
};
|
|
20
|
+
}) => {
|
|
21
|
+
webgl2: import("remotion").EffectImplementation<P, unknown>;
|
|
22
|
+
webgpu: import("remotion").EffectImplementation<P, unknown>;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TURBULENT_DISPLACE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\nstruct Params { size: vec2f, offset: vec2f, amount: f32, scale: f32, complexity: f32, evolution: f32, cycle: f32, seed: u32, displacement: f32, pinning: f32, cycleEvolution: f32, }\nfn noiseType() -> i32 { return 2; }\n\nfn lattice(point: vec3i, seed: u32) -> f32 {\n let p = bitcast<vec3u>(point) & vec3u(65535u);\n var h = (p.x*0x27d4eb2du) ^ (p.y*0x165667b1u) ^ (p.z*0x9e3779b9u) ^ (seed*0x85ebca6bu);\n h ^= h >> 15u; h *= 0x2c1b3c6du; h ^= h >> 12u; h *= 0x297a2d39u; h ^= h >> 15u;\n return f32(h & 65535u)/65535.0;\n}\nfn catmull(p: vec4f, t: f32) -> f32 {\n return 0.5*(2.0*p.y+(p.z-p.x)*t+(2.0*p.x-5.0*p.y+4.0*p.z-p.w)*t*t+(3.0*p.y-p.x-3.0*p.z+p.w)*t*t*t);\n}\nfn bspline(t: f32) -> vec3f { return vec3f(0.5*(1.0-t)*(1.0-t),0.5+t*(1.0-t),0.5*t*t); }\nfn sliceNoise(p: vec3i,t: vec2f,seed: u32) -> f32 {\n if(noiseType()==0) { return lattice(p,seed); }\n if(noiseType()==1) { return mix(mix(lattice(p,seed),lattice(p+vec3i(1,0,0),seed),t.x),mix(lattice(p+vec3i(0,1,0),seed),lattice(p+vec3i(1,1,0),seed),t.x),t.y); }\n if(noiseType()==2) {\n let wx=bspline(t.x); let wy=bspline(t.y); var result=0.0;\n for(var y=0;y<3;y++) { for(var x=0;x<3;x++) { result += wx[x]*wy[y]*lattice(p+vec3i(x-1,y-1,0),seed); } }\n return result;\n }\n var rows: vec4f;\n for(var y=0;y<4;y++) {\n var row: vec4f;\n for(var x=0;x<4;x++) { row[x]=lattice(p+vec3i(x-1,y-1,0),seed); }\n rows[y]=catmull(row,t.x);\n }\n return catmull(rows,t.y);\n}\nfn valueNoise(point: vec3f,seed: u32) -> f32 {\n let offset=select(0.0,0.5,noiseType()==2);\n let shifted=point+vec3f(offset,offset,0.0);\n let p=shifted-floor(shifted/65536.0)*65536.0;\n let cell=vec3i(floor(p)); let t=fract(p);\n let fz=t.z*t.z*t.z*(t.z*(t.z*6.0-15.0)+10.0);\n let n=mix(sliceNoise(cell,t.xy,seed),sliceNoise(cell+vec3i(0,0,1),t.xy,seed),fz);\n return select(n,0.5+(n-0.5)*(181.0/231.0)/0.55,noiseType()==2);\n}\n\nfn noiseLayer(p: vec2f,z: f32,seed: u32) -> f32 {\n if(params.cycleEvolution==0.0) { return valueNoise(vec3f(p,params.evolution+z),seed); }\n let t=params.evolution-floor(params.evolution/params.cycle)*params.cycle;\n let weight=smoothstep(0.0,1.0,t/params.cycle);\n return mix(valueNoise(vec3f(p,t+z),seed),valueNoise(vec3f(p,t-params.cycle+z),seed),weight);\n}\nfn turbulence(p: vec2f,channel: u32) -> f32 {\n var sum=0.0; var norm=0.0; var amplitude=1.0; var frequency=1.0;\n let falloff=select(0.5,0.3,params.displacement>=3.0 && params.displacement<=5.0);\n for(var octave=0;octave<10;octave++) {\n let weight=clamp(params.complexity-f32(octave),0.0,1.0);\n if(weight==0.0) { break; }\n let seed=(params.seed ^ 0x7d15u)+channel+u32(octave)*101u;\n sum += noiseLayer(p*frequency,f32(octave)*5.17,seed)*amplitude*weight;\n norm += amplitude*weight; amplitude *= falloff; frequency *= 2.0;\n }\n return sum/norm-0.5;\n}\nfn readPixel(p: vec2i) -> vec4f {\n if(any(p<vec2i(0)) || any(p>=vec2i(params.size))) { return vec4f(0); }\n let sourceSize=vec2i(textureDimensions(source));\n let sourcePixel=p+vec2i(0,sourceSize.y-i32(params.size.y));\n if(any(sourcePixel<vec2i(0)) || any(sourcePixel>=sourceSize)) { return vec4f(0); }\n return textureLoad(source,sourcePixel,0);\n}\nfn sampleSource(p: vec2f) -> vec4f {\n let base=vec2i(floor(p-vec2f(0.5))); let t=fract(p-vec2f(0.5));\n return mix(mix(readPixel(base),readPixel(base+vec2i(1,0)),t.x),mix(readPixel(base+vec2i(0,1)),readPixel(base+vec2i(1,1)),t.x),t.y);\n}\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n if(params.amount==0.0) { return textureSampleLevel(source,sourceSampler,input.uv,0); }\n let pixel=input.uv*params.size;\n let p=(pixel-params.offset*params.size)/params.scale;\n let mode=i32(params.displacement);\n var displacement: vec2f;\n if(mode==1 || mode==2 || mode==4 || mode==5) {\n let epsilon=0.05;\n let gradient=vec2f(turbulence(p+vec2f(epsilon,0),0u)-turbulence(p-vec2f(epsilon,0),0u),turbulence(p+vec2f(0,epsilon),0u)-turbulence(p-vec2f(0,epsilon),0u))/(2.0*epsilon);\n displacement=select(vec2f(-gradient.y,gradient.x),gradient,mode==1 || mode==4)*params.amount*0.25;\n } else if(mode==6) { displacement=vec2f(0,turbulence(p,17u)*params.amount); }\n else if(mode==7) { displacement=vec2f(turbulence(p,0u)*params.amount,0); }\n else if(mode==8) { displacement=vec2f(turbulence(p,0u)*params.amount); }\n else { displacement=vec2f(turbulence(p,0u),turbulence(p,17u))*params.amount; }\n let locked=params.pinning>=8.0;\n let pin=select(params.pinning,params.pinning-7.0,locked);\n let edge=max(1.0,min(params.size.x,params.size.y)*select(0.1,0.25,locked));\n let nearEdge=clamp((pixel-vec2f(0.5))/edge,vec2f(0),vec2f(1));\n let farEdge=clamp((params.size-vec2f(0.5)-pixel)/edge,vec2f(0),vec2f(1));\n let horizontal=min(nearEdge.x,farEdge.x); let vertical=min(nearEdge.y,farEdge.y);\n var weight=1.0;\n if(pin==1.0) { weight=min(horizontal,vertical); }\n if(pin==2.0) { weight=vertical; } if(pin==3.0) { weight=horizontal; }\n if(pin==4.0) { weight=nearEdge.x; } if(pin==5.0) { weight=nearEdge.y; }\n if(pin==6.0) { weight=farEdge.x; } if(pin==7.0) { weight=farEdge.y; }\n var sourcePixel=pixel+displacement*weight;\n if(locked) { sourcePixel=clamp(sourcePixel,vec2f(0.5),params.size-vec2f(0.5)); }\n return sampleSource(sourcePixel);\n}\n\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VALUE_NOISE_WEBGPU_SHADER = "\nfn lattice(point: vec3i, seed: u32) -> f32 {\n let p = bitcast<vec3u>(point) & vec3u(65535u);\n var h = (p.x*0x27d4eb2du) ^ (p.y*0x165667b1u) ^ (p.z*0x9e3779b9u) ^ (seed*0x85ebca6bu);\n h ^= h >> 15u; h *= 0x2c1b3c6du; h ^= h >> 12u; h *= 0x297a2d39u; h ^= h >> 15u;\n return f32(h & 65535u)/65535.0;\n}\nfn catmull(p: vec4f, t: f32) -> f32 {\n return 0.5*(2.0*p.y+(p.z-p.x)*t+(2.0*p.x-5.0*p.y+4.0*p.z-p.w)*t*t+(3.0*p.y-p.x-3.0*p.z+p.w)*t*t*t);\n}\nfn bspline(t: f32) -> vec3f { return vec3f(0.5*(1.0-t)*(1.0-t),0.5+t*(1.0-t),0.5*t*t); }\nfn sliceNoise(p: vec3i,t: vec2f,seed: u32) -> f32 {\n if(noiseType()==0) { return lattice(p,seed); }\n if(noiseType()==1) { return mix(mix(lattice(p,seed),lattice(p+vec3i(1,0,0),seed),t.x),mix(lattice(p+vec3i(0,1,0),seed),lattice(p+vec3i(1,1,0),seed),t.x),t.y); }\n if(noiseType()==2) {\n let wx=bspline(t.x); let wy=bspline(t.y); var result=0.0;\n for(var y=0;y<3;y++) { for(var x=0;x<3;x++) { result += wx[x]*wy[y]*lattice(p+vec3i(x-1,y-1,0),seed); } }\n return result;\n }\n var rows: vec4f;\n for(var y=0;y<4;y++) {\n var row: vec4f;\n for(var x=0;x<4;x++) { row[x]=lattice(p+vec3i(x-1,y-1,0),seed); }\n rows[y]=catmull(row,t.x);\n }\n return catmull(rows,t.y);\n}\nfn valueNoise(point: vec3f,seed: u32) -> f32 {\n let offset=select(0.0,0.5,noiseType()==2);\n let shifted=point+vec3f(offset,offset,0.0);\n let p=shifted-floor(shifted/65536.0)*65536.0;\n let cell=vec3i(floor(p)); let t=fract(p);\n let fz=t.z*t.z*t.z*(t.z*(t.z*6.0-15.0)+10.0);\n let n=mix(sliceNoise(cell,t.xy,seed),sliceNoise(cell+vec3i(0,0,1),t.xy,seed),fz);\n return select(n,0.5+(n-0.5)*(181.0/231.0)/0.55,noiseType()==2);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VIGNETTE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\nstruct Params { shape: vec4f, color: vec4f, center: vec2f, mode: f32, padding: f32 }\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let color = textureSampleLevel(source, sourceSampler, input.uv, 0.0);\n let centered = abs(input.uv - params.center) * 2.0;\n let distanceFromCenter = mix(max(centered.x, centered.y), length(centered), params.shape.w);\n var mask: f32;\n if (params.shape.z <= 0.0001) {\n mask = select(0.0, params.shape.x, distanceFromCenter >= params.shape.y);\n } else {\n mask = smoothstep(params.shape.y, params.shape.y + params.shape.z, distanceFromCenter) * params.shape.x;\n }\n if (params.mode == 1.0) { return color * (1.0 - mask); }\n let overlayAlpha = mask * params.color.a;\n return vec4f(params.color.rgb * overlayAlpha + color.rgb * (1.0 - overlayAlpha), overlayAlpha + color.a * (1.0 - overlayAlpha));\n}\n";
|
|
@@ -20,10 +20,11 @@ type ApplyWaveParams = {
|
|
|
20
20
|
readonly source: CanvasImageSource;
|
|
21
21
|
readonly width: number;
|
|
22
22
|
readonly height: number;
|
|
23
|
+
readonly flipSourceY: boolean;
|
|
23
24
|
readonly amplitude: number;
|
|
24
25
|
readonly wavelength: number;
|
|
25
26
|
readonly phase: number;
|
|
26
27
|
readonly direction: 'horizontal' | 'vertical';
|
|
27
28
|
};
|
|
28
|
-
export declare const applyWave: ({ state, source, width, height, amplitude, wavelength, phase, direction, }: ApplyWaveParams) => void;
|
|
29
|
+
export declare const applyWave: ({ state, source, width, height, flipSourceY, amplitude, wavelength, phase, direction, }: ApplyWaveParams) => void;
|
|
29
30
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WAVE_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\nstruct Params { resolutionAndWave: vec4f, phaseAndDirection: vec4f, }\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let resolution = params.resolutionAndWave.xy;\n let amplitude = params.resolutionAndWave.z;\n let wavelength = max(params.resolutionAndWave.w, 0.001);\n let phase = params.phaseAndDirection.x;\n var uv = input.uv;\n if (params.phaseAndDirection.y == 0.0) {\n let coord = input.uv.x * resolution.x;\n let offset = sin((coord / wavelength) * 6.28318530718 + phase) * amplitude;\n uv.y += offset / resolution.y;\n } else {\n let coord = (1.0 - input.uv.y) * resolution.y;\n let offset = sin((coord / wavelength) * 6.28318530718 + phase) * amplitude;\n uv.x -= offset / resolution.x;\n }\n return textureSampleLevel(source, sourceSampler, uv, 0);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WAVES_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\n@group(0) @binding(0) var sourceTexture: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var palette: texture_2d<f32>;\nstruct Params {\n geometry: vec4f,\n stripe: vec4f,\n flags: vec4f,\n wave: vec4f,\n}\nfn sampleSource(uv: vec2f) -> vec4f {\n return textureSampleLevel(sourceTexture, sourceSampler, vec2f(uv.x, 1.0 - uv.y), 0);\n}\nfn glslModulo(value: f32, divisor: f32) -> f32 { return value - divisor * floor(value / divisor); }\nfn paletteColor(index: f32) -> vec4f { return textureLoad(palette, vec2i(i32(index), 0), 0); }\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let vUv = vec2f(input.uv.x, 1.0 - input.uv.y);\n\n let texColor = sampleSource(vUv);\n let thickness = max(params.stripe.x, 0.001);\n let spacing = max(params.stripe.y, 0.001);\n let cycle = spacing * params.geometry.z;\n let centered = vec2f(input.position.x, params.geometry.y - input.position.y) - params.geometry.xy * 0.5;\n let s = sin(params.stripe.z);\n let c = cos(params.stripe.z);\n let rotated = vec2f(centered.x * c - centered.y * s, centered.x * s + centered.y * c);\n var axis = select(rotated.x, rotated.y, params.geometry.w == 0.0);\n let waveAxis = select(rotated.y, rotated.x, params.geometry.w == 0.0);\naxis += sin((waveAxis / max(params.wave.y, 0.001)) * 6.283185307179586 + params.wave.z) * params.wave.x;\n\n var position = glslModulo(axis + params.stripe.w, cycle);\n if (position < 0.0) { position += cycle; }\n let colorIndex = floor(position / spacing);\n let inStripe = glslModulo(position, spacing);\n if (inStripe > thickness) { return texColor; }\n\n let overlay = paletteColor(colorIndex);\n let premultiplied = overlay.rgb * overlay.a;\n if (params.flags.x != 0.0) {\n return vec4f(premultiplied * texColor.a + texColor.rgb * (1.0 - overlay.a), texColor.a);\n }\n return vec4f(premultiplied + texColor.rgb * (1.0 - overlay.a), overlay.a + texColor.a * (1.0 - overlay.a));\n\n}\n";
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export type WeatherCommonParams = {
|
|
2
|
+
/** Elapsed time in seconds. Must be nonnegative. Defaults to `0`. */
|
|
3
|
+
readonly time?: number;
|
|
4
|
+
/** Particle size, from `0` to `50`. Defaults to `1` for rain and `3` for snow. */
|
|
5
|
+
readonly size?: number;
|
|
6
|
+
/** Depth of the particle field, from `0` to `20000`. Defaults to `5000`. */
|
|
7
|
+
readonly sceneDepth?: number;
|
|
8
|
+
/** Fall speed. Defaults to `4000` for rain and `100` for snow. */
|
|
9
|
+
readonly speed?: number;
|
|
10
|
+
/** Horizontal wind strength. Positive values move right. Defaults to `0` for rain and `25` for snow. */
|
|
11
|
+
readonly wind?: number;
|
|
12
|
+
/** Per-particle wind variation, from `0` to `1`. Defaults to `0` for rain and `0.5` for snow. */
|
|
13
|
+
readonly windVariation?: number;
|
|
14
|
+
/** Random horizontal velocity spread, from `0` to `1000`. Defaults to `0`. */
|
|
15
|
+
readonly spread?: number;
|
|
16
|
+
/** Particle color. Its alpha multiplies opacity. Defaults to `#cccccc` for rain and `#ffffff` for snow. */
|
|
17
|
+
readonly color?: string;
|
|
18
|
+
/** Particle opacity, from `0` to `1`. Defaults to `0.25` for rain and `1` for snow. */
|
|
19
|
+
readonly opacity?: number;
|
|
20
|
+
/** Blend with the source. Defaults to `lighten` for rain and `composite` for snow. */
|
|
21
|
+
readonly transferMode?: 'composite' | 'lighten';
|
|
22
|
+
/** Include the source behind the particles. Defaults to `true`. */
|
|
23
|
+
readonly compositeWithOriginal?: boolean;
|
|
24
|
+
/** Normalized pattern position. `[0.5, 0.5]` leaves it centered, the default. */
|
|
25
|
+
readonly offset?: readonly [number, number];
|
|
26
|
+
/** Unsigned 32-bit integer for a repeatable particle field. Defaults to `0`. */
|
|
27
|
+
readonly seed?: number;
|
|
28
|
+
};
|
|
29
|
+
export type WeatherCommonResolved = Required<WeatherCommonParams>;
|
|
30
|
+
export declare const COMMON_WEATHER_DEFAULTS: {
|
|
31
|
+
readonly time: 0;
|
|
32
|
+
readonly sceneDepth: 5000;
|
|
33
|
+
readonly spread: 0;
|
|
34
|
+
readonly compositeWithOriginal: true;
|
|
35
|
+
readonly offset: readonly [0.5, 0.5];
|
|
36
|
+
readonly seed: 0;
|
|
37
|
+
};
|
|
38
|
+
export declare const createWeatherSchema: (defaults: WeatherCommonResolved, maxSpeed: number, maxWind: number) => {
|
|
39
|
+
readonly time: {
|
|
40
|
+
readonly type: 'number';
|
|
41
|
+
readonly min: 0;
|
|
42
|
+
readonly max: 10;
|
|
43
|
+
readonly step: 0.01;
|
|
44
|
+
readonly default: number;
|
|
45
|
+
readonly description: 'Time';
|
|
46
|
+
readonly hiddenFromList: false;
|
|
47
|
+
};
|
|
48
|
+
readonly size: {
|
|
49
|
+
readonly type: 'number';
|
|
50
|
+
readonly min: 0;
|
|
51
|
+
readonly max: 50;
|
|
52
|
+
readonly step: 0.01;
|
|
53
|
+
readonly default: number;
|
|
54
|
+
readonly description: 'Size';
|
|
55
|
+
readonly hiddenFromList: false;
|
|
56
|
+
};
|
|
57
|
+
readonly sceneDepth: {
|
|
58
|
+
readonly type: 'number';
|
|
59
|
+
readonly min: 0;
|
|
60
|
+
readonly max: 20000;
|
|
61
|
+
readonly step: 1;
|
|
62
|
+
readonly default: number;
|
|
63
|
+
readonly description: 'Scene depth';
|
|
64
|
+
readonly hiddenFromList: false;
|
|
65
|
+
};
|
|
66
|
+
readonly speed: {
|
|
67
|
+
readonly type: 'number';
|
|
68
|
+
readonly min: 0;
|
|
69
|
+
readonly max: number;
|
|
70
|
+
readonly step: 1;
|
|
71
|
+
readonly default: number;
|
|
72
|
+
readonly description: 'Speed';
|
|
73
|
+
readonly hiddenFromList: false;
|
|
74
|
+
};
|
|
75
|
+
readonly wind: {
|
|
76
|
+
readonly type: 'number';
|
|
77
|
+
readonly min: number;
|
|
78
|
+
readonly max: number;
|
|
79
|
+
readonly step: 1;
|
|
80
|
+
readonly default: number;
|
|
81
|
+
readonly description: 'Wind';
|
|
82
|
+
readonly hiddenFromList: false;
|
|
83
|
+
};
|
|
84
|
+
readonly windVariation: {
|
|
85
|
+
readonly type: 'number';
|
|
86
|
+
readonly min: 0;
|
|
87
|
+
readonly max: 1;
|
|
88
|
+
readonly step: 0.01;
|
|
89
|
+
readonly default: number;
|
|
90
|
+
readonly description: 'Wind variation';
|
|
91
|
+
readonly hiddenFromList: false;
|
|
92
|
+
};
|
|
93
|
+
readonly spread: {
|
|
94
|
+
readonly type: 'number';
|
|
95
|
+
readonly min: 0;
|
|
96
|
+
readonly max: 1000;
|
|
97
|
+
readonly step: 1;
|
|
98
|
+
readonly default: number;
|
|
99
|
+
readonly description: 'Spread';
|
|
100
|
+
readonly hiddenFromList: false;
|
|
101
|
+
};
|
|
102
|
+
readonly opacity: {
|
|
103
|
+
readonly type: 'number';
|
|
104
|
+
readonly min: 0;
|
|
105
|
+
readonly max: 1;
|
|
106
|
+
readonly step: 0.01;
|
|
107
|
+
readonly default: number;
|
|
108
|
+
readonly description: 'Opacity';
|
|
109
|
+
readonly hiddenFromList: false;
|
|
110
|
+
};
|
|
111
|
+
readonly color: {
|
|
112
|
+
readonly type: 'color';
|
|
113
|
+
readonly default: string;
|
|
114
|
+
readonly description: 'Color';
|
|
115
|
+
};
|
|
116
|
+
readonly transferMode: {
|
|
117
|
+
readonly type: 'enum';
|
|
118
|
+
readonly variants: {
|
|
119
|
+
readonly composite: {};
|
|
120
|
+
readonly lighten: {};
|
|
121
|
+
};
|
|
122
|
+
readonly default: "composite" | "lighten";
|
|
123
|
+
readonly description: 'Transfer mode';
|
|
124
|
+
};
|
|
125
|
+
readonly compositeWithOriginal: {
|
|
126
|
+
readonly type: 'boolean';
|
|
127
|
+
readonly default: boolean;
|
|
128
|
+
readonly description: 'Composite with original';
|
|
129
|
+
};
|
|
130
|
+
readonly offset: {
|
|
131
|
+
readonly type: 'uv-coordinate';
|
|
132
|
+
readonly step: 0.01;
|
|
133
|
+
readonly default: readonly [number, number];
|
|
134
|
+
readonly description: 'Offset';
|
|
135
|
+
};
|
|
136
|
+
readonly seed: {
|
|
137
|
+
readonly type: 'number';
|
|
138
|
+
readonly min: 0;
|
|
139
|
+
readonly max: 4294967295;
|
|
140
|
+
readonly step: 1;
|
|
141
|
+
readonly integer: true;
|
|
142
|
+
readonly default: number;
|
|
143
|
+
readonly description: 'Seed';
|
|
144
|
+
readonly hiddenFromList: false;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export declare const resolveWeatherParams: (params: WeatherCommonParams, defaults: WeatherCommonResolved) => WeatherCommonResolved;
|
|
148
|
+
export declare const validateWeatherRange: (value: number | undefined, name: string, min: number, max: number | null) => void;
|
|
149
|
+
export declare const validateWeatherParams: (params: WeatherCommonParams, label: string, maxSpeed: number, maxWind: number) => void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ParsedColorRgba } from '../color-utils.js';
|
|
2
|
+
export type WeatherRenderParams = {
|
|
3
|
+
readonly time: number;
|
|
4
|
+
readonly count: number;
|
|
5
|
+
readonly size: number;
|
|
6
|
+
readonly sizeVariation: number;
|
|
7
|
+
readonly sceneDepth: number;
|
|
8
|
+
readonly speed: number;
|
|
9
|
+
readonly speedVariation: number;
|
|
10
|
+
readonly wind: number;
|
|
11
|
+
readonly windVariation: number;
|
|
12
|
+
readonly spread: number;
|
|
13
|
+
readonly wiggleAmount: number;
|
|
14
|
+
readonly wiggleAmountVariation: number;
|
|
15
|
+
readonly wiggleFrequency: number;
|
|
16
|
+
readonly wiggleFrequencyVariation: number;
|
|
17
|
+
readonly color: string;
|
|
18
|
+
readonly opacity: number;
|
|
19
|
+
readonly transferMode: 'composite' | 'lighten';
|
|
20
|
+
readonly compositeWithOriginal: boolean;
|
|
21
|
+
readonly appearance: 'refracting' | 'soft-solid';
|
|
22
|
+
readonly offset: readonly [number, number];
|
|
23
|
+
readonly seed: number;
|
|
24
|
+
};
|
|
25
|
+
export type WeatherState = {
|
|
26
|
+
readonly gl: WebGL2RenderingContext;
|
|
27
|
+
readonly program: WebGLProgram;
|
|
28
|
+
readonly compositeProgram: WebGLProgram;
|
|
29
|
+
readonly vao: WebGLVertexArrayObject;
|
|
30
|
+
readonly sourceTexture: WebGLTexture;
|
|
31
|
+
readonly weatherTexture: WebGLTexture;
|
|
32
|
+
readonly framebuffer: WebGLFramebuffer;
|
|
33
|
+
readonly uniforms: Record<string, WebGLUniformLocation | null>;
|
|
34
|
+
readonly compositeUniforms: Record<string, WebGLUniformLocation | null>;
|
|
35
|
+
readonly colorCtx: CanvasRenderingContext2D;
|
|
36
|
+
readonly floatingPoint: boolean;
|
|
37
|
+
cachedColor: string | null;
|
|
38
|
+
cachedColorRgba: ParsedColorRgba;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
};
|
|
42
|
+
export declare const setupWeather: (target: HTMLCanvasElement, effectName: string) => WeatherState;
|
|
43
|
+
export declare const drawWeather: ({ state, source, width, height, flipSourceY, params, type, }: {
|
|
44
|
+
state: WeatherState;
|
|
45
|
+
source: TexImageSource;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
flipSourceY: boolean;
|
|
49
|
+
params: WeatherRenderParams;
|
|
50
|
+
type: 'rain' | 'snow';
|
|
51
|
+
}) => void;
|
|
52
|
+
export declare const cleanupWeather: (state: WeatherState) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const WEATHER_VERTEX_SHADER = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform sampler2D uSource;\nuniform vec2 uResolution;\nuniform int uSnow;\nuniform float uTime;\nuniform uint uSeed;\nuniform vec2 uOffset;\nuniform float uSize;\nuniform float uSizeVariation;\nuniform float uSceneDepth;\nuniform float uSpeed;\nuniform float uSpeedVariation;\nuniform float uWind;\nuniform float uWindVariation;\nuniform float uSpread;\nuniform float uWiggleAmount;\nuniform float uWiggleAmountVariation;\nuniform float uWiggleFrequency;\nuniform float uWiggleFrequencyVariation;\nuniform vec4 uColor;\nuniform float uOpacity;\nuniform int uRefract;\n\nflat out vec2 vPosition;\nflat out vec2 vLine;\nflat out float vRadius;\nflat out vec4 vColor;\n\nfloat noise(uint i, uint key) {\n\tuint h = i * 0x8da6b343u ^ key * 0xd8163841u ^ uSeed * 0xcb1ab31fu;\n\th ^= h >> 13;\n\th *= 0x5bd1e995u;\n\th ^= h >> 15;\n\treturn float(h & 0x00ffffffu) / 16777216.0;\n}\n\nfloat signedNoise(uint i, uint key) {\n\treturn noise(i, key) * 2.0 - 1.0;\n}\n\nfloat wrap(float value, float margin, float size) {\n\treturn -margin + mod(value + margin, size + 2.0 * margin);\n}\n\nvec4 sourcePixel(ivec2 p) {\n\tivec2 size = textureSize(uSource, 0);\n\tif (p.x < 0 || p.y < 0 || p.x >= size.x || p.y >= size.y) {\n\t\treturn vec4(0.0);\n\t}\n\treturn texelFetch(uSource, ivec2(p.x, size.y - 1 - p.y), 0);\n}\n\n// Bilinear sampling with transparent borders, at pixel centers of +0.5.\nvec4 sourceAt(vec2 position) {\n\tvec2 p = position - 0.5;\n\tivec2 base = ivec2(floor(p));\n\tvec2 f = fract(p);\n\treturn mix(\n\t\tmix(sourcePixel(base), sourcePixel(base + ivec2(1, 0)), f.x),\n\t\tmix(sourcePixel(base + ivec2(0, 1)), sourcePixel(base + ivec2(1, 1)), f.x),\n\t\tf.y\n\t);\n}\n\nvoid main() {\n\tuint i = uint(gl_InstanceID);\n\tfloat depth = 1.0 / (1.0 + noise(i, 1u) * uSceneDepth / 2500.0);\n\tvec2 offset = (uOffset - 0.5) * uResolution;\n\tvec2 position;\n\tvec2 line = vec2(0.0);\n\tfloat radius;\n\tfloat alpha;\n\tif (uSnow == 1) {\n\t\tradius = max(uSize * 0.5 * depth * (1.0 + uSizeVariation * signedNoise(i, 2u)), 0.05);\n\t\tfloat speed = uSpeed * (uResolution.y / 600.0) * depth * (1.0 + uSpeedVariation * signedNoise(i, 3u));\n\t\tfloat wind = uWind * (uResolution.y / 1200.0) * depth * (1.0 + uWindVariation * signedNoise(i, 4u))\n\t\t\t+ uSpread * signedNoise(i, 8u) * depth;\n\t\tfloat amplitude = uWiggleAmount * 2.0 * depth * (1.0 + uWiggleAmountVariation * signedNoise(i, 5u));\n\t\tfloat frequency = uWiggleFrequency * (1.0 + uWiggleFrequencyVariation * signedNoise(i, 6u));\n\t\tfloat phase = noise(i, 9u) * 6.283185307179586;\n\t\tfloat margin = radius + abs(amplitude) + 2.0;\n\t\tposition.y = wrap(noise(i, 10u) * (uResolution.y + 2.0 * margin) + speed * uTime + offset.y, margin, uResolution.y);\n\t\tposition.x = wrap(noise(i, 11u) * (uResolution.x + 2.0 * margin) + wind * uTime + offset.x, margin, uResolution.x)\n\t\t\t+ amplitude * sin(frequency * uTime * 6.283185307179586 + phase);\n\t\talpha = uOpacity * (0.4 + 0.6 * depth);\n\t} else {\n\t\tfloat speed = uSpeed / 4000.0 * uResolution.y * 2.2 * depth;\n\t\tfloat wind = uWind / 1000.0 * uResolution.y * (1.0 + uWindVariation * signedNoise(i, 2u)) * depth\n\t\t\t+ uSpread * signedNoise(i, 7u) * depth;\n\t\tfloat length = max(speed * 0.04 * max(uSize, 0.2), 1.0);\n\t\tfloat horizontalLength = wind * 0.04 * max(uSize, 0.2);\n\t\tfloat margin = length + abs(horizontalLength) + 4.0;\n\t\tposition.y = wrap(noise(i, 3u) * (uResolution.y + 2.0 * margin) + speed * uTime + offset.y, margin, uResolution.y);\n\t\tposition.x = wrap(noise(i, 4u) * (uResolution.x + 2.0 * margin) + wind * uTime + offset.x, margin, uResolution.x);\n\t\tline = vec2(-horizontalLength, -length);\n\t\tradius = max(uSize * 0.6 * depth, 0.25);\n\t\talpha = uOpacity * (0.35 + 0.65 * depth);\n\t}\n\n\tvec3 color = uColor.rgb;\n\tif (uSnow == 0 && uRefract == 1) {\n\t\tvec4 sampleColor = sourceAt(position + vec2(2.0, 0.0));\n\t\tif (sampleColor.a > 0.0) {\n\t\t\tvec3 straight = sampleColor.a > 0.000001 ? sampleColor.rgb / sampleColor.a : vec3(0.0);\n\t\t\tcolor *= straight * 0.6 + 0.5;\n\t\t}\n\t}\n\n\tvPosition = position;\n\tvLine = line;\n\tvRadius = radius;\n\tvColor = vec4(color, alpha * uColor.a);\n\tfloat padding = max(radius, 0.5) + 1.0;\n\tvec2 minimum = min(position, position + line) - padding;\n\tvec2 maximum = max(position, position + line) + padding;\n\tvec2 corner = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1));\n\tvec2 pixel = mix(minimum, maximum, corner);\n\tgl_Position = vec4(pixel.x / uResolution.x * 2.0 - 1.0, 1.0 - pixel.y / uResolution.y * 2.0, 0.0, 1.0);\n}\n";
|
|
2
|
+
export declare const WEATHER_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform vec2 uResolution;\nuniform int uSnow;\n\nflat in vec2 vPosition;\nflat in vec2 vLine;\nflat in float vRadius;\nflat in vec4 vColor;\nout vec4 fragColor;\n\nvoid main() {\n\tif (vColor.a <= 0.00001) discard;\n\tvec2 delta = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) - vPosition;\n\tfloat radius = max(vRadius, 0.5);\n\tfloat fade = min(vRadius / 0.5, 1.0);\n\tfloat coverage;\n\tif (uSnow == 1) {\n\t\tfloat distanceSquared = dot(delta, delta) / (radius * radius);\n\t\tif (distanceSquared >= 1.0) discard;\n\t\tfloat q = 1.0 - distanceSquared;\n\t\tcoverage = q * q;\n\t} else {\n\t\tfloat lengthSquared = dot(vLine, vLine);\n\t\tfloat along = lengthSquared > 0.0 ? clamp(dot(delta, vLine) / lengthSquared, 0.0, 1.0) : 0.0;\n\t\tcoverage = clamp(radius - length(delta - vLine * along) + 0.5, 0.0, 1.0);\n\t}\n\tfloat alpha = coverage * vColor.a * fade;\n\tif (alpha <= 0.000001) discard;\n\tfragColor = vec4(vColor.rgb * alpha, alpha);\n}\n";
|
|
3
|
+
export declare const WEATHER_COMPOSITE_VERTEX_SHADER = "#version 300 es\nout vec2 vUv;\n\nvoid main() {\n\tvUv = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1));\n\tgl_Position = vec4(vUv * 2.0 - 1.0, 0.0, 1.0);\n}\n";
|
|
4
|
+
export declare const WEATHER_COMPOSITE_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\n\nuniform sampler2D uSource;\nuniform sampler2D uWeather;\nuniform int uCompositeWithOriginal;\nuniform int uLighten;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nvoid main() {\n\tvec4 weather = texture(uWeather, vUv);\n\tif (uCompositeWithOriginal == 0) {\n\t\tfragColor = weather;\n\t\treturn;\n\t}\n\tvec4 source = texture(uSource, vUv);\n\tif (uLighten == 1) {\n\t\tfragColor = vec4(max(source.rgb, weather.rgb), source.a + weather.a - source.a * weather.a);\n\t} else {\n\t\tfragColor = weather + source * (1.0 - weather.a);\n\t}\n}\n";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ParsedColorRgba } from '../color-utils.js';
|
|
2
|
+
import type { WeatherRenderParams } from './runtime.js';
|
|
3
|
+
export type WeatherWebGpuState = {
|
|
4
|
+
readonly context: GPUCanvasContext;
|
|
5
|
+
readonly colorCtx: CanvasRenderingContext2D;
|
|
6
|
+
cachedColor: string | null;
|
|
7
|
+
cachedColorRgba: ParsedColorRgba;
|
|
8
|
+
resources: {
|
|
9
|
+
readonly device: GPUDevice;
|
|
10
|
+
readonly particles: GPURenderPipeline;
|
|
11
|
+
readonly composite: GPURenderPipeline;
|
|
12
|
+
readonly uniforms: GPUBuffer;
|
|
13
|
+
readonly sampler: GPUSampler;
|
|
14
|
+
textures: {
|
|
15
|
+
readonly source: GPUTexture;
|
|
16
|
+
readonly weather: GPUTexture;
|
|
17
|
+
readonly particleGroup: GPUBindGroup;
|
|
18
|
+
readonly compositeGroup: GPUBindGroup;
|
|
19
|
+
readonly width: number;
|
|
20
|
+
readonly height: number;
|
|
21
|
+
readonly sourceWidth: number;
|
|
22
|
+
readonly sourceHeight: number;
|
|
23
|
+
} | null;
|
|
24
|
+
} | null;
|
|
25
|
+
};
|
|
26
|
+
export declare const setupWeatherWebGpu: (target: HTMLCanvasElement) => WeatherWebGpuState;
|
|
27
|
+
export declare const cleanupWeatherWebGpu: (state: WeatherWebGpuState) => void;
|
|
28
|
+
export declare const drawWeatherWebGpu: ({ state, source, width, height, device, params, type, }: {
|
|
29
|
+
state: WeatherWebGpuState;
|
|
30
|
+
source: CanvasImageSource;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
device: GPUDevice;
|
|
34
|
+
params: WeatherRenderParams;
|
|
35
|
+
type: 'rain' | 'snow';
|
|
36
|
+
}) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WEATHER_WEBGPU_SHADER = "\n\nstruct VertexOutput {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n}\n\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> VertexOutput {\n\tlet positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n\tlet position = positions[index];\n\tvar output: VertexOutput;\n\toutput.position = vec4f(position, 0, 1);\n\toutput.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5);\n\treturn output;\n}\n\nstruct Params {\n resolution: vec2f, offset: vec2f, color: vec4f,\n snow: f32, time: f32, seed: u32, size: f32,\n sizeVariation: f32, sceneDepth: f32, speed: f32, speedVariation: f32,\n wind: f32, windVariation: f32, spread: f32, wiggleAmount: f32,\n wiggleAmountVariation: f32, wiggleFrequency: f32, wiggleFrequencyVariation: f32, opacity: f32,\n refract: f32, composite: f32, lighten: f32, padding: f32,\n}\nstruct ParticleOutput {\n @builtin(position) position: vec4f,\n @location(0) @interpolate(flat) particlePosition: vec2f,\n @location(1) @interpolate(flat) line: vec2f,\n @location(2) @interpolate(flat) radius: f32,\n @location(3) @interpolate(flat) color: vec4f,\n}\n@group(0) @binding(0) var source: texture_2d<f32>;\n@group(0) @binding(1) var sourceSampler: sampler;\n@group(0) @binding(2) var<uniform> params: Params;\n@group(0) @binding(3) var weather: texture_2d<f32>;\nfn noise(i: u32, key: u32) -> f32 {\n\tvar h: u32 = (i * 0x8da6b343u) ^ (key * 0xd8163841u) ^ (params.seed * 0xcb1ab31fu);\n\th ^= h >> 13u;\n\th *= 0x5bd1e995u;\n\th ^= h >> 15u;\n\treturn f32(h & 0x00ffffffu) / 16777216.0;\n}\n\nfn signedNoise(i: u32, key: u32) -> f32 {\n\treturn noise(i, key) * 2.0 - 1.0;\n}\n\nfn wrap(value: f32, margin: f32, size: f32) -> f32 {\n\treturn -margin + (value + margin - floor((value + margin)/(size + 2.0*margin))*(size+2.0*margin));\n}\n\nfn sourcePixel(p: vec2i) -> vec4f {\n\tvar size: vec2i = vec2i(textureDimensions(source));\n\tif (p.x < 0 || p.y < 0 || p.x >= size.x || p.y >= size.y) {\n\t\treturn vec4f(0.0);\n\t}\n\treturn textureLoad(source,p,0);\n}\n\n// Bilinear sampling with transparent borders, at pixel centers of +0.5.\nfn sourceAt(position: vec2f) -> vec4f {\n\tvar p: vec2f = position - vec2f(0.5);\n\tvar base: vec2i = vec2i(floor(p));\n\tvar f: vec2f = fract(p);\n\treturn mix(\n\t\tmix(sourcePixel(base), sourcePixel(base + vec2i(1, 0)), f.x),\n\t\tmix(sourcePixel(base + vec2i(0, 1)), sourcePixel(base + vec2i(1, 1)), f.x),\n\t\tf.y\n\t);\n}\n\n@vertex fn particleVertex(@builtin(vertex_index) vertexIndex: u32, @builtin(instance_index) instanceIndex: u32) -> ParticleOutput {\n var output: ParticleOutput;\n\tvar i: u32 = instanceIndex;\n\tvar depth: f32 = 1.0 / (1.0 + noise(i, 1u) * params.sceneDepth / 2500.0);\n\tvar offset: vec2f = (params.offset - vec2f(0.5)) * params.resolution;\n\tvar position: vec2f ;\n\tvar line: vec2f = vec2f(0.0);\n\tvar radius: f32 ;\n\tvar alpha: f32 ;\n\tif (params.snow == 1) {\n\t\tradius = max(params.size * 0.5 * depth * (1.0 + params.sizeVariation * signedNoise(i, 2u)), 0.05);\n\t\tvar speed: f32 = params.speed * (params.resolution.y / 600.0) * depth * (1.0 + params.speedVariation * signedNoise(i, 3u));\n\t\tvar wind: f32 = params.wind * (params.resolution.y / 1200.0) * depth * (1.0 + params.windVariation * signedNoise(i, 4u))\n\t\t\t+ params.spread * signedNoise(i, 8u) * depth;\n\t\tvar amplitude: f32 = params.wiggleAmount * 2.0 * depth * (1.0 + params.wiggleAmountVariation * signedNoise(i, 5u));\n\t\tvar frequency: f32 = params.wiggleFrequency * (1.0 + params.wiggleFrequencyVariation * signedNoise(i, 6u));\n\t\tvar phase: f32 = noise(i, 9u) * 6.283185307179586;\n\t\tvar margin: f32 = radius + abs(amplitude) + 2.0;\n\t\tposition.y = wrap(noise(i, 10u) * (params.resolution.y + 2.0 * margin) + speed * params.time + offset.y, margin, params.resolution.y);\n\t\tposition.x = wrap(noise(i, 11u) * (params.resolution.x + 2.0 * margin) + wind * params.time + offset.x, margin, params.resolution.x)\n\t\t\t+ amplitude * sin(frequency * params.time * 6.283185307179586 + phase);\n\t\talpha = params.opacity * (0.4 + 0.6 * depth);\n\t} else {\n\t\tvar speed: f32 = params.speed / 4000.0 * params.resolution.y * 2.2 * depth;\n\t\tvar wind: f32 = params.wind / 1000.0 * params.resolution.y * (1.0 + params.windVariation * signedNoise(i, 2u)) * depth\n\t\t\t+ params.spread * signedNoise(i, 7u) * depth;\n\t\tvar length: f32 = max(speed * 0.04 * max(params.size, 0.2), 1.0);\n\t\tvar horizontalLength: f32 = wind * 0.04 * max(params.size, 0.2);\n\t\tvar margin: f32 = length + abs(horizontalLength) + 4.0;\n\t\tposition.y = wrap(noise(i, 3u) * (params.resolution.y + 2.0 * margin) + speed * params.time + offset.y, margin, params.resolution.y);\n\t\tposition.x = wrap(noise(i, 4u) * (params.resolution.x + 2.0 * margin) + wind * params.time + offset.x, margin, params.resolution.x);\n\t\tline = vec2f(-horizontalLength, -length);\n\t\tradius = max(params.size * 0.6 * depth, 0.25);\n\t\talpha = params.opacity * (0.35 + 0.65 * depth);\n\t}\n\n\tvar color: vec3f = params.color.rgb;\n\tif (params.snow == 0 && params.refract == 1) {\n\t\tvar sampleColor: vec4f = sourceAt(position + vec2f(2.0, 0.0));\n\t\tif (sampleColor.a > 0.0) {\n\t\t\tvar straight: vec3f = select(vec3f(0),sampleColor.rgb/max(sampleColor.a,0.000001),sampleColor.a>0.000001);\n\t\t\tcolor *= straight * 0.6 + vec3f(0.5);\n\t\t}\n\t}\n\n\toutput.particlePosition = position;\n\toutput.line = line;\n\toutput.radius = radius;\n\toutput.color = vec4f(color, alpha * params.color.a);\n\tvar padding: f32 = max(radius, 0.5) + 1.0;\n\tvar minimum: vec2f = min(position, position + line) - vec2f(padding);\n\tvar maximum: vec2f = max(position, position + line) + vec2f(padding);\n\tvar corner: vec2f = vec2f(f32(vertexIndex & 1u), f32(vertexIndex >> 1u));\n\tvar pixel: vec2f = mix(minimum, maximum, corner);\n\toutput.position = vec4f(pixel.x / params.resolution.x * 2.0 - 1.0, 1.0 - pixel.y / params.resolution.y * 2.0, 0.0, 1.0);\nreturn output;\n}\n@fragment fn particleFragment(input: ParticleOutput) -> @location(0) vec4f {\n\tif (input.color.a <= 0.00001) { discard; }\n\tvar delta: vec2f = input.position.xy - input.particlePosition;\n\tvar radius: f32 = max(input.radius, 0.5);\n\tvar fade: f32 = min(input.radius / 0.5, 1.0);\n\tvar coverage: f32 ;\n\tif (params.snow == 1) {\n\t\tvar distanceSquared: f32 = dot(delta, delta) / (radius * radius);\n\t\tif (distanceSquared >= 1.0) { discard; }\n\t\tvar q: f32 = 1.0 - distanceSquared;\n\t\tcoverage = q * q;\n\t} else {\n\t\tvar lengthSquared: f32 = dot(input.line, input.line);\n\t\tvar along: f32 = select(0.0,clamp(dot(delta, input.line)/max(lengthSquared,0.00000001),0.0,1.0),lengthSquared>0.0);\n\t\tcoverage = clamp(radius - length(delta - input.line * along) + 0.5, 0.0, 1.0);\n\t}\n\tvar alpha: f32 = coverage * input.color.a * fade;\n\tif (alpha <= 0.000001) { discard; }\n\treturn vec4f(input.color.rgb * alpha, alpha);\n}\n\n@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {\n let result=textureSampleLevel(weather,sourceSampler,input.uv,0);\n if(params.composite==0.0) { return result; }\n let original=textureSampleLevel(source,sourceSampler,input.uv,0);\n if(params.lighten==1.0) { return vec4f(max(original.rgb,result.rgb),original.a+result.a-original.a*result.a); }\n return result+original*(1.0-result.a);\n}\n";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type WebGlProjectionState = {
|
|
2
|
+
gl: WebGL2RenderingContext;
|
|
3
|
+
program: WebGLProgram;
|
|
4
|
+
texture: WebGLTexture;
|
|
5
|
+
vao: WebGLVertexArrayObject;
|
|
6
|
+
uniforms: WebGLUniformLocation | null;
|
|
7
|
+
source: WebGLUniformLocation | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const setupWebGlProjection: (target: HTMLCanvasElement, shader: string) => WebGlProjectionState;
|
|
10
|
+
export declare const applyWebGlProjection: ({ state, source, width, height, flipSourceY, uniformData, }: {
|
|
11
|
+
state: WebGlProjectionState;
|
|
12
|
+
source: CanvasImageSource;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
flipSourceY: boolean;
|
|
16
|
+
uniformData: Float32Array<ArrayBuffer>;
|
|
17
|
+
}) => void;
|
|
18
|
+
export declare const cleanupWebGlProjection: ({ gl, program, texture, vao, }: WebGlProjectionState) => void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type WebGpuSinglePassState } from './webgpu-single-pass-runtime.js';
|
|
2
|
+
export type WebGpuColorState = WebGpuSinglePassState & {
|
|
3
|
+
readonly colorContext: CanvasRenderingContext2D;
|
|
4
|
+
colors: {
|
|
5
|
+
key: string;
|
|
6
|
+
data: Uint8Array<ArrayBuffer>;
|
|
7
|
+
} | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const setupWebGpuColors: (target: HTMLCanvasElement, label: string) => WebGpuColorState;
|
|
10
|
+
export declare const getWebGpuColors: (state: WebGpuColorState, colors: readonly string[]) => Uint8Array<ArrayBuffer>;
|