@remotion/effects 4.0.535 → 4.0.537
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 +30 -0
- package/dist/bevel-alpha/index.d.ts +13 -0
- package/dist/bevel-alpha/shaders.d.ts +3 -0
- package/dist/bevel-alpha.d.ts +1 -0
- package/dist/cylinder/index.d.ts +20 -0
- package/dist/cylinder/shader.d.ts +1 -0
- package/dist/cylinder.d.ts +1 -0
- package/dist/esm/bevel-alpha.mjs +474 -0
- package/dist/esm/cylinder.mjs +390 -0
- package/dist/esm/fractal-noise.mjs +688 -0
- package/dist/esm/lens-blur.mjs +550 -0
- package/dist/esm/page-turn.mjs +405 -0
- package/dist/esm/sphere.mjs +376 -0
- package/dist/esm/turbulent-displace.mjs +652 -0
- package/dist/fractal-noise/index.d.ts +40 -0
- package/dist/fractal-noise/shader.d.ts +1 -0
- package/dist/fractal-noise.d.ts +1 -0
- package/dist/lens-blur/index.d.ts +30 -0
- package/dist/lens-blur/shader.d.ts +1 -0
- package/dist/lens-blur.d.ts +1 -0
- package/dist/page-turn/index.d.ts +20 -0
- package/dist/page-turn/shader.d.ts +1 -0
- package/dist/page-turn.d.ts +1 -0
- package/dist/sphere/index.d.ts +18 -0
- package/dist/sphere/shader.d.ts +1 -0
- package/dist/sphere.d.ts +1 -0
- package/dist/turbulent-displace/index.d.ts +28 -0
- package/dist/turbulent-displace/shader.d.ts +1 -0
- package/dist/turbulent-displace.d.ts +1 -0
- package/dist/value-noise-shader.d.ts +1 -0
- package/dist/webgpu-projection-runtime.d.ts +24 -0
- package/package.json +62 -5
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
// src/turbulent-displace/index.ts
|
|
2
|
+
import { Internals } from "remotion";
|
|
3
|
+
|
|
4
|
+
// src/validate-effect-param.ts
|
|
5
|
+
var assertEffectParamsObject = (params, effectLabel) => {
|
|
6
|
+
if (params === null || typeof params !== "object") {
|
|
7
|
+
throw new TypeError(`${effectLabel} effect requires a parameters object, but got ${JSON.stringify(params)}`);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var assertRequiredFiniteNumber = (value, name) => {
|
|
11
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
12
|
+
throw new TypeError(`"${name}" must be a finite number, but got ${JSON.stringify(value)}`);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var assertRequiredColor = (value, name) => {
|
|
16
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
17
|
+
throw new TypeError(`"${name}" must be a non-empty string, but got ${JSON.stringify(value)}`);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var assertOptionalColor = (value, name) => {
|
|
21
|
+
if (value === undefined) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
assertRequiredColor(value, name);
|
|
25
|
+
};
|
|
26
|
+
var assertOptionalBoolean = (value, name) => {
|
|
27
|
+
if (value === undefined) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (typeof value !== "boolean") {
|
|
31
|
+
throw new TypeError(`"${name}" must be a boolean, but got ${JSON.stringify(value)}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/color-utils.ts
|
|
36
|
+
var DEFAULT_AMOUNT = 1;
|
|
37
|
+
var DEFAULT_BRIGHTNESS_AMOUNT = 0;
|
|
38
|
+
var DEFAULT_HUE_DEGREES = 0;
|
|
39
|
+
var colorAmountSchema = {
|
|
40
|
+
type: "number",
|
|
41
|
+
min: 0,
|
|
42
|
+
max: 1,
|
|
43
|
+
step: 0.01,
|
|
44
|
+
default: DEFAULT_AMOUNT,
|
|
45
|
+
description: "Amount",
|
|
46
|
+
hiddenFromList: false
|
|
47
|
+
};
|
|
48
|
+
var colorMultiplierSchema = {
|
|
49
|
+
type: "number",
|
|
50
|
+
min: 0,
|
|
51
|
+
step: 0.01,
|
|
52
|
+
default: DEFAULT_AMOUNT,
|
|
53
|
+
description: "Amount",
|
|
54
|
+
hiddenFromList: false
|
|
55
|
+
};
|
|
56
|
+
var brightnessAmountSchema = {
|
|
57
|
+
type: "number",
|
|
58
|
+
min: -1,
|
|
59
|
+
max: 1,
|
|
60
|
+
step: 0.01,
|
|
61
|
+
default: DEFAULT_BRIGHTNESS_AMOUNT,
|
|
62
|
+
description: "Amount",
|
|
63
|
+
hiddenFromList: false
|
|
64
|
+
};
|
|
65
|
+
var hueDegreesSchema = {
|
|
66
|
+
type: "rotation-degrees",
|
|
67
|
+
step: 1,
|
|
68
|
+
default: DEFAULT_HUE_DEGREES,
|
|
69
|
+
description: "Degrees"
|
|
70
|
+
};
|
|
71
|
+
var assertOptionalFiniteNumber = (value, name) => {
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
assertRequiredFiniteNumber(value, name);
|
|
76
|
+
};
|
|
77
|
+
var validateUnitInterval = (value, name) => {
|
|
78
|
+
if (value < 0) {
|
|
79
|
+
throw new TypeError(`"${name}" must be >= 0, but got ${JSON.stringify(value)}`);
|
|
80
|
+
}
|
|
81
|
+
if (value > 1) {
|
|
82
|
+
throw new TypeError(`"${name}" must be <= 1, but got ${JSON.stringify(value)}`);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var validateNonNegative = (value, name) => {
|
|
86
|
+
if (value < 0) {
|
|
87
|
+
throw new TypeError(`"${name}" must be >= 0, but got ${JSON.stringify(value)}`);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var validateSignedUnitInterval = (value, name) => {
|
|
91
|
+
if (value < -1) {
|
|
92
|
+
throw new TypeError(`"${name}" must be >= -1, but got ${JSON.stringify(value)}`);
|
|
93
|
+
}
|
|
94
|
+
if (value > 1) {
|
|
95
|
+
throw new TypeError(`"${name}" must be <= 1, but got ${JSON.stringify(value)}`);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var clampColorChannel = (value) => {
|
|
99
|
+
return Math.max(0, Math.min(255, value));
|
|
100
|
+
};
|
|
101
|
+
var parseColorRgba = (ctx, color) => {
|
|
102
|
+
ctx.clearRect(0, 0, 1, 1);
|
|
103
|
+
ctx.fillStyle = color;
|
|
104
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
105
|
+
const { data } = ctx.getImageData(0, 0, 1, 1);
|
|
106
|
+
return [data[0], data[1], data[2], data[3]];
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// src/value-noise-shader.ts
|
|
110
|
+
var VALUE_NOISE_SHADER = `
|
|
111
|
+
float lattice(ivec3 point, uint seed) {
|
|
112
|
+
// Wrap lattice indices as well as coordinates so interpolation stays continuous
|
|
113
|
+
// across the period boundary, including negative coordinates.
|
|
114
|
+
uvec3 p = uvec3(point) & uvec3(65535u);
|
|
115
|
+
uint h = p.x * 0x27d4eb2du ^ p.y * 0x165667b1u ^ p.z * 0x9e3779b9u ^ seed * 0x85ebca6bu;
|
|
116
|
+
h ^= h >> 15;
|
|
117
|
+
h *= 0x2c1b3c6du;
|
|
118
|
+
h ^= h >> 12;
|
|
119
|
+
h *= 0x297a2d39u;
|
|
120
|
+
h ^= h >> 15;
|
|
121
|
+
return float(h & 65535u) / 65535.0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
float catmull(vec4 p, float t) {
|
|
125
|
+
return 0.5 * (2.0 * p.y + (p.z - p.x) * t
|
|
126
|
+
+ (2.0 * p.x - 5.0 * p.y + 4.0 * p.z - p.w) * t * t
|
|
127
|
+
+ (3.0 * p.y - p.x - 3.0 * p.z + p.w) * t * t * t);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
vec3 bspline(float t) {
|
|
131
|
+
return vec3(0.5 * (1.0-t) * (1.0-t), 0.5 + t * (1.0-t), 0.5 * t * t);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
float sliceNoise(ivec3 p, vec2 t, uint seed) {
|
|
135
|
+
if (uNoiseType == 0) return lattice(p, seed);
|
|
136
|
+
if (uNoiseType == 1) {
|
|
137
|
+
return mix(mix(lattice(p, seed), lattice(p + ivec3(1,0,0), seed), t.x),
|
|
138
|
+
mix(lattice(p + ivec3(0,1,0), seed), lattice(p + ivec3(1,1,0), seed), t.x), t.y);
|
|
139
|
+
}
|
|
140
|
+
if (uNoiseType == 2) {
|
|
141
|
+
vec3 wx = bspline(t.x);
|
|
142
|
+
vec3 wy = bspline(t.y);
|
|
143
|
+
float result = 0.0;
|
|
144
|
+
for (int y = 0; y < 3; y++) {
|
|
145
|
+
for (int x = 0; x < 3; x++) {
|
|
146
|
+
result += wx[x] * wy[y] * lattice(p + ivec3(x-1, y-1, 0), seed);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
vec4 rows;
|
|
152
|
+
for (int y = 0; y < 4; y++) {
|
|
153
|
+
vec4 row;
|
|
154
|
+
for (int x = 0; x < 4; x++) {
|
|
155
|
+
row[x] = lattice(p + ivec3(x-1, y-1, 0), seed);
|
|
156
|
+
}
|
|
157
|
+
rows[y] = catmull(row, t.x);
|
|
158
|
+
}
|
|
159
|
+
return catmull(rows, t.y);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
float valueNoise(vec3 point, uint seed) {
|
|
163
|
+
// A large period keeps conversion to integer coordinates defined at extreme scales.
|
|
164
|
+
vec3 p = mod(point + vec3(uNoiseType == 2 ? 0.5 : 0.0, uNoiseType == 2 ? 0.5 : 0.0, 0.0), 65536.0);
|
|
165
|
+
ivec3 cell = ivec3(floor(p));
|
|
166
|
+
vec3 t = fract(p);
|
|
167
|
+
float fz = t.z * t.z * t.z * (t.z * (t.z * 6.0 - 15.0) + 10.0);
|
|
168
|
+
float n = mix(sliceNoise(cell, t.xy, seed), sliceNoise(cell + ivec3(0,0,1), t.xy, seed), fz);
|
|
169
|
+
return uNoiseType == 2 ? 0.5 + (n - 0.5) * (181.0 / 231.0) / 0.55 : n;
|
|
170
|
+
}
|
|
171
|
+
`;
|
|
172
|
+
|
|
173
|
+
// src/turbulent-displace/shader.ts
|
|
174
|
+
var TURBULENT_DISPLACE_FRAGMENT_SHADER = `#version 300 es
|
|
175
|
+
precision highp float;
|
|
176
|
+
precision highp int;
|
|
177
|
+
|
|
178
|
+
in vec2 vUv;
|
|
179
|
+
out vec4 fragColor;
|
|
180
|
+
uniform sampler2D uSource;
|
|
181
|
+
uniform vec2 uResolution;
|
|
182
|
+
uniform float uAmount;
|
|
183
|
+
uniform float uSize;
|
|
184
|
+
uniform vec2 uOffset;
|
|
185
|
+
uniform float uComplexity;
|
|
186
|
+
uniform float uEvolution;
|
|
187
|
+
uniform bool uCycleEvolution;
|
|
188
|
+
uniform float uCycle;
|
|
189
|
+
uniform uint uSeed;
|
|
190
|
+
uniform int uDisplacement;
|
|
191
|
+
uniform int uPinning;
|
|
192
|
+
const int uNoiseType = 2;
|
|
193
|
+
|
|
194
|
+
${VALUE_NOISE_SHADER}
|
|
195
|
+
|
|
196
|
+
float noiseLayer(vec2 p, float z, uint seed) {
|
|
197
|
+
if (!uCycleEvolution) return valueNoise(vec3(p, uEvolution + z), seed);
|
|
198
|
+
float t = mod(uEvolution, uCycle);
|
|
199
|
+
// Zero blend derivatives at the seam keep the looping motion smooth.
|
|
200
|
+
float weight = smoothstep(0.0, 1.0, t / uCycle);
|
|
201
|
+
return mix(valueNoise(vec3(p, t + z), seed), valueNoise(vec3(p, t - uCycle + z), seed), weight);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
float turbulence(vec2 p, uint channel) {
|
|
205
|
+
float sum = 0.0;
|
|
206
|
+
float norm = 0.0;
|
|
207
|
+
float amplitude = 1.0;
|
|
208
|
+
float frequency = 1.0;
|
|
209
|
+
float falloff = uDisplacement >= 3 && uDisplacement <= 5 ? 0.3 : 0.5;
|
|
210
|
+
for (int octave = 0; octave < 10; octave++) {
|
|
211
|
+
float weight = clamp(uComplexity - float(octave), 0.0, 1.0);
|
|
212
|
+
if (weight == 0.0) break;
|
|
213
|
+
uint seed = (uSeed ^ 0x7d15u) + channel + uint(octave) * 101u;
|
|
214
|
+
sum += noiseLayer(p * frequency, float(octave) * 5.17, seed) * amplitude * weight;
|
|
215
|
+
norm += amplitude * weight;
|
|
216
|
+
amplitude *= falloff;
|
|
217
|
+
frequency *= 2.0;
|
|
218
|
+
}
|
|
219
|
+
return sum / norm - 0.5;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
vec4 readPixel(ivec2 p) {
|
|
223
|
+
if (any(lessThan(p, ivec2(0))) || any(greaterThanEqual(p, ivec2(uResolution)))) return vec4(0.0);
|
|
224
|
+
return texelFetch(uSource, ivec2(p.x, int(uResolution.y) - 1 - p.y), 0);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
vec4 sampleSource(vec2 p) {
|
|
228
|
+
// Bilinear interpolation with transparent samples outside the source, so
|
|
229
|
+
// warped alpha edges do not smear the outermost pixel across the canvas.
|
|
230
|
+
ivec2 base = ivec2(floor(p - 0.5));
|
|
231
|
+
vec2 t = fract(p - 0.5);
|
|
232
|
+
return mix(mix(readPixel(base), readPixel(base + ivec2(1,0)), t.x),
|
|
233
|
+
mix(readPixel(base + ivec2(0,1)), readPixel(base + ivec2(1,1)), t.x), t.y);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
void main() {
|
|
237
|
+
if (uAmount == 0.0) {
|
|
238
|
+
fragColor = texture(uSource, vUv);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
vec2 pixel = vec2(vUv.x, 1.0 - vUv.y) * uResolution;
|
|
242
|
+
vec2 p = (pixel - uOffset * uResolution) / uSize;
|
|
243
|
+
vec2 displacement;
|
|
244
|
+
if (uDisplacement == 1 || uDisplacement == 2 || uDisplacement == 4 || uDisplacement == 5) {
|
|
245
|
+
float epsilon = 0.05;
|
|
246
|
+
vec2 gradient = vec2(
|
|
247
|
+
turbulence(p + vec2(epsilon,0), 0u) - turbulence(p - vec2(epsilon,0), 0u),
|
|
248
|
+
turbulence(p + vec2(0,epsilon), 0u) - turbulence(p - vec2(0,epsilon), 0u)
|
|
249
|
+
) / (2.0 * epsilon);
|
|
250
|
+
displacement = (uDisplacement == 1 || uDisplacement == 4) ? gradient : vec2(-gradient.y, gradient.x);
|
|
251
|
+
displacement *= uAmount * 0.25;
|
|
252
|
+
} else if (uDisplacement == 6) {
|
|
253
|
+
displacement = vec2(0.0, turbulence(p, 17u) * uAmount);
|
|
254
|
+
} else if (uDisplacement == 7) {
|
|
255
|
+
displacement = vec2(turbulence(p, 0u) * uAmount, 0.0);
|
|
256
|
+
} else if (uDisplacement == 8) {
|
|
257
|
+
displacement = vec2(turbulence(p, 0u) * uAmount);
|
|
258
|
+
} else {
|
|
259
|
+
displacement = vec2(turbulence(p, 0u), turbulence(p, 17u)) * uAmount;
|
|
260
|
+
}
|
|
261
|
+
bool locked = uPinning >= 8;
|
|
262
|
+
int pin = locked ? uPinning - 7 : uPinning;
|
|
263
|
+
float edge = max(1.0, min(uResolution.x, uResolution.y) * (locked ? 0.25 : 0.1));
|
|
264
|
+
vec2 nearEdge = clamp((pixel - 0.5) / edge, 0.0, 1.0);
|
|
265
|
+
vec2 farEdge = clamp((uResolution - 0.5 - pixel) / edge, 0.0, 1.0);
|
|
266
|
+
float horizontal = min(nearEdge.x, farEdge.x);
|
|
267
|
+
float vertical = min(nearEdge.y, farEdge.y);
|
|
268
|
+
float weight = 1.0;
|
|
269
|
+
if (pin == 1) weight = min(horizontal, vertical);
|
|
270
|
+
if (pin == 2) weight = vertical;
|
|
271
|
+
if (pin == 3) weight = horizontal;
|
|
272
|
+
if (pin == 4) weight = nearEdge.x;
|
|
273
|
+
if (pin == 5) weight = nearEdge.y;
|
|
274
|
+
if (pin == 6) weight = farEdge.x;
|
|
275
|
+
if (pin == 7) weight = farEdge.y;
|
|
276
|
+
vec2 sourcePixel = pixel + displacement * weight;
|
|
277
|
+
if (locked) sourcePixel = clamp(sourcePixel, vec2(0.5), uResolution - 0.5);
|
|
278
|
+
fragColor = sampleSource(sourcePixel);
|
|
279
|
+
}
|
|
280
|
+
`;
|
|
281
|
+
|
|
282
|
+
// src/turbulent-displace/index.ts
|
|
283
|
+
var { createEffect, createWebGL2ContextError } = Internals;
|
|
284
|
+
var DEFAULT_DISPLACEMENT = "turbulent";
|
|
285
|
+
var DEFAULT_AMOUNT2 = 50;
|
|
286
|
+
var DEFAULT_SIZE = 100;
|
|
287
|
+
var DEFAULT_OFFSET = [0.5, 0.5];
|
|
288
|
+
var DEFAULT_COMPLEXITY = 1;
|
|
289
|
+
var DEFAULT_EVOLUTION = 0;
|
|
290
|
+
var DEFAULT_CYCLE_EVOLUTION = false;
|
|
291
|
+
var DEFAULT_CYCLE = 1;
|
|
292
|
+
var DEFAULT_SEED = 0;
|
|
293
|
+
var DEFAULT_PINNING = "all";
|
|
294
|
+
var DISPLACEMENT_MODES = [
|
|
295
|
+
"turbulent",
|
|
296
|
+
"bulge",
|
|
297
|
+
"twist",
|
|
298
|
+
"turbulent-smoother",
|
|
299
|
+
"bulge-smoother",
|
|
300
|
+
"twist-smoother",
|
|
301
|
+
"vertical",
|
|
302
|
+
"horizontal",
|
|
303
|
+
"cross"
|
|
304
|
+
];
|
|
305
|
+
var PINNING_MODES = [
|
|
306
|
+
"none",
|
|
307
|
+
"all",
|
|
308
|
+
"horizontal",
|
|
309
|
+
"vertical",
|
|
310
|
+
"left",
|
|
311
|
+
"top",
|
|
312
|
+
"right",
|
|
313
|
+
"bottom",
|
|
314
|
+
"all-locked",
|
|
315
|
+
"horizontal-locked",
|
|
316
|
+
"vertical-locked",
|
|
317
|
+
"left-locked",
|
|
318
|
+
"top-locked",
|
|
319
|
+
"right-locked",
|
|
320
|
+
"bottom-locked"
|
|
321
|
+
];
|
|
322
|
+
var turbulentDisplaceSchema = {
|
|
323
|
+
displacement: {
|
|
324
|
+
type: "enum",
|
|
325
|
+
variants: {
|
|
326
|
+
turbulent: {},
|
|
327
|
+
bulge: {},
|
|
328
|
+
twist: {},
|
|
329
|
+
"turbulent-smoother": {},
|
|
330
|
+
"bulge-smoother": {},
|
|
331
|
+
"twist-smoother": {},
|
|
332
|
+
vertical: {},
|
|
333
|
+
horizontal: {},
|
|
334
|
+
cross: {}
|
|
335
|
+
},
|
|
336
|
+
default: DEFAULT_DISPLACEMENT,
|
|
337
|
+
description: "Displacement"
|
|
338
|
+
},
|
|
339
|
+
amount: {
|
|
340
|
+
type: "number",
|
|
341
|
+
min: -200,
|
|
342
|
+
max: 200,
|
|
343
|
+
step: 1,
|
|
344
|
+
default: DEFAULT_AMOUNT2,
|
|
345
|
+
description: "Amount",
|
|
346
|
+
hiddenFromList: false
|
|
347
|
+
},
|
|
348
|
+
size: {
|
|
349
|
+
type: "number",
|
|
350
|
+
min: 1,
|
|
351
|
+
max: 1000,
|
|
352
|
+
step: 1,
|
|
353
|
+
default: DEFAULT_SIZE,
|
|
354
|
+
description: "Size",
|
|
355
|
+
hiddenFromList: false
|
|
356
|
+
},
|
|
357
|
+
offset: {
|
|
358
|
+
type: "uv-coordinate",
|
|
359
|
+
step: 0.01,
|
|
360
|
+
default: DEFAULT_OFFSET,
|
|
361
|
+
description: "Offset"
|
|
362
|
+
},
|
|
363
|
+
complexity: {
|
|
364
|
+
type: "number",
|
|
365
|
+
min: 1,
|
|
366
|
+
max: 10,
|
|
367
|
+
step: 0.1,
|
|
368
|
+
default: DEFAULT_COMPLEXITY,
|
|
369
|
+
description: "Complexity",
|
|
370
|
+
hiddenFromList: false
|
|
371
|
+
},
|
|
372
|
+
evolution: {
|
|
373
|
+
type: "rotation-degrees",
|
|
374
|
+
step: 1,
|
|
375
|
+
default: DEFAULT_EVOLUTION,
|
|
376
|
+
description: "Evolution"
|
|
377
|
+
},
|
|
378
|
+
cycleEvolution: {
|
|
379
|
+
type: "boolean",
|
|
380
|
+
default: DEFAULT_CYCLE_EVOLUTION,
|
|
381
|
+
description: "Cycle evolution"
|
|
382
|
+
},
|
|
383
|
+
cycle: {
|
|
384
|
+
type: "number",
|
|
385
|
+
min: 1,
|
|
386
|
+
max: 100,
|
|
387
|
+
step: 1,
|
|
388
|
+
integer: true,
|
|
389
|
+
default: DEFAULT_CYCLE,
|
|
390
|
+
description: "Cycle length",
|
|
391
|
+
hiddenFromList: false
|
|
392
|
+
},
|
|
393
|
+
seed: {
|
|
394
|
+
type: "number",
|
|
395
|
+
min: 0,
|
|
396
|
+
max: 4294967295,
|
|
397
|
+
step: 1,
|
|
398
|
+
integer: true,
|
|
399
|
+
default: DEFAULT_SEED,
|
|
400
|
+
description: "Seed",
|
|
401
|
+
hiddenFromList: false
|
|
402
|
+
},
|
|
403
|
+
pinning: {
|
|
404
|
+
type: "enum",
|
|
405
|
+
variants: {
|
|
406
|
+
none: {},
|
|
407
|
+
all: {},
|
|
408
|
+
horizontal: {},
|
|
409
|
+
vertical: {},
|
|
410
|
+
left: {},
|
|
411
|
+
top: {},
|
|
412
|
+
right: {},
|
|
413
|
+
bottom: {},
|
|
414
|
+
"all-locked": {},
|
|
415
|
+
"horizontal-locked": {},
|
|
416
|
+
"vertical-locked": {},
|
|
417
|
+
"left-locked": {},
|
|
418
|
+
"top-locked": {},
|
|
419
|
+
"right-locked": {},
|
|
420
|
+
"bottom-locked": {}
|
|
421
|
+
},
|
|
422
|
+
default: DEFAULT_PINNING,
|
|
423
|
+
description: "Pinning"
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var resolve = (params) => ({
|
|
427
|
+
displacement: params.displacement ?? DEFAULT_DISPLACEMENT,
|
|
428
|
+
amount: params.amount ?? DEFAULT_AMOUNT2,
|
|
429
|
+
size: params.size ?? DEFAULT_SIZE,
|
|
430
|
+
offset: params.offset ?? DEFAULT_OFFSET,
|
|
431
|
+
complexity: params.complexity ?? DEFAULT_COMPLEXITY,
|
|
432
|
+
evolution: params.evolution ?? DEFAULT_EVOLUTION,
|
|
433
|
+
cycleEvolution: params.cycleEvolution ?? DEFAULT_CYCLE_EVOLUTION,
|
|
434
|
+
cycle: params.cycle ?? DEFAULT_CYCLE,
|
|
435
|
+
seed: params.seed ?? DEFAULT_SEED,
|
|
436
|
+
pinning: params.pinning ?? DEFAULT_PINNING
|
|
437
|
+
});
|
|
438
|
+
var validateTurbulentDisplaceParams = (params) => {
|
|
439
|
+
assertEffectParamsObject(params, "Turbulent displace");
|
|
440
|
+
assertOptionalFiniteNumber(params.amount, "amount");
|
|
441
|
+
assertOptionalFiniteNumber(params.size, "size");
|
|
442
|
+
assertOptionalFiniteNumber(params.complexity, "complexity");
|
|
443
|
+
assertOptionalFiniteNumber(params.evolution, "evolution");
|
|
444
|
+
assertOptionalBoolean(params.cycleEvolution, "cycleEvolution");
|
|
445
|
+
assertOptionalFiniteNumber(params.cycle, "cycle");
|
|
446
|
+
assertOptionalFiniteNumber(params.seed, "seed");
|
|
447
|
+
if (params.displacement !== undefined && !DISPLACEMENT_MODES.includes(params.displacement)) {
|
|
448
|
+
throw new TypeError("Invalid displacement: " + JSON.stringify(params.displacement));
|
|
449
|
+
}
|
|
450
|
+
if (params.pinning !== undefined && !PINNING_MODES.includes(params.pinning)) {
|
|
451
|
+
throw new TypeError("Invalid pinning: " + JSON.stringify(params.pinning));
|
|
452
|
+
}
|
|
453
|
+
if (params.offset !== undefined) {
|
|
454
|
+
if (!Array.isArray(params.offset) || params.offset.length !== 2)
|
|
455
|
+
throw new TypeError('"offset" must be a two-number tuple');
|
|
456
|
+
assertRequiredFiniteNumber(params.offset[0], "offset[0]");
|
|
457
|
+
assertRequiredFiniteNumber(params.offset[1], "offset[1]");
|
|
458
|
+
}
|
|
459
|
+
const r = resolve(params);
|
|
460
|
+
if (r.size < 1)
|
|
461
|
+
throw new TypeError('"size" must be at least 1');
|
|
462
|
+
if (r.complexity < 1 || r.complexity > 10)
|
|
463
|
+
throw new TypeError('"complexity" must be between 1 and 10');
|
|
464
|
+
if (!Number.isInteger(r.cycle) || r.cycle < 1 || r.cycle > 65535)
|
|
465
|
+
throw new TypeError('"cycle" must be an integer between 1 and 65535');
|
|
466
|
+
if (!Number.isInteger(r.seed) || r.seed < 0 || r.seed > 4294967295)
|
|
467
|
+
throw new TypeError('"seed" must be an unsigned 32-bit integer');
|
|
468
|
+
};
|
|
469
|
+
var VERTEX_SHADER = `#version 300 es
|
|
470
|
+
in vec2 aPos;
|
|
471
|
+
in vec2 aUv;
|
|
472
|
+
out vec2 vUv;
|
|
473
|
+
|
|
474
|
+
void main() {
|
|
475
|
+
vUv = aUv;
|
|
476
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
477
|
+
}
|
|
478
|
+
`;
|
|
479
|
+
var compileShader = (gl, type, source) => {
|
|
480
|
+
const shader = gl.createShader(type);
|
|
481
|
+
if (!shader) {
|
|
482
|
+
throw new Error("Failed to create WebGL shader");
|
|
483
|
+
}
|
|
484
|
+
gl.shaderSource(shader, source);
|
|
485
|
+
gl.compileShader(shader);
|
|
486
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
487
|
+
const log = gl.getShaderInfoLog(shader);
|
|
488
|
+
gl.deleteShader(shader);
|
|
489
|
+
throw new Error(`TurbulentDisplace shader compile failed: ${log ?? "(no log)"}`);
|
|
490
|
+
}
|
|
491
|
+
return shader;
|
|
492
|
+
};
|
|
493
|
+
var linkProgram = (gl, vs, fs) => {
|
|
494
|
+
const program = gl.createProgram();
|
|
495
|
+
if (!program) {
|
|
496
|
+
throw new Error("Failed to create WebGL program");
|
|
497
|
+
}
|
|
498
|
+
gl.attachShader(program, vs);
|
|
499
|
+
gl.attachShader(program, fs);
|
|
500
|
+
gl.linkProgram(program);
|
|
501
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
502
|
+
const log = gl.getProgramInfoLog(program);
|
|
503
|
+
gl.deleteProgram(program);
|
|
504
|
+
throw new Error(`TurbulentDisplace program link failed: ${log ?? "(no log)"}`);
|
|
505
|
+
}
|
|
506
|
+
return program;
|
|
507
|
+
};
|
|
508
|
+
var setupTurbulentDisplace = (target) => {
|
|
509
|
+
const gl = target.getContext("webgl2", {
|
|
510
|
+
premultipliedAlpha: true,
|
|
511
|
+
alpha: true,
|
|
512
|
+
preserveDrawingBuffer: true
|
|
513
|
+
});
|
|
514
|
+
if (!gl) {
|
|
515
|
+
throw createWebGL2ContextError("turbulent displace effect");
|
|
516
|
+
}
|
|
517
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
518
|
+
const vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
|
|
519
|
+
const fs = compileShader(gl, gl.FRAGMENT_SHADER, TURBULENT_DISPLACE_FRAGMENT_SHADER);
|
|
520
|
+
const program = linkProgram(gl, vs, fs);
|
|
521
|
+
gl.deleteShader(vs);
|
|
522
|
+
gl.deleteShader(fs);
|
|
523
|
+
const vao = gl.createVertexArray();
|
|
524
|
+
if (!vao) {
|
|
525
|
+
throw new Error("Failed to create WebGL vertex array");
|
|
526
|
+
}
|
|
527
|
+
gl.bindVertexArray(vao);
|
|
528
|
+
const data = new Float32Array([
|
|
529
|
+
-1,
|
|
530
|
+
-1,
|
|
531
|
+
0,
|
|
532
|
+
0,
|
|
533
|
+
1,
|
|
534
|
+
-1,
|
|
535
|
+
1,
|
|
536
|
+
0,
|
|
537
|
+
-1,
|
|
538
|
+
1,
|
|
539
|
+
0,
|
|
540
|
+
1,
|
|
541
|
+
1,
|
|
542
|
+
1,
|
|
543
|
+
1,
|
|
544
|
+
1
|
|
545
|
+
]);
|
|
546
|
+
const vbo = gl.createBuffer();
|
|
547
|
+
if (!vbo) {
|
|
548
|
+
throw new Error("Failed to create WebGL buffer");
|
|
549
|
+
}
|
|
550
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
551
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
552
|
+
const aPos = gl.getAttribLocation(program, "aPos");
|
|
553
|
+
const aUv = gl.getAttribLocation(program, "aUv");
|
|
554
|
+
gl.enableVertexAttribArray(aPos);
|
|
555
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
|
|
556
|
+
gl.enableVertexAttribArray(aUv);
|
|
557
|
+
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
|
|
558
|
+
gl.bindVertexArray(null);
|
|
559
|
+
const texture = gl.createTexture();
|
|
560
|
+
if (!texture) {
|
|
561
|
+
throw new Error("Failed to create WebGL texture");
|
|
562
|
+
}
|
|
563
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
564
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
565
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
566
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
567
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
568
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
569
|
+
return {
|
|
570
|
+
gl,
|
|
571
|
+
program,
|
|
572
|
+
vao,
|
|
573
|
+
vbo,
|
|
574
|
+
texture,
|
|
575
|
+
uSource: gl.getUniformLocation(program, "uSource"),
|
|
576
|
+
uResolution: gl.getUniformLocation(program, "uResolution"),
|
|
577
|
+
uDisplacement: gl.getUniformLocation(program, "uDisplacement"),
|
|
578
|
+
uAmount: gl.getUniformLocation(program, "uAmount"),
|
|
579
|
+
uSize: gl.getUniformLocation(program, "uSize"),
|
|
580
|
+
uOffset: gl.getUniformLocation(program, "uOffset"),
|
|
581
|
+
uComplexity: gl.getUniformLocation(program, "uComplexity"),
|
|
582
|
+
uEvolution: gl.getUniformLocation(program, "uEvolution"),
|
|
583
|
+
uCycleEvolution: gl.getUniformLocation(program, "uCycleEvolution"),
|
|
584
|
+
uCycle: gl.getUniformLocation(program, "uCycle"),
|
|
585
|
+
uSeed: gl.getUniformLocation(program, "uSeed"),
|
|
586
|
+
uPinning: gl.getUniformLocation(program, "uPinning")
|
|
587
|
+
};
|
|
588
|
+
};
|
|
589
|
+
var turbulentDisplace = createEffect({
|
|
590
|
+
type: "remotion/turbulent-displace",
|
|
591
|
+
label: "turbulentDisplace()",
|
|
592
|
+
documentationLink: "https://www.remotion.dev/docs/effects/turbulent-displace",
|
|
593
|
+
backend: "webgl2",
|
|
594
|
+
calculateKey: (params) => {
|
|
595
|
+
const r = resolve(params);
|
|
596
|
+
return `turbulent-displace-${JSON.stringify(r)}`;
|
|
597
|
+
},
|
|
598
|
+
setup: (target) => setupTurbulentDisplace(target),
|
|
599
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
600
|
+
const r = resolve(params);
|
|
601
|
+
const { gl, program, texture, vao } = state;
|
|
602
|
+
gl.viewport(0, 0, width, height);
|
|
603
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
604
|
+
gl.clearColor(0, 0, 0, 0);
|
|
605
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
606
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
607
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
608
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
609
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
610
|
+
gl.useProgram(program);
|
|
611
|
+
if (state.uSource)
|
|
612
|
+
gl.uniform1i(state.uSource, 0);
|
|
613
|
+
if (state.uResolution)
|
|
614
|
+
gl.uniform2f(state.uResolution, width, height);
|
|
615
|
+
if (state.uDisplacement)
|
|
616
|
+
gl.uniform1i(state.uDisplacement, DISPLACEMENT_MODES.indexOf(r.displacement));
|
|
617
|
+
if (state.uAmount)
|
|
618
|
+
gl.uniform1f(state.uAmount, r.amount);
|
|
619
|
+
if (state.uSize)
|
|
620
|
+
gl.uniform1f(state.uSize, r.size);
|
|
621
|
+
if (state.uOffset)
|
|
622
|
+
gl.uniform2f(state.uOffset, r.offset[0], r.offset[1]);
|
|
623
|
+
if (state.uComplexity)
|
|
624
|
+
gl.uniform1f(state.uComplexity, r.complexity);
|
|
625
|
+
if (state.uEvolution)
|
|
626
|
+
gl.uniform1f(state.uEvolution, r.evolution / 360);
|
|
627
|
+
if (state.uCycleEvolution)
|
|
628
|
+
gl.uniform1i(state.uCycleEvolution, r.cycleEvolution ? 1 : 0);
|
|
629
|
+
if (state.uCycle)
|
|
630
|
+
gl.uniform1f(state.uCycle, r.cycle);
|
|
631
|
+
if (state.uSeed)
|
|
632
|
+
gl.uniform1ui(state.uSeed, r.seed);
|
|
633
|
+
if (state.uPinning)
|
|
634
|
+
gl.uniform1i(state.uPinning, PINNING_MODES.indexOf(r.pinning));
|
|
635
|
+
gl.bindVertexArray(vao);
|
|
636
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
637
|
+
gl.bindVertexArray(null);
|
|
638
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
639
|
+
gl.useProgram(null);
|
|
640
|
+
},
|
|
641
|
+
cleanup: ({ gl, program, vao, vbo, texture }) => {
|
|
642
|
+
gl.deleteTexture(texture);
|
|
643
|
+
gl.deleteBuffer(vbo);
|
|
644
|
+
gl.deleteProgram(program);
|
|
645
|
+
gl.deleteVertexArray(vao);
|
|
646
|
+
},
|
|
647
|
+
schema: turbulentDisplaceSchema,
|
|
648
|
+
validateParams: validateTurbulentDisplaceParams
|
|
649
|
+
});
|
|
650
|
+
export {
|
|
651
|
+
turbulentDisplace
|
|
652
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
declare const FRACTAL_TYPES: readonly ["basic", "turbulent-smooth", "turbulent-basic", "turbulent-sharp", "dynamic", "dynamic-twist", "dynamic-progressive", "max", "strings"];
|
|
2
|
+
declare const NOISE_TYPES: readonly ["block", "linear", "soft-linear", "spline"];
|
|
3
|
+
export type FractalNoiseParams = {
|
|
4
|
+
/** Texture shape. Defaults to `basic`. */
|
|
5
|
+
readonly fractalType?: (typeof FRACTAL_TYPES)[number];
|
|
6
|
+
/** Lattice interpolation. Defaults to `soft-linear`. */
|
|
7
|
+
readonly noiseType?: (typeof NOISE_TYPES)[number];
|
|
8
|
+
/** Size of the largest noise cells in pixels. Defaults to `100`. */
|
|
9
|
+
readonly scale?: number;
|
|
10
|
+
/** Number of noise layers, including fractional layers, from `1` to `20`. Defaults to `6`. */
|
|
11
|
+
readonly complexity?: number;
|
|
12
|
+
/** Evolution in degrees. Animate to morph the texture. Defaults to `0`. */
|
|
13
|
+
readonly evolution?: number;
|
|
14
|
+
/** Contrast multiplier around mid-gray. Defaults to `1`. */
|
|
15
|
+
readonly contrast?: number;
|
|
16
|
+
/** Brightness added after contrast. Defaults to `0`. */
|
|
17
|
+
readonly brightness?: number;
|
|
18
|
+
/** Horizontal texture translation in pixels. Defaults to `0`. */
|
|
19
|
+
readonly offsetX?: number;
|
|
20
|
+
/** Vertical texture translation in pixels. Defaults to `0`. */
|
|
21
|
+
readonly offsetY?: number;
|
|
22
|
+
/** Relative strength of each successive layer, from `0` to `1`. Defaults to `0.7`. */
|
|
23
|
+
readonly subInfluence?: number;
|
|
24
|
+
/** Relative cell size of each successive layer, from `0.1` to `1`. Defaults to `0.56`. */
|
|
25
|
+
readonly subScaling?: number;
|
|
26
|
+
/** Loop evolution after `cycle` revolutions. Defaults to `false`. */
|
|
27
|
+
readonly cycleEvolution?: boolean;
|
|
28
|
+
/** Loop length in whole revolutions. Defaults to `1`. */
|
|
29
|
+
readonly cycle?: number;
|
|
30
|
+
/** Unsigned 32-bit integer seed for a repeatable texture. Defaults to `0`. */
|
|
31
|
+
readonly seed?: number;
|
|
32
|
+
/** Invert the generated grayscale values. Defaults to `false`. */
|
|
33
|
+
readonly invert?: boolean;
|
|
34
|
+
/** Mix with the source from `0` (unchanged) to `1` (noise only). Defaults to `1`. */
|
|
35
|
+
readonly amount?: number;
|
|
36
|
+
};
|
|
37
|
+
export declare const fractalNoise: (params?: (FractalNoiseParams & {
|
|
38
|
+
readonly disabled?: boolean | undefined;
|
|
39
|
+
}) | undefined) => import("remotion").EffectDescriptor<unknown>;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FRACTAL_NOISE_FRAGMENT_SHADER = "#version 300 es\nprecision highp float;\nprecision highp int;\n\nin vec2 vUv;\nout vec4 fragColor;\nuniform sampler2D uSource;\nuniform vec2 uResolution;\nuniform vec2 uOffset;\nuniform float uScale;\nuniform float uComplexity;\nuniform float uEvolution;\nuniform float uSubInfluence;\nuniform float uSubScaling;\nuniform float uContrast;\nuniform float uBrightness;\nuniform float uAmount;\nuniform float uCycle;\nuniform uint uSeed;\nuniform int uFractalType;\nuniform int uNoiseType;\nuniform bool uInvert;\nuniform bool uCycleEvolution;\n\n\nfloat lattice(ivec3 point, uint seed) {\n // Wrap lattice indices as well as coordinates so interpolation stays continuous\n // across the period boundary, including negative coordinates.\n uvec3 p = uvec3(point) & uvec3(65535u);\n uint h = p.x * 0x27d4eb2du ^ p.y * 0x165667b1u ^ p.z * 0x9e3779b9u ^ seed * 0x85ebca6bu;\n h ^= h >> 15;\n h *= 0x2c1b3c6du;\n h ^= h >> 12;\n h *= 0x297a2d39u;\n h ^= h >> 15;\n return float(h & 65535u) / 65535.0;\n}\n\nfloat catmull(vec4 p, float t) {\n return 0.5 * (2.0 * p.y + (p.z - p.x) * t\n + (2.0 * p.x - 5.0 * p.y + 4.0 * p.z - p.w) * t * t\n + (3.0 * p.y - p.x - 3.0 * p.z + p.w) * t * t * t);\n}\n\nvec3 bspline(float t) {\n return vec3(0.5 * (1.0-t) * (1.0-t), 0.5 + t * (1.0-t), 0.5 * t * t);\n}\n\nfloat sliceNoise(ivec3 p, vec2 t, uint seed) {\n if (uNoiseType == 0) return lattice(p, seed);\n if (uNoiseType == 1) {\n return mix(mix(lattice(p, seed), lattice(p + ivec3(1,0,0), seed), t.x),\n mix(lattice(p + ivec3(0,1,0), seed), lattice(p + ivec3(1,1,0), seed), t.x), t.y);\n }\n if (uNoiseType == 2) {\n vec3 wx = bspline(t.x);\n vec3 wy = bspline(t.y);\n float result = 0.0;\n for (int y = 0; y < 3; y++) {\n for (int x = 0; x < 3; x++) {\n result += wx[x] * wy[y] * lattice(p + ivec3(x-1, y-1, 0), seed);\n }\n }\n return result;\n }\n vec4 rows;\n for (int y = 0; y < 4; y++) {\n vec4 row;\n for (int x = 0; x < 4; x++) {\n row[x] = lattice(p + ivec3(x-1, y-1, 0), seed);\n }\n rows[y] = catmull(row, t.x);\n }\n return catmull(rows, t.y);\n}\n\nfloat valueNoise(vec3 point, uint seed) {\n // A large period keeps conversion to integer coordinates defined at extreme scales.\n vec3 p = mod(point + vec3(uNoiseType == 2 ? 0.5 : 0.0, uNoiseType == 2 ? 0.5 : 0.0, 0.0), 65536.0);\n ivec3 cell = ivec3(floor(p));\n vec3 t = fract(p);\n float fz = t.z * t.z * t.z * (t.z * (t.z * 6.0 - 15.0) + 10.0);\n float n = mix(sliceNoise(cell, t.xy, seed), sliceNoise(cell + ivec3(0,0,1), t.xy, seed), fz);\n return uNoiseType == 2 ? 0.5 + (n - 0.5) * (181.0 / 231.0) / 0.55 : n;\n}\n\n\nfloat layer(vec2 p, float z, uint seed) {\n if (!uCycleEvolution) return valueNoise(vec3(p, uEvolution + z), seed);\n float t = mod(uEvolution, uCycle);\n return mix(valueNoise(vec3(p, t + z), seed), valueNoise(vec3(p, t - uCycle + z), seed), t / uCycle);\n}\n\nfloat shape(float n) {\n float s = 2.0 * n - 1.0;\n if (uFractalType == 1) return 1.0 - s * s;\n if (uFractalType == 2) return 1.0 - abs(s);\n if (uFractalType == 3) return (1.0 - abs(s)) * (1.0 - abs(s));\n if (uFractalType == 8) {\n float distance = clamp(abs(s) / 0.12, 0.0, 1.0);\n return 1.0 - distance * distance;\n }\n return n;\n}\n\nvoid main() {\n vec4 source = texture(uSource, vUv);\n if (source.a == 0.0 || uAmount == 0.0) {\n fragColor = source;\n return;\n }\n vec2 pixel = vec2(vUv.x, 1.0 - vUv.y) * uResolution;\n vec2 base = (pixel - uResolution * 0.5 - uOffset) / uScale;\n float sum = 0.0;\n float norm = 0.0;\n float amplitude = 1.0;\n float frequency = 1.0;\n float best = 0.0;\n for (int octave = 0; octave < 20; octave++) {\n float weight = clamp(uComplexity - float(octave), 0.0, 1.0);\n if (weight == 0.0 || amplitude == 0.0) break;\n vec2 p = base * frequency;\n float z = float(octave) * 7.31;\n uint seed = (uSeed ^ 0x51edu) + uint(octave);\n if (uFractalType >= 4 && uFractalType <= 6) {\n float a = layer(p * 0.5, z + 3.1, seed ^ 0x55u) - 0.5;\n if (uFractalType == 5) {\n float angle = a * 3.0;\n p = mat2(cos(angle), sin(angle), -sin(angle), cos(angle)) * p;\n } else {\n float b = layer(p * 0.5, z + 5.7, seed ^ 0xaau) - 0.5;\n float strength = uFractalType == 6 ? 0.5 + float(octave) * 0.35 : 1.0;\n p += vec2(a, b) * 1.5 * strength;\n }\n }\n float n = shape(layer(p, z, seed));\n // Fade fractional octaves in for Max too, so animating complexity is continuous.\n best = max(best, n * amplitude * weight);\n sum += n * amplitude * weight;\n norm += amplitude * weight;\n amplitude *= uSubInfluence;\n frequency /= uSubScaling;\n }\n float noise = uFractalType == 7 ? best : sum / norm;\n noise = clamp((noise - 0.5) * uContrast + 0.5 + uBrightness, 0.0, 1.0);\n if (uInvert) noise = 1.0 - noise;\n fragColor = vec4(mix(source.rgb, vec3(noise) * source.a, uAmount), source.a);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fractalNoise, type FractalNoiseParams } from './fractal-noise/index.js';
|