@remotion/effects 4.0.540 → 4.0.542

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 (133) hide show
  1. package/THIRD_PARTY_LICENSES.md +10 -0
  2. package/dist/esm/lightning.mjs +603 -0
  3. package/dist/esm/magnify.mjs +403 -0
  4. package/dist/esm/preview/barrel-distortion.mjs +303 -0
  5. package/dist/esm/preview/bevel-alpha.mjs +525 -0
  6. package/dist/esm/preview/blur.mjs +435 -0
  7. package/dist/esm/preview/brightness.mjs +95 -0
  8. package/dist/esm/preview/burlap.mjs +481 -0
  9. package/dist/esm/preview/checkerboard.mjs +8 -0
  10. package/dist/esm/preview/chromatic-aberration.mjs +308 -0
  11. package/dist/esm/preview/color-correction.mjs +522 -0
  12. package/dist/esm/preview/color-key.mjs +440 -0
  13. package/dist/esm/preview/contour-lines.mjs +608 -0
  14. package/dist/esm/preview/contrast.mjs +95 -0
  15. package/dist/esm/preview/corner-pin.mjs +6 -0
  16. package/dist/esm/preview/curves.mjs +357 -0
  17. package/dist/esm/preview/cylinder.mjs +273 -0
  18. package/dist/esm/preview/dot-grid.mjs +333 -0
  19. package/dist/esm/preview/drop-shadow.mjs +607 -0
  20. package/dist/esm/preview/duotone.mjs +344 -0
  21. package/dist/esm/preview/emboss.mjs +479 -0
  22. package/dist/esm/preview/evolve.mjs +485 -0
  23. package/dist/esm/preview/exposure.mjs +264 -0
  24. package/dist/esm/preview/film-burn.mjs +298 -0
  25. package/dist/esm/preview/fisheye.mjs +422 -0
  26. package/dist/esm/preview/flannel.mjs +401 -0
  27. package/dist/esm/preview/fractal-noise.mjs +642 -0
  28. package/dist/esm/preview/glow.mjs +598 -0
  29. package/dist/esm/preview/grayscale.mjs +86 -0
  30. package/dist/esm/preview/gridlines.mjs +8 -0
  31. package/dist/esm/preview/halftone-linear-gradient.mjs +523 -0
  32. package/dist/esm/preview/halftone.mjs +552 -0
  33. package/dist/esm/preview/hue.mjs +83 -0
  34. package/dist/esm/preview/index-00v3hr66.mjs +299 -0
  35. package/dist/esm/preview/index-0w4eqht8.mjs +351 -0
  36. package/dist/esm/preview/index-18y0zcy2.mjs +440 -0
  37. package/dist/esm/preview/index-1m1b1ad7.mjs +520 -0
  38. package/dist/esm/preview/index-34fxm3ax.mjs +518 -0
  39. package/dist/esm/preview/index-4fvp93ps.mjs +32 -0
  40. package/dist/esm/preview/index-4scpn12x.mjs +224 -0
  41. package/dist/esm/preview/index-4z6pt3ka.mjs +104 -0
  42. package/dist/esm/preview/index-618ky75w.mjs +51 -0
  43. package/dist/esm/preview/index-6agxdrvr.mjs +411 -0
  44. package/dist/esm/preview/index-6jkps947.mjs +120 -0
  45. package/dist/esm/preview/index-8agtsbw4.mjs +617 -0
  46. package/dist/esm/preview/index-8jx11jyn.mjs +29 -0
  47. package/dist/esm/preview/index-8p04sssx.mjs +123 -0
  48. package/dist/esm/preview/index-afdtmrh2.mjs +596 -0
  49. package/dist/esm/preview/index-b86qstcs.mjs +18 -0
  50. package/dist/esm/preview/index-cb77qg3g.mjs +587 -0
  51. package/dist/esm/preview/index-cdp7tr8x.mjs +122 -0
  52. package/dist/esm/preview/index-evy8hyah.mjs +55 -0
  53. package/dist/esm/preview/index-gnsce796.mjs +6 -0
  54. package/dist/esm/preview/index-kkvzt8b7.mjs +199 -0
  55. package/dist/esm/preview/index-r0v18b2n.mjs +425 -0
  56. package/dist/esm/preview/index-rswpzmm5.mjs +926 -0
  57. package/dist/esm/preview/index-s9mrx750.mjs +97 -0
  58. package/dist/esm/preview/index-tvfexb7s.mjs +164 -0
  59. package/dist/esm/preview/index-vp56k1gj.mjs +215 -0
  60. package/dist/esm/preview/index-wxhvgv2s.mjs +79 -0
  61. package/dist/esm/preview/index-wy95a41r.mjs +407 -0
  62. package/dist/esm/preview/index-ysnwfc4t.mjs +306 -0
  63. package/dist/esm/preview/index.mjs +51 -0
  64. package/dist/esm/preview/invert.mjs +84 -0
  65. package/dist/esm/preview/iris-wipe.mjs +315 -0
  66. package/dist/esm/preview/lens-blur.mjs +563 -0
  67. package/dist/esm/preview/levels.mjs +400 -0
  68. package/dist/esm/preview/light-leak.mjs +8 -0
  69. package/dist/esm/preview/light-trail.mjs +516 -0
  70. package/dist/esm/preview/lightning.mjs +603 -0
  71. package/dist/esm/preview/linear-gradient-tint.mjs +6 -0
  72. package/dist/esm/preview/linear-gradient.mjs +6 -0
  73. package/dist/esm/preview/linear-progressive-blur.mjs +516 -0
  74. package/dist/esm/preview/linear-progressive-pixelate.mjs +176 -0
  75. package/dist/esm/preview/lines.mjs +536 -0
  76. package/dist/esm/preview/liquid-contours.mjs +512 -0
  77. package/dist/esm/preview/long-shadows.mjs +437 -0
  78. package/dist/esm/preview/lut.mjs +601 -0
  79. package/dist/esm/preview/magnify.mjs +403 -0
  80. package/dist/esm/preview/mirror.mjs +341 -0
  81. package/dist/esm/preview/noise-displacement.mjs +584 -0
  82. package/dist/esm/preview/noise.mjs +318 -0
  83. package/dist/esm/preview/outline.mjs +725 -0
  84. package/dist/esm/preview/page-turn.mjs +302 -0
  85. package/dist/esm/preview/paper.mjs +1249 -0
  86. package/dist/esm/preview/pattern.mjs +6 -0
  87. package/dist/esm/preview/pixel-dissolve.mjs +360 -0
  88. package/dist/esm/preview/pixelate.mjs +249 -0
  89. package/dist/esm/preview/radial-progressive-blur.mjs +582 -0
  90. package/dist/esm/preview/radial-progressive-pixelate.mjs +220 -0
  91. package/dist/esm/preview/radial-wipe.mjs +224 -0
  92. package/dist/esm/preview/rain-fall.mjs +114 -0
  93. package/dist/esm/preview/region-blur.mjs +500 -0
  94. package/dist/esm/preview/rings.mjs +8 -0
  95. package/dist/esm/preview/roughen-edges.mjs +590 -0
  96. package/dist/esm/preview/saturation.mjs +86 -0
  97. package/dist/esm/preview/scale.mjs +109 -0
  98. package/dist/esm/preview/scanlines.mjs +362 -0
  99. package/dist/esm/preview/shadows-highlights.mjs +284 -0
  100. package/dist/esm/preview/shatter.mjs +868 -0
  101. package/dist/esm/preview/shine.mjs +368 -0
  102. package/dist/esm/preview/shrinkwrap.mjs +769 -0
  103. package/dist/esm/preview/skew.mjs +300 -0
  104. package/dist/esm/preview/snow-fall.mjs +170 -0
  105. package/dist/esm/preview/speckle.mjs +356 -0
  106. package/dist/esm/preview/sphere.mjs +252 -0
  107. package/dist/esm/preview/starburst.mjs +8 -0
  108. package/dist/esm/preview/tear.mjs +375 -0
  109. package/dist/esm/preview/thermal-vision.mjs +387 -0
  110. package/dist/esm/preview/tile.mjs +7 -0
  111. package/dist/esm/preview/tint.mjs +125 -0
  112. package/dist/esm/preview/translate.mjs +151 -0
  113. package/dist/esm/preview/turbulent-displace.mjs +613 -0
  114. package/dist/esm/preview/tv-signal-off.mjs +308 -0
  115. package/dist/esm/preview/venetian-blinds.mjs +341 -0
  116. package/dist/esm/preview/vibrance.mjs +254 -0
  117. package/dist/esm/preview/vignette.mjs +458 -0
  118. package/dist/esm/preview/wave.mjs +384 -0
  119. package/dist/esm/preview/waves.mjs +599 -0
  120. package/dist/esm/preview/white-balance.mjs +280 -0
  121. package/dist/esm/preview/white-noise.mjs +244 -0
  122. package/dist/esm/preview/zigzag.mjs +8 -0
  123. package/dist/esm/preview/zoom-blur.mjs +389 -0
  124. package/dist/lightning/geometry.d.ts +10 -0
  125. package/dist/lightning/index.d.ts +4 -0
  126. package/dist/lightning/mask.d.ts +2 -0
  127. package/dist/lightning/params.d.ts +259 -0
  128. package/dist/lightning/shaders.d.ts +2 -0
  129. package/dist/lightning.d.ts +2 -0
  130. package/dist/magnify/shader.d.ts +1 -0
  131. package/dist/magnify/webgpu-shader.d.ts +1 -0
  132. package/dist/magnify.d.ts +28 -0
  133. package/package.json +30 -6
