@remotion/effects 4.0.536 → 4.0.538

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.
Files changed (113) hide show
  1. package/THIRD_PARTY_LICENSES.md +30 -0
  2. package/dist/barrel-distortion/index.d.ts +1 -1
  3. package/dist/bevel-alpha/index.d.ts +13 -0
  4. package/dist/bevel-alpha/shaders.d.ts +3 -0
  5. package/dist/bevel-alpha.d.ts +1 -0
  6. package/dist/blur/index.d.ts +1 -1
  7. package/dist/brightness.d.ts +1 -1
  8. package/dist/burlap.d.ts +1 -1
  9. package/dist/checkerboard.d.ts +17 -17
  10. package/dist/chromatic-aberration/index.d.ts +1 -1
  11. package/dist/color-correction.d.ts +1 -1
  12. package/dist/color-key.d.ts +9 -9
  13. package/dist/color-utils.d.ts +8 -8
  14. package/dist/contour-lines.d.ts +23 -23
  15. package/dist/contrast.d.ts +1 -1
  16. package/dist/corner-pin/index.d.ts +1 -1
  17. package/dist/cylinder/index.d.ts +20 -0
  18. package/dist/cylinder/shader.d.ts +1 -0
  19. package/dist/cylinder.d.ts +1 -0
  20. package/dist/dot-grid.d.ts +7 -7
  21. package/dist/drop-shadow/index.d.ts +1 -1
  22. package/dist/duotone.d.ts +7 -7
  23. package/dist/emboss.d.ts +15 -15
  24. package/dist/esm/bevel-alpha.mjs +474 -0
  25. package/dist/esm/cylinder.mjs +390 -0
  26. package/dist/esm/fractal-noise.mjs +688 -0
  27. package/dist/esm/lens-blur.mjs +550 -0
  28. package/dist/esm/long-shadows.mjs +410 -0
  29. package/dist/esm/page-turn.mjs +405 -0
  30. package/dist/esm/sphere.mjs +376 -0
  31. package/dist/esm/turbulent-displace.mjs +652 -0
  32. package/dist/evolve.d.ts +8 -8
  33. package/dist/exposure.d.ts +1 -1
  34. package/dist/fisheye/index.d.ts +1 -1
  35. package/dist/flannel.d.ts +1 -1
  36. package/dist/fractal-noise/index.d.ts +40 -0
  37. package/dist/fractal-noise/shader.d.ts +1 -0
  38. package/dist/fractal-noise.d.ts +1 -0
  39. package/dist/gaussian-blur-shader.d.ts +1 -1
  40. package/dist/glow/index.d.ts +1 -1
  41. package/dist/grayscale.d.ts +1 -1
  42. package/dist/gridlines.d.ts +23 -23
  43. package/dist/halftone-linear-gradient.d.ts +21 -21
  44. package/dist/halftone.d.ts +25 -25
  45. package/dist/hue.d.ts +1 -1
  46. package/dist/invert.d.ts +1 -1
  47. package/dist/lens-blur/index.d.ts +30 -0
  48. package/dist/lens-blur/shader.d.ts +1 -0
  49. package/dist/lens-blur.d.ts +1 -0
  50. package/dist/levels.d.ts +1 -1
  51. package/dist/light-leak.d.ts +7 -7
  52. package/dist/light-trail/index.d.ts +1 -1
  53. package/dist/linear-gradient-tint.d.ts +1 -1
  54. package/dist/linear-gradient.d.ts +1 -1
  55. package/dist/linear-progressive-blur/index.d.ts +1 -1
  56. package/dist/linear-progressive-blur/linear-progressive-blur-shaders.d.ts +1 -1
  57. package/dist/linear-progressive-pixelate/index.d.ts +1 -1
  58. package/dist/lines.d.ts +18 -18
  59. package/dist/liquid-contours.d.ts +21 -21
  60. package/dist/long-shadows.d.ts +13 -0
  61. package/dist/lut/index.d.ts +3 -3
  62. package/dist/mirror/index.d.ts +1 -1
  63. package/dist/noise-displacement.d.ts +1 -1
  64. package/dist/noise.d.ts +1 -1
  65. package/dist/outline/polygonize-alpha.d.ts +1 -1
  66. package/dist/outline.d.ts +11 -11
  67. package/dist/page-turn/index.d.ts +20 -0
  68. package/dist/page-turn/shader.d.ts +1 -0
  69. package/dist/page-turn.d.ts +1 -0
  70. package/dist/paper.d.ts +1 -1
  71. package/dist/pattern.d.ts +1 -1
  72. package/dist/pixel-dissolve.d.ts +1 -1
  73. package/dist/pixelate.d.ts +1 -1
  74. package/dist/radial-progressive-blur/index.d.ts +1 -1
  75. package/dist/radial-progressive-blur/radial-progressive-blur-shaders.d.ts +1 -1
  76. package/dist/radial-progressive-pixelate/index.d.ts +1 -1
  77. package/dist/region-blur/index.d.ts +11 -11
  78. package/dist/rings.d.ts +15 -15
  79. package/dist/roughen-edges.d.ts +1 -1
  80. package/dist/saturation.d.ts +1 -1
  81. package/dist/scale/index.d.ts +1 -1
  82. package/dist/scanlines.d.ts +1 -1
  83. package/dist/shadows-highlights.d.ts +1 -1
  84. package/dist/shine.d.ts +1 -1
  85. package/dist/shrinkwrap.d.ts +1 -1
  86. package/dist/skew.d.ts +1 -1
  87. package/dist/speckle.d.ts +1 -1
  88. package/dist/sphere/index.d.ts +18 -0
  89. package/dist/sphere/shader.d.ts +1 -0
  90. package/dist/sphere.d.ts +1 -0
  91. package/dist/starburst.d.ts +13 -13
  92. package/dist/tear.d.ts +1 -1
  93. package/dist/thermal-vision.d.ts +7 -7
  94. package/dist/tile.d.ts +1 -1
  95. package/dist/tint.d.ts +5 -5
  96. package/dist/translate/index.d.ts +2 -2
  97. package/dist/turbulent-displace/index.d.ts +28 -0
  98. package/dist/turbulent-displace/shader.d.ts +1 -0
  99. package/dist/turbulent-displace.d.ts +1 -0
  100. package/dist/tv-signal-off.d.ts +1 -1
  101. package/dist/value-noise-shader.d.ts +1 -0
  102. package/dist/venetian-blinds.d.ts +8 -8
  103. package/dist/vibrance.d.ts +1 -1
  104. package/dist/vignette.d.ts +16 -16
  105. package/dist/visual-test/visual-utils.d.ts +8 -8
  106. package/dist/wave/index.d.ts +1 -1
  107. package/dist/waves.d.ts +24 -24
  108. package/dist/webgpu-projection-runtime.d.ts +24 -0
  109. package/dist/white-balance.d.ts +1 -1
  110. package/dist/white-noise.d.ts +1 -1
  111. package/dist/zigzag.d.ts +22 -22
  112. package/dist/zoom-blur/index.d.ts +1 -1
  113. package/package.json +71 -6
