@remotion/effects 4.0.485 → 4.0.487
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/paper.mjs +921 -0
- package/dist/esm/roughen-edges.mjs +566 -0
- package/dist/paper.d.ts +35 -0
- package/dist/roughen-edges.d.ts +13 -0
- package/package.json +19 -3
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
// src/roughen-edges.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/roughen-edges.ts
|
|
110
|
+
var { createEffect, createWebGL2ContextError } = Internals;
|
|
111
|
+
var DEFAULT_AMOUNT2 = 1;
|
|
112
|
+
var DEFAULT_BORDER = 26.5;
|
|
113
|
+
var DEFAULT_SCALE = 0.07;
|
|
114
|
+
var DEFAULT_SEED = 231.2;
|
|
115
|
+
var MAX_BORDER = 200;
|
|
116
|
+
var MAX_SEED = 1000;
|
|
117
|
+
var NOISE_TEXTURE_SIZE = 256;
|
|
118
|
+
var roughenEdgesSchema = {
|
|
119
|
+
amount: {
|
|
120
|
+
type: "number",
|
|
121
|
+
min: 0,
|
|
122
|
+
max: 1,
|
|
123
|
+
step: 0.01,
|
|
124
|
+
default: DEFAULT_AMOUNT2,
|
|
125
|
+
description: "Amount",
|
|
126
|
+
hiddenFromList: false
|
|
127
|
+
},
|
|
128
|
+
border: {
|
|
129
|
+
type: "number",
|
|
130
|
+
min: 0,
|
|
131
|
+
max: MAX_BORDER,
|
|
132
|
+
step: 0.1,
|
|
133
|
+
default: DEFAULT_BORDER,
|
|
134
|
+
description: "Border",
|
|
135
|
+
hiddenFromList: false
|
|
136
|
+
},
|
|
137
|
+
scale: {
|
|
138
|
+
type: "number",
|
|
139
|
+
min: 0.01,
|
|
140
|
+
max: 4,
|
|
141
|
+
step: 0.01,
|
|
142
|
+
default: DEFAULT_SCALE,
|
|
143
|
+
description: "Scale",
|
|
144
|
+
hiddenFromList: false
|
|
145
|
+
},
|
|
146
|
+
seed: {
|
|
147
|
+
type: "number",
|
|
148
|
+
min: 0,
|
|
149
|
+
max: MAX_SEED,
|
|
150
|
+
step: 0.01,
|
|
151
|
+
default: DEFAULT_SEED,
|
|
152
|
+
description: "Seed",
|
|
153
|
+
hiddenFromList: false
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var resolve = (p) => ({
|
|
157
|
+
amount: p.amount ?? DEFAULT_AMOUNT2,
|
|
158
|
+
border: p.border ?? DEFAULT_BORDER,
|
|
159
|
+
scale: p.scale ?? DEFAULT_SCALE,
|
|
160
|
+
seed: p.seed ?? DEFAULT_SEED
|
|
161
|
+
});
|
|
162
|
+
var validateAtMost = (value, max, name) => {
|
|
163
|
+
if (value > max) {
|
|
164
|
+
throw new TypeError(`"${name}" must be <= ${max}, but got ${JSON.stringify(value)}`);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
var validateRoughenEdgesParams = (params) => {
|
|
168
|
+
assertEffectParamsObject(params, "Roughen edges");
|
|
169
|
+
assertOptionalFiniteNumber(params.amount, "amount");
|
|
170
|
+
assertOptionalFiniteNumber(params.border, "border");
|
|
171
|
+
assertOptionalFiniteNumber(params.scale, "scale");
|
|
172
|
+
assertOptionalFiniteNumber(params.seed, "seed");
|
|
173
|
+
const r = resolve(params);
|
|
174
|
+
validateUnitInterval(r.amount, "amount");
|
|
175
|
+
validateNonNegative(r.border, "border");
|
|
176
|
+
validateAtMost(r.border, MAX_BORDER, "border");
|
|
177
|
+
if (r.scale <= 0) {
|
|
178
|
+
throw new TypeError(`"scale" must be greater than 0, but got ${JSON.stringify(r.scale)}`);
|
|
179
|
+
}
|
|
180
|
+
validateAtMost(r.scale, 4, "scale");
|
|
181
|
+
validateNonNegative(r.seed, "seed");
|
|
182
|
+
validateAtMost(r.seed, MAX_SEED, "seed");
|
|
183
|
+
};
|
|
184
|
+
var ROUGHEN_EDGES_VS = `#version 300 es
|
|
185
|
+
in vec2 aPos;
|
|
186
|
+
in vec2 aUv;
|
|
187
|
+
out vec2 vUv;
|
|
188
|
+
|
|
189
|
+
void main() {
|
|
190
|
+
vUv = aUv;
|
|
191
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
var ROUGHEN_EDGES_FS = `#version 300 es
|
|
195
|
+
precision highp float;
|
|
196
|
+
|
|
197
|
+
in vec2 vUv;
|
|
198
|
+
out vec4 fragColor;
|
|
199
|
+
|
|
200
|
+
uniform sampler2D uSource;
|
|
201
|
+
uniform vec2 uResolution;
|
|
202
|
+
uniform float uAmount;
|
|
203
|
+
uniform float uBorder;
|
|
204
|
+
uniform float uScale;
|
|
205
|
+
uniform float uSeed;
|
|
206
|
+
uniform sampler2D uNoiseTexture;
|
|
207
|
+
|
|
208
|
+
float sampleAlpha(vec2 uv) {
|
|
209
|
+
return texture(uSource, clamp(uv, vec2(0.0), vec2(1.0))).a;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
vec2 seedOffset(float salt) {
|
|
213
|
+
float seeded = uSeed + salt;
|
|
214
|
+
return fract(
|
|
215
|
+
sin(
|
|
216
|
+
vec2(
|
|
217
|
+
seeded * 12.9898 + 78.233,
|
|
218
|
+
seeded * 39.3468 + 11.135
|
|
219
|
+
)
|
|
220
|
+
) * 43758.5453
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
float randomR(vec2 p) {
|
|
225
|
+
vec2 uv = floor(p) / 100.0 + 0.5;
|
|
226
|
+
return texture(uNoiseTexture, fract(uv)).r;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
float valueNoise(vec2 st) {
|
|
230
|
+
vec2 i = floor(st);
|
|
231
|
+
vec2 f = fract(st);
|
|
232
|
+
float a = randomR(i);
|
|
233
|
+
float b = randomR(i + vec2(1.0, 0.0));
|
|
234
|
+
float c = randomR(i + vec2(0.0, 1.0));
|
|
235
|
+
float d = randomR(i + vec2(1.0, 1.0));
|
|
236
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
237
|
+
float x1 = mix(a, b, u.x);
|
|
238
|
+
float x2 = mix(c, d, u.x);
|
|
239
|
+
return mix(x1, x2, u.y);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
float fbm(vec2 n) {
|
|
243
|
+
float total = 0.0;
|
|
244
|
+
float amplitude = 0.5;
|
|
245
|
+
for (int i = 0; i < 4; i++) {
|
|
246
|
+
total += valueNoise(n) * amplitude;
|
|
247
|
+
n *= 2.03;
|
|
248
|
+
amplitude *= 0.55;
|
|
249
|
+
}
|
|
250
|
+
return total;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
void addAlphaSample(
|
|
254
|
+
vec2 uv,
|
|
255
|
+
vec2 offset,
|
|
256
|
+
inout float minAlpha,
|
|
257
|
+
inout float maxAlpha
|
|
258
|
+
) {
|
|
259
|
+
float alpha = sampleAlpha(uv + offset);
|
|
260
|
+
minAlpha = min(minAlpha, alpha);
|
|
261
|
+
maxAlpha = max(maxAlpha, alpha);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
float edgeProximity(vec2 uv, float alpha) {
|
|
265
|
+
if (uBorder <= 0.0) {
|
|
266
|
+
return 0.0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
vec2 reach = max(uBorder, 1.0) / uResolution;
|
|
270
|
+
float minAlpha = alpha;
|
|
271
|
+
float maxAlpha = alpha;
|
|
272
|
+
|
|
273
|
+
addAlphaSample(uv, vec2(reach.x, 0.0), minAlpha, maxAlpha);
|
|
274
|
+
addAlphaSample(uv, vec2(-reach.x, 0.0), minAlpha, maxAlpha);
|
|
275
|
+
addAlphaSample(uv, vec2(0.0, reach.y), minAlpha, maxAlpha);
|
|
276
|
+
addAlphaSample(uv, vec2(0.0, -reach.y), minAlpha, maxAlpha);
|
|
277
|
+
addAlphaSample(uv, vec2(reach.x, reach.y), minAlpha, maxAlpha);
|
|
278
|
+
addAlphaSample(uv, vec2(-reach.x, reach.y), minAlpha, maxAlpha);
|
|
279
|
+
addAlphaSample(uv, vec2(reach.x, -reach.y), minAlpha, maxAlpha);
|
|
280
|
+
addAlphaSample(uv, vec2(-reach.x, -reach.y), minAlpha, maxAlpha);
|
|
281
|
+
|
|
282
|
+
return smoothstep(0.02, 0.35, maxAlpha - minAlpha);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
vec2 alphaGradient(vec2 uv) {
|
|
286
|
+
vec2 reach = max(uBorder * 0.25, 1.0) / uResolution;
|
|
287
|
+
return vec2(
|
|
288
|
+
sampleAlpha(uv + vec2(reach.x, 0.0)) -
|
|
289
|
+
sampleAlpha(uv - vec2(reach.x, 0.0)),
|
|
290
|
+
sampleAlpha(uv + vec2(0.0, reach.y)) -
|
|
291
|
+
sampleAlpha(uv - vec2(0.0, reach.y))
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
float edgeNoise(vec2 uv, float salt) {
|
|
296
|
+
vec2 patternUV = uv - 0.5;
|
|
297
|
+
patternUV *= vec2(uResolution.x / max(uResolution.y, 1.0), 1.0);
|
|
298
|
+
patternUV *= 7.0 / max(uScale, 0.001);
|
|
299
|
+
patternUV += 64.0 * seedOffset(salt);
|
|
300
|
+
return fbm(patternUV);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
void main() {
|
|
304
|
+
vec4 source = texture(uSource, vUv);
|
|
305
|
+
|
|
306
|
+
if (uAmount <= 0.0 || uBorder <= 0.0) {
|
|
307
|
+
fragColor = source;
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
float alpha = source.a;
|
|
312
|
+
float proximity = edgeProximity(vUv, alpha);
|
|
313
|
+
|
|
314
|
+
if (proximity <= 0.001) {
|
|
315
|
+
fragColor = source;
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
vec2 gradient = alphaGradient(vUv);
|
|
320
|
+
vec2 noiseVector = vec2(
|
|
321
|
+
edgeNoise(vUv + vec2(0.17, 0.0), 2.0),
|
|
322
|
+
edgeNoise(vUv + vec2(0.0, 0.31), 3.0)
|
|
323
|
+
) * 2.0 - 1.0;
|
|
324
|
+
vec2 direction = gradient + 0.7 * noiseVector;
|
|
325
|
+
if (length(direction) <= 0.0001) {
|
|
326
|
+
direction = length(noiseVector) <= 0.0001 ? vec2(1.0, 0.0) : noiseVector;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
direction = normalize(direction);
|
|
330
|
+
|
|
331
|
+
float scalar = edgeNoise(vUv, 4.0) * 2.0 - 1.0;
|
|
332
|
+
vec2 offset = direction * scalar * uBorder / uResolution;
|
|
333
|
+
vec4 roughened = texture(
|
|
334
|
+
uSource,
|
|
335
|
+
clamp(vUv + offset, vec2(0.0), vec2(1.0))
|
|
336
|
+
);
|
|
337
|
+
float blend = clamp(proximity * uAmount, 0.0, 1.0);
|
|
338
|
+
|
|
339
|
+
fragColor = mix(source, roughened, blend);
|
|
340
|
+
}
|
|
341
|
+
`;
|
|
342
|
+
var compileShader = (gl, type, source) => {
|
|
343
|
+
const shader = gl.createShader(type);
|
|
344
|
+
if (!shader) {
|
|
345
|
+
throw new Error("Failed to create WebGL shader");
|
|
346
|
+
}
|
|
347
|
+
gl.shaderSource(shader, source);
|
|
348
|
+
gl.compileShader(shader);
|
|
349
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
350
|
+
const log = gl.getShaderInfoLog(shader);
|
|
351
|
+
gl.deleteShader(shader);
|
|
352
|
+
throw new Error(`Roughen edges shader compile failed: ${log ?? "(no log)"}`);
|
|
353
|
+
}
|
|
354
|
+
return shader;
|
|
355
|
+
};
|
|
356
|
+
var linkProgram = (gl, vs, fs) => {
|
|
357
|
+
const program = gl.createProgram();
|
|
358
|
+
if (!program) {
|
|
359
|
+
throw new Error("Failed to create WebGL program");
|
|
360
|
+
}
|
|
361
|
+
gl.attachShader(program, vs);
|
|
362
|
+
gl.attachShader(program, fs);
|
|
363
|
+
gl.linkProgram(program);
|
|
364
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
365
|
+
const log = gl.getProgramInfoLog(program);
|
|
366
|
+
gl.deleteProgram(program);
|
|
367
|
+
throw new Error(`Roughen edges program link failed: ${log ?? "(no log)"}`);
|
|
368
|
+
}
|
|
369
|
+
return program;
|
|
370
|
+
};
|
|
371
|
+
var createSourceTexture = (gl) => {
|
|
372
|
+
const texture = gl.createTexture();
|
|
373
|
+
if (!texture) {
|
|
374
|
+
throw new Error("Failed to create WebGL texture");
|
|
375
|
+
}
|
|
376
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
377
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
378
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
379
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
380
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
381
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
382
|
+
return texture;
|
|
383
|
+
};
|
|
384
|
+
var initialNoiseState = (seed) => {
|
|
385
|
+
const scaledSeed = Math.round(seed * 1000);
|
|
386
|
+
const mixedState = (2654435769 ^ Math.imul(scaledSeed, 2246822507)) >>> 0;
|
|
387
|
+
return mixedState === 0 ? 2654435769 : mixedState;
|
|
388
|
+
};
|
|
389
|
+
var nextNoiseState = (state) => {
|
|
390
|
+
let next = state;
|
|
391
|
+
next ^= next << 13;
|
|
392
|
+
next ^= next >>> 17;
|
|
393
|
+
next ^= next << 5;
|
|
394
|
+
return next >>> 0;
|
|
395
|
+
};
|
|
396
|
+
var createNoiseData = (seed) => {
|
|
397
|
+
const data = new Uint8Array(NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * 4);
|
|
398
|
+
let state = initialNoiseState(seed);
|
|
399
|
+
for (let i = 0;i < data.length; i += 4) {
|
|
400
|
+
state = nextNoiseState(state);
|
|
401
|
+
data[i] = state & 255;
|
|
402
|
+
state = nextNoiseState(state);
|
|
403
|
+
data[i + 1] = state & 255;
|
|
404
|
+
state = nextNoiseState(state);
|
|
405
|
+
data[i + 2] = state & 255;
|
|
406
|
+
data[i + 3] = 255;
|
|
407
|
+
}
|
|
408
|
+
return data;
|
|
409
|
+
};
|
|
410
|
+
var uploadNoiseTexture = (gl, texture, seed) => {
|
|
411
|
+
const data = createNoiseData(seed);
|
|
412
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
413
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
414
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
415
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
|
416
|
+
};
|
|
417
|
+
var createNoiseTexture = (gl) => {
|
|
418
|
+
const texture = gl.createTexture();
|
|
419
|
+
if (!texture) {
|
|
420
|
+
throw new Error("Failed to create WebGL noise texture");
|
|
421
|
+
}
|
|
422
|
+
uploadNoiseTexture(gl, texture, DEFAULT_SEED);
|
|
423
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
424
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
425
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
|
426
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
|
427
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
428
|
+
return texture;
|
|
429
|
+
};
|
|
430
|
+
var setupRoughenEdges = (target) => {
|
|
431
|
+
const gl = target.getContext("webgl2", {
|
|
432
|
+
premultipliedAlpha: true,
|
|
433
|
+
alpha: true,
|
|
434
|
+
preserveDrawingBuffer: true
|
|
435
|
+
});
|
|
436
|
+
if (!gl) {
|
|
437
|
+
throw createWebGL2ContextError("roughen edges effect");
|
|
438
|
+
}
|
|
439
|
+
const vs = compileShader(gl, gl.VERTEX_SHADER, ROUGHEN_EDGES_VS);
|
|
440
|
+
const fs = compileShader(gl, gl.FRAGMENT_SHADER, ROUGHEN_EDGES_FS);
|
|
441
|
+
const program = linkProgram(gl, vs, fs);
|
|
442
|
+
gl.deleteShader(vs);
|
|
443
|
+
gl.deleteShader(fs);
|
|
444
|
+
const vao = gl.createVertexArray();
|
|
445
|
+
if (!vao) {
|
|
446
|
+
throw new Error("Failed to create WebGL vertex array");
|
|
447
|
+
}
|
|
448
|
+
gl.bindVertexArray(vao);
|
|
449
|
+
const data = new Float32Array([
|
|
450
|
+
-1,
|
|
451
|
+
-1,
|
|
452
|
+
0,
|
|
453
|
+
0,
|
|
454
|
+
1,
|
|
455
|
+
-1,
|
|
456
|
+
1,
|
|
457
|
+
0,
|
|
458
|
+
-1,
|
|
459
|
+
1,
|
|
460
|
+
0,
|
|
461
|
+
1,
|
|
462
|
+
1,
|
|
463
|
+
1,
|
|
464
|
+
1,
|
|
465
|
+
1
|
|
466
|
+
]);
|
|
467
|
+
const vbo = gl.createBuffer();
|
|
468
|
+
if (!vbo) {
|
|
469
|
+
throw new Error("Failed to create WebGL buffer");
|
|
470
|
+
}
|
|
471
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
472
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
473
|
+
const aPos = gl.getAttribLocation(program, "aPos");
|
|
474
|
+
const aUv = gl.getAttribLocation(program, "aUv");
|
|
475
|
+
gl.enableVertexAttribArray(aPos);
|
|
476
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
|
|
477
|
+
gl.enableVertexAttribArray(aUv);
|
|
478
|
+
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
|
|
479
|
+
gl.bindVertexArray(null);
|
|
480
|
+
const sourceTexture = createSourceTexture(gl);
|
|
481
|
+
const noiseTexture = createNoiseTexture(gl);
|
|
482
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
483
|
+
return {
|
|
484
|
+
gl,
|
|
485
|
+
program,
|
|
486
|
+
vao,
|
|
487
|
+
vbo,
|
|
488
|
+
sourceTexture,
|
|
489
|
+
noiseTexture,
|
|
490
|
+
uniforms: {
|
|
491
|
+
uSource: gl.getUniformLocation(program, "uSource"),
|
|
492
|
+
uResolution: gl.getUniformLocation(program, "uResolution"),
|
|
493
|
+
uAmount: gl.getUniformLocation(program, "uAmount"),
|
|
494
|
+
uBorder: gl.getUniformLocation(program, "uBorder"),
|
|
495
|
+
uScale: gl.getUniformLocation(program, "uScale"),
|
|
496
|
+
uSeed: gl.getUniformLocation(program, "uSeed"),
|
|
497
|
+
uNoiseTexture: gl.getUniformLocation(program, "uNoiseTexture")
|
|
498
|
+
},
|
|
499
|
+
cachedNoiseSeed: DEFAULT_SEED
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
var roughenEdges = createEffect({
|
|
503
|
+
type: "dev.remotion.effects.roughen-edges",
|
|
504
|
+
label: "roughenEdges()",
|
|
505
|
+
documentationLink: "https://www.remotion.dev/docs/effects/roughen-edges",
|
|
506
|
+
backend: "webgl2",
|
|
507
|
+
calculateKey: (params) => {
|
|
508
|
+
const r = resolve(params);
|
|
509
|
+
return `roughen-edges-${r.amount}-${r.border}-${r.scale}-${r.seed}`;
|
|
510
|
+
},
|
|
511
|
+
setup: (target) => setupRoughenEdges(target),
|
|
512
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
513
|
+
const r = resolve(params);
|
|
514
|
+
const { gl, program, vao, sourceTexture, noiseTexture, uniforms } = state;
|
|
515
|
+
gl.viewport(0, 0, width, height);
|
|
516
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
517
|
+
gl.clearColor(0, 0, 0, 0);
|
|
518
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
519
|
+
gl.useProgram(program);
|
|
520
|
+
gl.bindVertexArray(vao);
|
|
521
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
522
|
+
gl.bindTexture(gl.TEXTURE_2D, sourceTexture);
|
|
523
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
524
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
525
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
526
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
527
|
+
gl.bindTexture(gl.TEXTURE_2D, noiseTexture);
|
|
528
|
+
if (state.cachedNoiseSeed !== r.seed) {
|
|
529
|
+
uploadNoiseTexture(gl, noiseTexture, r.seed);
|
|
530
|
+
state.cachedNoiseSeed = r.seed;
|
|
531
|
+
}
|
|
532
|
+
if (uniforms.uSource)
|
|
533
|
+
gl.uniform1i(uniforms.uSource, 0);
|
|
534
|
+
if (uniforms.uResolution)
|
|
535
|
+
gl.uniform2f(uniforms.uResolution, width, height);
|
|
536
|
+
if (uniforms.uAmount)
|
|
537
|
+
gl.uniform1f(uniforms.uAmount, r.amount);
|
|
538
|
+
if (uniforms.uBorder)
|
|
539
|
+
gl.uniform1f(uniforms.uBorder, r.border);
|
|
540
|
+
if (uniforms.uScale)
|
|
541
|
+
gl.uniform1f(uniforms.uScale, r.scale);
|
|
542
|
+
if (uniforms.uSeed)
|
|
543
|
+
gl.uniform1f(uniforms.uSeed, r.seed);
|
|
544
|
+
if (uniforms.uNoiseTexture)
|
|
545
|
+
gl.uniform1i(uniforms.uNoiseTexture, 1);
|
|
546
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
547
|
+
gl.bindVertexArray(null);
|
|
548
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
549
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
550
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
551
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
552
|
+
gl.useProgram(null);
|
|
553
|
+
},
|
|
554
|
+
cleanup: ({ gl, program, vao, vbo, sourceTexture, noiseTexture }) => {
|
|
555
|
+
gl.deleteTexture(sourceTexture);
|
|
556
|
+
gl.deleteTexture(noiseTexture);
|
|
557
|
+
gl.deleteBuffer(vbo);
|
|
558
|
+
gl.deleteProgram(program);
|
|
559
|
+
gl.deleteVertexArray(vao);
|
|
560
|
+
},
|
|
561
|
+
schema: roughenEdgesSchema,
|
|
562
|
+
validateParams: validateRoughenEdgesParams
|
|
563
|
+
});
|
|
564
|
+
export {
|
|
565
|
+
roughenEdges
|
|
566
|
+
};
|
package/dist/paper.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type PaperParams = {
|
|
2
|
+
/** Strength of the paper texture from `0` to `1`. Defaults to `1`. */
|
|
3
|
+
readonly amount?: number;
|
|
4
|
+
/** Light-facing paper color. Defaults to `#9fadbc`. */
|
|
5
|
+
readonly colorFront?: string;
|
|
6
|
+
/** Shadow-facing paper color. Defaults to `#ffffff`. */
|
|
7
|
+
readonly colorBack?: string;
|
|
8
|
+
/** Sharpness of light and color transitions from `0` to `1`. Defaults to `0.3`. */
|
|
9
|
+
readonly contrast?: number;
|
|
10
|
+
/** Fine pixel noise from `0` to `1`. Defaults to `0.4`. */
|
|
11
|
+
readonly roughness?: number;
|
|
12
|
+
/** Curly fiber intensity from `0` to `1`. Defaults to `0.3`. */
|
|
13
|
+
readonly fiber?: number;
|
|
14
|
+
/** Curly fiber scale from `0.01` to `1`. Defaults to `0.2`. */
|
|
15
|
+
readonly fiberSize?: number;
|
|
16
|
+
/** Cell-based crumple intensity from `0` to `1`. Defaults to `0.3`. */
|
|
17
|
+
readonly crumples?: number;
|
|
18
|
+
/** Cell-based crumple scale from `0.01` to `1`. Defaults to `0.35`. */
|
|
19
|
+
readonly crumpleSize?: number;
|
|
20
|
+
/** Fold lighting intensity from `0` to `1`. Defaults to `0.65`. */
|
|
21
|
+
readonly folds?: number;
|
|
22
|
+
/** Number of generated folds from `0` to `15`. Defaults to `5`. */
|
|
23
|
+
readonly foldCount?: number;
|
|
24
|
+
/** Speckle visibility from `0` to `1`. Defaults to `0.2`. */
|
|
25
|
+
readonly drops?: number;
|
|
26
|
+
/** Large-scale mask applied to the paper pattern from `0` to `1`. Defaults to `0`. */
|
|
27
|
+
readonly fade?: number;
|
|
28
|
+
/** Seed for the generated paper pattern from `0` to `1000`. Defaults to `6`. */
|
|
29
|
+
readonly seed?: number;
|
|
30
|
+
/** Scale of the generated paper texture from `0.01` to `4`. Defaults to `0.6`. */
|
|
31
|
+
readonly scale?: number;
|
|
32
|
+
};
|
|
33
|
+
export declare const paper: (params?: (PaperParams & {
|
|
34
|
+
readonly disabled?: boolean | undefined;
|
|
35
|
+
}) | undefined) => import("remotion").EffectDescriptor<unknown>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type RoughenEdgesParams = {
|
|
2
|
+
/** Strength of the roughened edge from `0` to `1`. Defaults to `1`. */
|
|
3
|
+
readonly amount?: number;
|
|
4
|
+
/** Size of the roughened edge in pixels. Defaults to `26.5`. */
|
|
5
|
+
readonly border?: number;
|
|
6
|
+
/** Scale of the generated edge noise from `0.01` to `4`. Defaults to `0.07`. */
|
|
7
|
+
readonly scale?: number;
|
|
8
|
+
/** Seed for the generated edge pattern from `0` to `1000`. Defaults to `231.2`. */
|
|
9
|
+
readonly seed?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const roughenEdges: (params?: (RoughenEdgesParams & {
|
|
12
|
+
readonly disabled?: boolean | undefined;
|
|
13
|
+
}) | undefined) => import("remotion").EffectDescriptor<unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/effects",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.487",
|
|
4
4
|
"description": "Effects that can be applied to Remotion-based canvas components",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"url": "https://github.com/remotion-dev/remotion/issues"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"remotion": "4.0.
|
|
29
|
+
"remotion": "4.0.487"
|
|
30
30
|
},
|
|
31
31
|
"exports": {
|
|
32
32
|
".": {
|
|
@@ -199,6 +199,16 @@
|
|
|
199
199
|
"module": "./dist/esm/noise-displacement.mjs",
|
|
200
200
|
"import": "./dist/esm/noise-displacement.mjs"
|
|
201
201
|
},
|
|
202
|
+
"./paper": {
|
|
203
|
+
"types": "./dist/paper.d.ts",
|
|
204
|
+
"module": "./dist/esm/paper.mjs",
|
|
205
|
+
"import": "./dist/esm/paper.mjs"
|
|
206
|
+
},
|
|
207
|
+
"./roughen-edges": {
|
|
208
|
+
"types": "./dist/roughen-edges.d.ts",
|
|
209
|
+
"module": "./dist/esm/roughen-edges.mjs",
|
|
210
|
+
"import": "./dist/esm/roughen-edges.mjs"
|
|
211
|
+
},
|
|
202
212
|
"./pattern": {
|
|
203
213
|
"types": "./dist/pattern.d.ts",
|
|
204
214
|
"module": "./dist/esm/pattern.mjs",
|
|
@@ -402,6 +412,12 @@
|
|
|
402
412
|
"noise-displacement": [
|
|
403
413
|
"dist/noise-displacement.d.ts"
|
|
404
414
|
],
|
|
415
|
+
"paper": [
|
|
416
|
+
"dist/paper.d.ts"
|
|
417
|
+
],
|
|
418
|
+
"roughen-edges": [
|
|
419
|
+
"dist/roughen-edges.d.ts"
|
|
420
|
+
],
|
|
405
421
|
"pattern": [
|
|
406
422
|
"dist/pattern.d.ts"
|
|
407
423
|
],
|
|
@@ -466,7 +482,7 @@
|
|
|
466
482
|
},
|
|
467
483
|
"homepage": "https://www.remotion.dev/docs/effects/api",
|
|
468
484
|
"devDependencies": {
|
|
469
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
485
|
+
"@remotion/eslint-config-internal": "4.0.487",
|
|
470
486
|
"@vitest/browser-playwright": "4.0.9",
|
|
471
487
|
"eslint": "9.19.0",
|
|
472
488
|
"vitest": "4.0.9",
|