@remotion/effects 4.0.486 → 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/roughen-edges.mjs +566 -0
- package/dist/roughen-edges.d.ts +13 -0
- package/package.json +11 -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
|
+
};
|
|
@@ -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
|
".": {
|
|
@@ -204,6 +204,11 @@
|
|
|
204
204
|
"module": "./dist/esm/paper.mjs",
|
|
205
205
|
"import": "./dist/esm/paper.mjs"
|
|
206
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
|
+
},
|
|
207
212
|
"./pattern": {
|
|
208
213
|
"types": "./dist/pattern.d.ts",
|
|
209
214
|
"module": "./dist/esm/pattern.mjs",
|
|
@@ -410,6 +415,9 @@
|
|
|
410
415
|
"paper": [
|
|
411
416
|
"dist/paper.d.ts"
|
|
412
417
|
],
|
|
418
|
+
"roughen-edges": [
|
|
419
|
+
"dist/roughen-edges.d.ts"
|
|
420
|
+
],
|
|
413
421
|
"pattern": [
|
|
414
422
|
"dist/pattern.d.ts"
|
|
415
423
|
],
|
|
@@ -474,7 +482,7 @@
|
|
|
474
482
|
},
|
|
475
483
|
"homepage": "https://www.remotion.dev/docs/effects/api",
|
|
476
484
|
"devDependencies": {
|
|
477
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
485
|
+
"@remotion/eslint-config-internal": "4.0.487",
|
|
478
486
|
"@vitest/browser-playwright": "4.0.9",
|
|
479
487
|
"eslint": "9.19.0",
|
|
480
488
|
"vitest": "4.0.9",
|