@@ -0,0 +1,405 @@
1
+ // src/page-turn/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/webgpu-projection-runtime.ts
110
+ var cleanupWebGpuProjection = (state) => {
111
+ state.resources?.texture.destroy();
112
+ state.resources?.uniforms.destroy();
113
+ state.resources = null;
114
+ state.context.unconfigure();
115
+ };
116
+ var setupWebGpuProjection = (target, label) => {
117
+ const context = target.getContext("webgpu");
118
+ if (!context) {
119
+ throw new Error(`WebGPU is not available for the ${label} effect`);
120
+ }
121
+ return { context, resources: null };
122
+ };
123
+ var applyWebGpuProjection = ({
124
+ state,
125
+ source,
126
+ width,
127
+ height,
128
+ device,
129
+ shader,
130
+ uniformData
131
+ }) => {
132
+ if (state.resources && (state.resources.device !== device || state.resources.width !== width || state.resources.height !== height)) {
133
+ cleanupWebGpuProjection(state);
134
+ }
135
+ if (!state.resources) {
136
+ const format = navigator.gpu.getPreferredCanvasFormat();
137
+ state.context.configure({ device, format, alphaMode: "premultiplied" });
138
+ const module = device.createShaderModule({ code: shader });
139
+ const pipeline = device.createRenderPipeline({
140
+ layout: "auto",
141
+ vertex: { module, entryPoint: "vertex" },
142
+ fragment: { module, entryPoint: "fragment", targets: [{ format }] },
143
+ primitive: { topology: "triangle-list" }
144
+ });
145
+ const uniforms = device.createBuffer({
146
+ size: uniformData.byteLength,
147
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
148
+ });
149
+ const sampler = device.createSampler({
150
+ addressModeU: "repeat",
151
+ magFilter: "linear",
152
+ minFilter: "linear"
153
+ });
154
+ const texture = device.createTexture({
155
+ size: [width, height],
156
+ format: "rgba8unorm",
157
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
158
+ });
159
+ const bindGroup = device.createBindGroup({
160
+ layout: pipeline.getBindGroupLayout(0),
161
+ entries: [
162
+ { binding: 0, resource: texture.createView() },
163
+ { binding: 1, resource: sampler },
164
+ { binding: 2, resource: { buffer: uniforms } }
165
+ ]
166
+ });
167
+ state.resources = {
168
+ device,
169
+ pipeline,
170
+ uniforms,
171
+ sampler,
172
+ texture,
173
+ bindGroup,
174
+ width,
175
+ height
176
+ };
177
+ }
178
+ const { resources } = state;
179
+ device.queue.copyExternalImageToTexture({ source }, { texture: resources.texture, premultipliedAlpha: true }, [width, height]);
180
+ device.queue.writeBuffer(resources.uniforms, 0, uniformData);
181
+ const encoder = device.createCommandEncoder();
182
+ const pass = encoder.beginRenderPass({
183
+ colorAttachments: [
184
+ {
185
+ view: state.context.getCurrentTexture().createView(),
186
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
187
+ loadOp: "clear",
188
+ storeOp: "store"
189
+ }
190
+ ]
191
+ });
192
+ pass.setPipeline(resources.pipeline);
193
+ pass.setBindGroup(0, resources.bindGroup);
194
+ pass.draw(3);
195
+ pass.end();
196
+ device.queue.submit([encoder.finish()]);
197
+ };
198
+
199
+ // src/page-turn/shader.ts
200
+ var PAGE_TURN_SHADER = `
201
+ struct Params {
202
+ resolution: vec2f,
203
+ foldPosition: vec2f,
204
+ geometry: vec4f,
205
+ paperColor: vec4f,
206
+ back: vec4f,
207
+ }
208
+ @group(0) @binding(0) var source: texture_2d<f32>;
209
+ @group(0) @binding(1) var sourceSampler: sampler;
210
+ @group(0) @binding(2) var<uniform> params: Params;
211
+
212
+ @vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {
213
+ let positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
214
+ return vec4f(positions[index], 0, 1);
215
+ }
216
+
217
+ fn samplePage(pixel: vec2f) -> vec4f {
218
+ if (any(pixel < vec2f(0)) || any(pixel >= params.resolution)) { return vec4f(0); }
219
+ // The shared projection sampler wraps horizontally; pages must not wrap at the edges.
220
+ let uv = clamp(pixel, vec2f(0.5), params.resolution - vec2f(0.5)) / params.resolution;
221
+ return textureSampleLevel(source, sourceSampler, uv, 0);
222
+ }
223
+
224
+ @fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {
225
+ let radius = params.geometry.x;
226
+ let direction = params.geometry.y;
227
+ let normal = vec2f(-sin(direction), cos(direction));
228
+ let distance = dot(position.xy - params.foldPosition, normal);
229
+ let coverage = 1.0 - smoothstep(radius - max(fwidth(distance), 0.001), radius, distance);
230
+ if (distance >= radius) { return vec4f(0); }
231
+
232
+ var front = vec4f(0);
233
+ var back = vec4f(0);
234
+ var backDistance = 3.14159265359 * radius - distance;
235
+ var backShade = 0.9;
236
+ if (distance <= 0.0) {
237
+ front = samplePage(position.xy);
238
+ } else {
239
+ let angle = asin(clamp(distance / radius, 0.0, 1.0));
240
+ let frontDistance = radius * angle;
241
+ backDistance = 3.14159265359 * radius - frontDistance;
242
+ let light = params.geometry.z;
243
+ let lightDot = normal.x * sin(light) - normal.y * cos(light);
244
+ let shade = 1.0 - 0.4 * (angle / 1.57079632679) * (0.5 + 0.5 * lightDot);
245
+ let color = samplePage(position.xy + normal * (frontDistance - distance));
246
+ front = vec4f(color.rgb * shade, color.a);
247
+ backShade = 0.6 + 0.4 * cos(angle);
248
+ }
249
+ let color = samplePage(position.xy + normal * (backDistance - distance));
250
+ let tint = (1.0 - params.back.x) * params.paperColor.a;
251
+ back = vec4f(mix(color.rgb, params.paperColor.rgb * color.a, tint) * backShade, color.a);
252
+ if (params.geometry.w == 1.0) { return front * coverage; }
253
+ if (params.geometry.w == 2.0) { return back * coverage; }
254
+ // Premultiplied source-over: the curled back covers the front, which shows through its alpha.
255
+ return (back + front * (1.0 - back.a)) * coverage;
256
+ }
257
+ `;
258
+
259
+ // src/page-turn/index.ts
260
+ var DEFAULT_FOLD_POSITION = [0.7, 0.7];
261
+ var DEFAULT_FOLD_DIRECTION = 315;
262
+ var DEFAULT_FOLD_RADIUS = 60;
263
+ var DEFAULT_LIGHT_DIRECTION = -45;
264
+ var DEFAULT_RENDER = "both";
265
+ var DEFAULT_BACK_PAGE_OPACITY = 0.25;
266
+ var DEFAULT_PAPER_COLOR = "#ffffff";
267
+ var pageTurnSchema = {
268
+ foldPosition: {
269
+ type: "uv-coordinate",
270
+ default: DEFAULT_FOLD_POSITION,
271
+ description: "Fold position"
272
+ },
273
+ foldDirection: {
274
+ type: "rotation-degrees",
275
+ default: DEFAULT_FOLD_DIRECTION,
276
+ description: "Fold direction"
277
+ },
278
+ foldRadius: {
279
+ type: "number",
280
+ min: 1,
281
+ max: 500,
282
+ step: 1,
283
+ default: DEFAULT_FOLD_RADIUS,
284
+ description: "Fold radius",
285
+ hiddenFromList: false
286
+ },
287
+ lightDirection: {
288
+ type: "rotation-degrees",
289
+ default: DEFAULT_LIGHT_DIRECTION,
290
+ description: "Light direction"
291
+ },
292
+ render: {
293
+ type: "enum",
294
+ variants: { both: {}, front: {}, back: {} },
295
+ default: DEFAULT_RENDER,
296
+ description: "Faces"
297
+ },
298
+ backPageOpacity: {
299
+ type: "number",
300
+ min: 0,
301
+ max: 1,
302
+ step: 0.01,
303
+ default: DEFAULT_BACK_PAGE_OPACITY,
304
+ description: "Back image opacity",
305
+ hiddenFromList: false
306
+ },
307
+ paperColor: {
308
+ type: "color",
309
+ default: DEFAULT_PAPER_COLOR,
310
+ description: "Paper color"
311
+ }
312
+ };
313
+ var resolve = (params) => ({
314
+ foldPosition: params.foldPosition ?? DEFAULT_FOLD_POSITION,
315
+ foldDirection: params.foldDirection ?? DEFAULT_FOLD_DIRECTION,
316
+ foldRadius: params.foldRadius ?? DEFAULT_FOLD_RADIUS,
317
+ lightDirection: params.lightDirection ?? DEFAULT_LIGHT_DIRECTION,
318
+ render: params.render ?? DEFAULT_RENDER,
319
+ backPageOpacity: params.backPageOpacity ?? DEFAULT_BACK_PAGE_OPACITY,
320
+ paperColor: params.paperColor ?? DEFAULT_PAPER_COLOR
321
+ });
322
+ var pageTurn = Internals.createEffect({
323
+ type: "remotion/page-turn",
324
+ label: "pageTurn()",
325
+ documentationLink: "https://www.remotion.dev/docs/effects/page-turn",
326
+ backend: "webgpu",
327
+ schema: pageTurnSchema,
328
+ validateParams: (params) => {
329
+ assertEffectParamsObject(params, "Page turn");
330
+ for (const key of [
331
+ "foldDirection",
332
+ "foldRadius",
333
+ "lightDirection",
334
+ "backPageOpacity"
335
+ ]) {
336
+ assertOptionalFiniteNumber(params[key], key);
337
+ }
338
+ assertOptionalColor(params.paperColor, "paperColor");
339
+ const r = resolve(params);
340
+ if (r.foldRadius <= 0)
341
+ throw new TypeError('"foldRadius" must be greater than 0');
342
+ validateUnitInterval(r.backPageOpacity, "backPageOpacity");
343
+ if (params.foldPosition !== undefined && (!Array.isArray(params.foldPosition) || params.foldPosition.length !== 2 || !Number.isFinite(params.foldPosition[0]) || !Number.isFinite(params.foldPosition[1]))) {
344
+ throw new TypeError('"foldPosition" must contain two finite numbers');
345
+ }
346
+ if (params.render !== undefined && params.render !== "both" && params.render !== "front" && params.render !== "back") {
347
+ throw new TypeError('"render" must be "both", "front", or "back"');
348
+ }
349
+ },
350
+ calculateKey: (params) => {
351
+ const r = resolve(params);
352
+ return `page-turn-${r.foldPosition.join(",")}-${r.foldDirection}-${r.foldRadius}-${r.lightDirection}-${r.render}-${r.backPageOpacity}-${r.paperColor}`;
353
+ },
354
+ setup: (target) => {
355
+ const colorCanvas = document.createElement("canvas");
356
+ colorCanvas.width = 1;
357
+ colorCanvas.height = 1;
358
+ const colorCtx = colorCanvas.getContext("2d", { willReadFrequently: true });
359
+ if (!colorCtx)
360
+ throw new Error("Could not create the page turn color context");
361
+ return {
362
+ ...setupWebGpuProjection(target, "page turn"),
363
+ colorCtx,
364
+ cachedColor: null,
365
+ cachedRgba: [255, 255, 255, 255]
366
+ };
367
+ },
368
+ apply: ({ source, width, height, params, state, gpuDevice }) => {
369
+ if (!gpuDevice)
370
+ throw new Error("A WebGPU device is required for the page turn effect");
371
+ const r = resolve(params);
372
+ if (state.cachedColor !== r.paperColor) {
373
+ state.cachedColor = r.paperColor;
374
+ state.cachedRgba = parseColorRgba(state.colorCtx, r.paperColor);
375
+ }
376
+ const radians = Math.PI / 180;
377
+ applyWebGpuProjection({
378
+ source,
379
+ width,
380
+ height,
381
+ state,
382
+ device: gpuDevice,
383
+ shader: PAGE_TURN_SHADER,
384
+ uniformData: new Float32Array([
385
+ width,
386
+ height,
387
+ r.foldPosition[0] * width,
388
+ r.foldPosition[1] * height,
389
+ r.foldRadius,
390
+ r.foldDirection % 360 * radians,
391
+ r.lightDirection % 360 * radians,
392
+ r.render === "front" ? 1 : r.render === "back" ? 2 : 0,
393
+ ...state.cachedRgba.map((channel) => channel / 255),
394
+ r.backPageOpacity,
395
+ 0,
396
+ 0,
397
+ 0
398
+ ])
399
+ });
400
+ },
401
+ cleanup: cleanupWebGpuProjection
402
+ });
403
+ export {
404
+ pageTurn
405
+ };