@@ -0,0 +1,109 @@
1
+ import"./index-8p04sssx.mjs";
2
+ import {
3
+ createRectTransformImplementations
4
+ } from "./index-s9mrx750.mjs";
5
+ import {
6
+ assertEffectParamsObject,
7
+ assertRequiredFiniteNumber
8
+ } from "./index-4fvp93ps.mjs";
9
+
10
+ // src/scale/index.ts
11
+ import { Internals } from "remotion";
12
+ var { createEffect } = Internals;
13
+ var scaleSchema = {
14
+ scale: {
15
+ type: "number",
16
+ min: 0.1,
17
+ max: 10,
18
+ step: 0.1,
19
+ default: 1,
20
+ description: "Factor",
21
+ hiddenFromList: false,
22
+ defaultKeyframeOutput: "perceptual-scale"
23
+ },
24
+ horizontal: {
25
+ type: "boolean",
26
+ default: true,
27
+ description: "Horizontal"
28
+ },
29
+ vertical: {
30
+ type: "boolean",
31
+ default: true,
32
+ description: "Vertical"
33
+ }
34
+ };
35
+ var resolve = (p) => ({
36
+ scale: p.scale,
37
+ horizontal: p.horizontal ?? true,
38
+ vertical: p.vertical ?? true
39
+ });
40
+ var validateScaleParams = (params) => {
41
+ assertEffectParamsObject(params, "Scale");
42
+ assertRequiredFiniteNumber(params.scale, "scale");
43
+ if (typeof params.horizontal !== "undefined" && typeof params.horizontal !== "boolean") {
44
+ throw new TypeError(`"horizontal" must be a boolean, but got ${JSON.stringify(params.horizontal)}`);
45
+ }
46
+ if (typeof params.vertical !== "undefined" && typeof params.vertical !== "boolean") {
47
+ throw new TypeError(`"vertical" must be a boolean, but got ${JSON.stringify(params.vertical)}`);
48
+ }
49
+ const resolved = resolve(params);
50
+ if (resolved.scale <= 0) {
51
+ throw new TypeError(`"scale" must be greater than 0, but got ${JSON.stringify(resolved.scale)}`);
52
+ }
53
+ };
54
+ var scale = createEffect({
55
+ type: "dev.remotion.effects.scale",
56
+ label: "scale()",
57
+ documentationLink: "https://www.remotion.dev/docs/effects/scale",
58
+ calculateKey: (params) => {
59
+ const r = resolve(params);
60
+ return `scale-${r.scale}-${r.horizontal}-${r.vertical}`;
61
+ },
62
+ implementations: {
63
+ ...createRectTransformImplementations("scale", (params, width, height) => {
64
+ const r = resolve(params);
65
+ const scaledWidth = width * (r.horizontal ? r.scale : 1);
66
+ const scaledHeight = height * (r.vertical ? r.scale : 1);
67
+ return {
68
+ x: (width - scaledWidth) / 2,
69
+ y: (height - scaledHeight) / 2,
70
+ width: scaledWidth,
71
+ height: scaledHeight
72
+ };
73
+ }),
74
+ "2d": Internals.createEffectImplementation({
75
+ setup: () => null,
76
+ apply: ({ source, target, width, height, params }) => {
77
+ const ctx = target.getContext("2d");
78
+ if (!ctx) {
79
+ throw new Error("Failed to acquire 2D context for scale effect. The canvas may have been assigned a different context type.");
80
+ }
81
+ const r = resolve(params);
82
+ const scaleX = r.horizontal ? r.scale : 1;
83
+ const scaleY = r.vertical ? r.scale : 1;
84
+ if (scaleX === 1 && scaleY === 1) {
85
+ ctx.clearRect(0, 0, width, height);
86
+ ctx.drawImage(source, 0, 0, width, height);
87
+ return;
88
+ }
89
+ ctx.clearRect(0, 0, width, height);
90
+ ctx.save();
91
+ const centerX = width / 2;
92
+ const centerY = height / 2;
93
+ ctx.translate(centerX, centerY);
94
+ ctx.scale(scaleX, scaleY);
95
+ ctx.translate(-centerX, -centerY);
96
+ ctx.drawImage(source, 0, 0, width, height);
97
+ ctx.restore();
98
+ },
99
+ cleanup: () => {
100
+ return;
101
+ }
102
+ })
103
+ },
104
+ schema: scaleSchema,
105
+ validateParams: validateScaleParams
106
+ });
107
+ export {
108
+ scale
109
+ };
@@ -0,0 +1,362 @@
1
+ import {
2
+ assertOptionalFiniteNumber,
3
+ validateUnitInterval,
4
+ validateNonNegative
5
+ } from "./index-wxhvgv2s.mjs";
6
+ import {
7
+ WEBGPU_SINGLE_PASS_VERTEX,
8
+ setupWebGpuSinglePass,
9
+ cleanupWebGpuSinglePass,
10
+ applyWebGpuSinglePass
11
+ } from "./index-tvfexb7s.mjs";
12
+ import {
13
+ assertEffectParamsObject
14
+ } from "./index-4fvp93ps.mjs";
15
+
16
+ // src/scanlines.ts
17
+ import { Internals } from "remotion";
18
+ var { createEffect, createWebGL2ContextError } = Internals;
19
+ var DEFAULT_AMOUNT = 0.15;
20
+ var DEFAULT_SPACING = 4;
21
+ var DEFAULT_THICKNESS = 1;
22
+ var DEFAULT_OFFSET = 0;
23
+ var DEFAULT_PREMULTIPLY = false;
24
+ var scanlinesSchema = {
25
+ amount: {
26
+ type: "number",
27
+ min: 0,
28
+ max: 1,
29
+ step: 0.01,
30
+ default: DEFAULT_AMOUNT,
31
+ description: "Amount",
32
+ hiddenFromList: false
33
+ },
34
+ spacing: {
35
+ type: "number",
36
+ min: 0.1,
37
+ max: 100,
38
+ step: 0.1,
39
+ default: DEFAULT_SPACING,
40
+ description: "Spacing",
41
+ hiddenFromList: false
42
+ },
43
+ thickness: {
44
+ type: "number",
45
+ min: 0,
46
+ max: 100,
47
+ step: 0.1,
48
+ default: DEFAULT_THICKNESS,
49
+ description: "Thickness",
50
+ hiddenFromList: false
51
+ },
52
+ offset: {
53
+ type: "number",
54
+ step: 0.1,
55
+ default: DEFAULT_OFFSET,
56
+ description: "Offset",
57
+ hiddenFromList: false
58
+ },
59
+ premultiply: {
60
+ type: "boolean",
61
+ default: DEFAULT_PREMULTIPLY,
62
+ description: "Premultiply"
63
+ }
64
+ };
65
+ var resolve = (p) => ({
66
+ amount: p.amount ?? DEFAULT_AMOUNT,
67
+ spacing: p.spacing ?? DEFAULT_SPACING,
68
+ thickness: p.thickness ?? DEFAULT_THICKNESS,
69
+ offset: p.offset ?? DEFAULT_OFFSET,
70
+ premultiply: p.premultiply ?? DEFAULT_PREMULTIPLY
71
+ });
72
+ var assertOptionalBoolean = (value, name) => {
73
+ if (value === undefined) {
74
+ return;
75
+ }
76
+ if (typeof value !== "boolean") {
77
+ throw new TypeError(`"${name}" must be a boolean, but got ${JSON.stringify(value)}`);
78
+ }
79
+ };
80
+ var validatePositive = (value, name) => {
81
+ if (value <= 0) {
82
+ throw new TypeError(`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`);
83
+ }
84
+ };
85
+ var validateScanlinesParams = (params) => {
86
+ assertEffectParamsObject(params, "Scanlines");
87
+ assertOptionalFiniteNumber(params.amount, "amount");
88
+ assertOptionalFiniteNumber(params.spacing, "spacing");
89
+ assertOptionalFiniteNumber(params.thickness, "thickness");
90
+ assertOptionalFiniteNumber(params.offset, "offset");
91
+ assertOptionalBoolean(params.premultiply, "premultiply");
92
+ const r = resolve(params);
93
+ validateUnitInterval(r.amount, "amount");
94
+ validatePositive(r.spacing, "spacing");
95
+ validateNonNegative(r.thickness, "thickness");
96
+ };
97
+ var SCANLINES_VS = `#version 300 es
98
+ in vec2 aPos;
99
+ in vec2 aUv;
100
+ out vec2 vUv;
101
+
102
+ void main() {
103
+ vUv = aUv;
104
+ gl_Position = vec4(aPos, 0.0, 1.0);
105
+ }
106
+ `;
107
+ var SCANLINES_FS = `#version 300 es
108
+ precision highp float;
109
+
110
+ in vec2 vUv;
111
+ out vec4 fragColor;
112
+
113
+ uniform sampler2D uSource;
114
+ uniform float uAmount;
115
+ uniform float uSpacing;
116
+ uniform float uThickness;
117
+ uniform float uOffset;
118
+ uniform bool uPremultiply;
119
+
120
+ void main() {
121
+ vec4 texColor = texture(uSource, vUv);
122
+ float alpha = texColor.a;
123
+
124
+ if (alpha <= 0.001) {
125
+ fragColor = vec4(0.0);
126
+ return;
127
+ }
128
+
129
+ if (uAmount <= 0.0 || uThickness <= 0.0) {
130
+ fragColor = texColor;
131
+ return;
132
+ }
133
+
134
+ float spacing = max(uSpacing, 0.001);
135
+ float thickness = min(uThickness, spacing);
136
+ float halfThickness = thickness * 0.5;
137
+ float position = mod(gl_FragCoord.y + uOffset, spacing);
138
+ float distanceToLine = min(position, spacing - position);
139
+ float line = 1.0 - smoothstep(halfThickness, halfThickness + 1.0, distanceToLine);
140
+ float dutyCycle = thickness / spacing;
141
+ float signal = line - dutyCycle;
142
+
143
+ vec3 rgb = texColor.rgb / alpha;
144
+ vec3 scanlineLayer = uPremultiply ? rgb * signal : vec3(signal);
145
+ rgb = clamp(rgb + scanlineLayer * uAmount, 0.0, 1.0);
146
+ fragColor = vec4(rgb * alpha, alpha);
147
+ }
148
+ `;
149
+ var compileShader = (gl, type, source) => {
150
+ const shader = gl.createShader(type);
151
+ if (!shader) {
152
+ throw new Error("Failed to create WebGL shader");
153
+ }
154
+ gl.shaderSource(shader, source);
155
+ gl.compileShader(shader);
156
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
157
+ const log = gl.getShaderInfoLog(shader);
158
+ gl.deleteShader(shader);
159
+ throw new Error(`Scanlines shader compile failed: ${log ?? "(no log)"}`);
160
+ }
161
+ return shader;
162
+ };
163
+ var linkProgram = (gl, vs, fs) => {
164
+ const program = gl.createProgram();
165
+ if (!program) {
166
+ throw new Error("Failed to create WebGL program");
167
+ }
168
+ gl.attachShader(program, vs);
169
+ gl.attachShader(program, fs);
170
+ gl.linkProgram(program);
171
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
172
+ const log = gl.getProgramInfoLog(program);
173
+ gl.deleteProgram(program);
174
+ throw new Error(`Scanlines program link failed: ${log ?? "(no log)"}`);
175
+ }
176
+ return program;
177
+ };
178
+ var setupScanlines = (target) => {
179
+ const gl = target.getContext("webgl2", {
180
+ premultipliedAlpha: true,
181
+ alpha: true,
182
+ preserveDrawingBuffer: true
183
+ });
184
+ if (!gl) {
185
+ throw createWebGL2ContextError("scanlines effect");
186
+ }
187
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
188
+ const vs = compileShader(gl, gl.VERTEX_SHADER, SCANLINES_VS);
189
+ const fs = compileShader(gl, gl.FRAGMENT_SHADER, SCANLINES_FS);
190
+ const program = linkProgram(gl, vs, fs);
191
+ gl.deleteShader(vs);
192
+ gl.deleteShader(fs);
193
+ const vao = gl.createVertexArray();
194
+ if (!vao) {
195
+ throw new Error("Failed to create WebGL vertex array");
196
+ }
197
+ gl.bindVertexArray(vao);
198
+ const data = new Float32Array([
199
+ -1,
200
+ -1,
201
+ 0,
202
+ 0,
203
+ 1,
204
+ -1,
205
+ 1,
206
+ 0,
207
+ -1,
208
+ 1,
209
+ 0,
210
+ 1,
211
+ 1,
212
+ 1,
213
+ 1,
214
+ 1
215
+ ]);
216
+ const vbo = gl.createBuffer();
217
+ if (!vbo) {
218
+ throw new Error("Failed to create WebGL buffer");
219
+ }
220
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
221
+ gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
222
+ const aPos = gl.getAttribLocation(program, "aPos");
223
+ const aUv = gl.getAttribLocation(program, "aUv");
224
+ gl.enableVertexAttribArray(aPos);
225
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
226
+ gl.enableVertexAttribArray(aUv);
227
+ gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
228
+ gl.bindVertexArray(null);
229
+ const texture = gl.createTexture();
230
+ if (!texture) {
231
+ throw new Error("Failed to create WebGL texture");
232
+ }
233
+ gl.bindTexture(gl.TEXTURE_2D, texture);
234
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
235
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
236
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
237
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
238
+ gl.bindTexture(gl.TEXTURE_2D, null);
239
+ return {
240
+ gl,
241
+ program,
242
+ vao,
243
+ vbo,
244
+ texture,
245
+ uSource: gl.getUniformLocation(program, "uSource"),
246
+ uAmount: gl.getUniformLocation(program, "uAmount"),
247
+ uSpacing: gl.getUniformLocation(program, "uSpacing"),
248
+ uThickness: gl.getUniformLocation(program, "uThickness"),
249
+ uOffset: gl.getUniformLocation(program, "uOffset"),
250
+ uPremultiply: gl.getUniformLocation(program, "uPremultiply")
251
+ };
252
+ };
253
+ var WEBGPU_SHADER = `
254
+ ${WEBGPU_SINGLE_PASS_VERTEX}
255
+ struct Params { controls: vec4f, options: vec4f, }
256
+ @group(0) @binding(0) var source: texture_2d<f32>;
257
+ @group(0) @binding(1) var sourceSampler: sampler;
258
+ @group(0) @binding(2) var<uniform> params: Params;
259
+ @fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {
260
+ let texColor = textureSampleLevel(source, sourceSampler, input.uv, 0);
261
+ let alpha = texColor.a;
262
+ if (alpha <= 0.001) { return vec4f(0); }
263
+ if (params.controls.x <= 0.0 || params.controls.z <= 0.0) { return texColor; }
264
+ let spacing = max(params.controls.y, 0.001);
265
+ let thickness = min(params.controls.z, spacing);
266
+ let halfThickness = thickness * 0.5;
267
+ // WebGL fragment coordinates run bottom-to-top.
268
+ let rawPosition = params.options.y - input.position.y + params.controls.w;
269
+ let position = rawPosition - spacing * floor(rawPosition / spacing);
270
+ let distanceToLine = min(position, spacing - position);
271
+ let line = 1.0 - smoothstep(halfThickness, halfThickness + 1.0, distanceToLine);
272
+ let dutyCycle = thickness / spacing;
273
+ let signal = line - dutyCycle;
274
+ let rgb = texColor.rgb / alpha;
275
+ let scanlineLayer = select(vec3f(signal), rgb * signal, params.options.x != 0.0);
276
+ let result = clamp(rgb + scanlineLayer * params.controls.x, vec3f(0), vec3f(1));
277
+ return vec4f(result * alpha, alpha);
278
+ }
279
+ `;
280
+ var scanlines = createEffect({
281
+ type: "dev.remotion.effects.scanlines",
282
+ label: "scanlines()",
283
+ documentationLink: "https://www.remotion.dev/docs/effects/scanlines",
284
+ calculateKey: (params) => {
285
+ const r = resolve(params);
286
+ return `scanlines-${r.amount}-${r.spacing}-${r.thickness}-${r.offset}-${r.premultiply ? 1 : 0}`;
287
+ },
288
+ implementations: {
289
+ webgpu: Internals.createEffectImplementation({
290
+ setup: (target) => setupWebGpuSinglePass(target, "scanlines"),
291
+ apply: ({ source, width, height, params, state, gpuDevice }) => {
292
+ if (!gpuDevice) {
293
+ throw new Error("A WebGPU device is required for the scanlines effect");
294
+ }
295
+ const r = resolve(params);
296
+ applyWebGpuSinglePass({
297
+ source,
298
+ width,
299
+ height,
300
+ state,
301
+ device: gpuDevice,
302
+ shader: WEBGPU_SHADER,
303
+ uniformData: new Float32Array([
304
+ r.amount,
305
+ r.spacing,
306
+ r.thickness,
307
+ r.offset,
308
+ r.premultiply ? 1 : 0,
309
+ height,
310
+ 0,
311
+ 0
312
+ ])
313
+ });
314
+ },
315
+ cleanup: cleanupWebGpuSinglePass
316
+ }),
317
+ webgl2: Internals.createEffectImplementation({
318
+ setup: (target) => setupScanlines(target),
319
+ apply: ({ source, width, height, params, state, flipSourceY }) => {
320
+ const r = resolve(params);
321
+ const { gl, program, texture, vao } = state;
322
+ gl.viewport(0, 0, width, height);
323
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
324
+ gl.clearColor(0, 0, 0, 0);
325
+ gl.clear(gl.COLOR_BUFFER_BIT);
326
+ gl.activeTexture(gl.TEXTURE0);
327
+ gl.bindTexture(gl.TEXTURE_2D, texture);
328
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
329
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
330
+ gl.useProgram(program);
331
+ if (state.uSource)
332
+ gl.uniform1i(state.uSource, 0);
333
+ if (state.uAmount)
334
+ gl.uniform1f(state.uAmount, r.amount);
335
+ if (state.uSpacing)
336
+ gl.uniform1f(state.uSpacing, r.spacing);
337
+ if (state.uThickness)
338
+ gl.uniform1f(state.uThickness, r.thickness);
339
+ if (state.uOffset)
340
+ gl.uniform1f(state.uOffset, r.offset);
341
+ if (state.uPremultiply)
342
+ gl.uniform1i(state.uPremultiply, r.premultiply ? 1 : 0);
343
+ gl.bindVertexArray(vao);
344
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
345
+ gl.bindVertexArray(null);
346
+ gl.bindTexture(gl.TEXTURE_2D, null);
347
+ gl.useProgram(null);
348
+ },
349
+ cleanup: ({ gl, program, vao, vbo, texture }) => {
350
+ gl.deleteTexture(texture);
351
+ gl.deleteBuffer(vbo);
352
+ gl.deleteProgram(program);
353
+ gl.deleteVertexArray(vao);
354
+ }
355
+ })
356
+ },
357
+ schema: scanlinesSchema,
358
+ validateParams: validateScanlinesParams
359
+ });
360
+ export {
361
+ scanlines
362
+ };