@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.
- package/THIRD_PARTY_LICENSES.md +10 -0
- package/dist/esm/lightning.mjs +603 -0
- package/dist/esm/magnify.mjs +403 -0
- package/dist/esm/preview/barrel-distortion.mjs +303 -0
- package/dist/esm/preview/bevel-alpha.mjs +525 -0
- package/dist/esm/preview/blur.mjs +435 -0
- package/dist/esm/preview/brightness.mjs +95 -0
- package/dist/esm/preview/burlap.mjs +481 -0
- package/dist/esm/preview/checkerboard.mjs +8 -0
- package/dist/esm/preview/chromatic-aberration.mjs +308 -0
- package/dist/esm/preview/color-correction.mjs +522 -0
- package/dist/esm/preview/color-key.mjs +440 -0
- package/dist/esm/preview/contour-lines.mjs +608 -0
- package/dist/esm/preview/contrast.mjs +95 -0
- package/dist/esm/preview/corner-pin.mjs +6 -0
- package/dist/esm/preview/curves.mjs +357 -0
- package/dist/esm/preview/cylinder.mjs +273 -0
- package/dist/esm/preview/dot-grid.mjs +333 -0
- package/dist/esm/preview/drop-shadow.mjs +607 -0
- package/dist/esm/preview/duotone.mjs +344 -0
- package/dist/esm/preview/emboss.mjs +479 -0
- package/dist/esm/preview/evolve.mjs +485 -0
- package/dist/esm/preview/exposure.mjs +264 -0
- package/dist/esm/preview/film-burn.mjs +298 -0
- package/dist/esm/preview/fisheye.mjs +422 -0
- package/dist/esm/preview/flannel.mjs +401 -0
- package/dist/esm/preview/fractal-noise.mjs +642 -0
- package/dist/esm/preview/glow.mjs +598 -0
- package/dist/esm/preview/grayscale.mjs +86 -0
- package/dist/esm/preview/gridlines.mjs +8 -0
- package/dist/esm/preview/halftone-linear-gradient.mjs +523 -0
- package/dist/esm/preview/halftone.mjs +552 -0
- package/dist/esm/preview/hue.mjs +83 -0
- package/dist/esm/preview/index-00v3hr66.mjs +299 -0
- package/dist/esm/preview/index-0w4eqht8.mjs +351 -0
- package/dist/esm/preview/index-18y0zcy2.mjs +440 -0
- package/dist/esm/preview/index-1m1b1ad7.mjs +520 -0
- package/dist/esm/preview/index-34fxm3ax.mjs +518 -0
- package/dist/esm/preview/index-4fvp93ps.mjs +32 -0
- package/dist/esm/preview/index-4scpn12x.mjs +224 -0
- package/dist/esm/preview/index-4z6pt3ka.mjs +104 -0
- package/dist/esm/preview/index-618ky75w.mjs +51 -0
- package/dist/esm/preview/index-6agxdrvr.mjs +411 -0
- package/dist/esm/preview/index-6jkps947.mjs +120 -0
- package/dist/esm/preview/index-8agtsbw4.mjs +617 -0
- package/dist/esm/preview/index-8jx11jyn.mjs +29 -0
- package/dist/esm/preview/index-8p04sssx.mjs +123 -0
- package/dist/esm/preview/index-afdtmrh2.mjs +596 -0
- package/dist/esm/preview/index-b86qstcs.mjs +18 -0
- package/dist/esm/preview/index-cb77qg3g.mjs +587 -0
- package/dist/esm/preview/index-cdp7tr8x.mjs +122 -0
- package/dist/esm/preview/index-evy8hyah.mjs +55 -0
- package/dist/esm/preview/index-gnsce796.mjs +6 -0
- package/dist/esm/preview/index-kkvzt8b7.mjs +199 -0
- package/dist/esm/preview/index-r0v18b2n.mjs +425 -0
- package/dist/esm/preview/index-rswpzmm5.mjs +926 -0
- package/dist/esm/preview/index-s9mrx750.mjs +97 -0
- package/dist/esm/preview/index-tvfexb7s.mjs +164 -0
- package/dist/esm/preview/index-vp56k1gj.mjs +215 -0
- package/dist/esm/preview/index-wxhvgv2s.mjs +79 -0
- package/dist/esm/preview/index-wy95a41r.mjs +407 -0
- package/dist/esm/preview/index-ysnwfc4t.mjs +306 -0
- package/dist/esm/preview/index.mjs +51 -0
- package/dist/esm/preview/invert.mjs +84 -0
- package/dist/esm/preview/iris-wipe.mjs +315 -0
- package/dist/esm/preview/lens-blur.mjs +563 -0
- package/dist/esm/preview/levels.mjs +400 -0
- package/dist/esm/preview/light-leak.mjs +8 -0
- package/dist/esm/preview/light-trail.mjs +516 -0
- package/dist/esm/preview/lightning.mjs +603 -0
- package/dist/esm/preview/linear-gradient-tint.mjs +6 -0
- package/dist/esm/preview/linear-gradient.mjs +6 -0
- package/dist/esm/preview/linear-progressive-blur.mjs +516 -0
- package/dist/esm/preview/linear-progressive-pixelate.mjs +176 -0
- package/dist/esm/preview/lines.mjs +536 -0
- package/dist/esm/preview/liquid-contours.mjs +512 -0
- package/dist/esm/preview/long-shadows.mjs +437 -0
- package/dist/esm/preview/lut.mjs +601 -0
- package/dist/esm/preview/magnify.mjs +403 -0
- package/dist/esm/preview/mirror.mjs +341 -0
- package/dist/esm/preview/noise-displacement.mjs +584 -0
- package/dist/esm/preview/noise.mjs +318 -0
- package/dist/esm/preview/outline.mjs +725 -0
- package/dist/esm/preview/page-turn.mjs +302 -0
- package/dist/esm/preview/paper.mjs +1249 -0
- package/dist/esm/preview/pattern.mjs +6 -0
- package/dist/esm/preview/pixel-dissolve.mjs +360 -0
- package/dist/esm/preview/pixelate.mjs +249 -0
- package/dist/esm/preview/radial-progressive-blur.mjs +582 -0
- package/dist/esm/preview/radial-progressive-pixelate.mjs +220 -0
- package/dist/esm/preview/radial-wipe.mjs +224 -0
- package/dist/esm/preview/rain-fall.mjs +114 -0
- package/dist/esm/preview/region-blur.mjs +500 -0
- package/dist/esm/preview/rings.mjs +8 -0
- package/dist/esm/preview/roughen-edges.mjs +590 -0
- package/dist/esm/preview/saturation.mjs +86 -0
- package/dist/esm/preview/scale.mjs +109 -0
- package/dist/esm/preview/scanlines.mjs +362 -0
- package/dist/esm/preview/shadows-highlights.mjs +284 -0
- package/dist/esm/preview/shatter.mjs +868 -0
- package/dist/esm/preview/shine.mjs +368 -0
- package/dist/esm/preview/shrinkwrap.mjs +769 -0
- package/dist/esm/preview/skew.mjs +300 -0
- package/dist/esm/preview/snow-fall.mjs +170 -0
- package/dist/esm/preview/speckle.mjs +356 -0
- package/dist/esm/preview/sphere.mjs +252 -0
- package/dist/esm/preview/starburst.mjs +8 -0
- package/dist/esm/preview/tear.mjs +375 -0
- package/dist/esm/preview/thermal-vision.mjs +387 -0
- package/dist/esm/preview/tile.mjs +7 -0
- package/dist/esm/preview/tint.mjs +125 -0
- package/dist/esm/preview/translate.mjs +151 -0
- package/dist/esm/preview/turbulent-displace.mjs +613 -0
- package/dist/esm/preview/tv-signal-off.mjs +308 -0
- package/dist/esm/preview/venetian-blinds.mjs +341 -0
- package/dist/esm/preview/vibrance.mjs +254 -0
- package/dist/esm/preview/vignette.mjs +458 -0
- package/dist/esm/preview/wave.mjs +384 -0
- package/dist/esm/preview/waves.mjs +599 -0
- package/dist/esm/preview/white-balance.mjs +280 -0
- package/dist/esm/preview/white-noise.mjs +244 -0
- package/dist/esm/preview/zigzag.mjs +8 -0
- package/dist/esm/preview/zoom-blur.mjs +389 -0
- package/dist/lightning/geometry.d.ts +10 -0
- package/dist/lightning/index.d.ts +4 -0
- package/dist/lightning/mask.d.ts +2 -0
- package/dist/lightning/params.d.ts +259 -0
- package/dist/lightning/shaders.d.ts +2 -0
- package/dist/lightning.d.ts +2 -0
- package/dist/magnify/shader.d.ts +1 -0
- package/dist/magnify/webgpu-shader.d.ts +1 -0
- package/dist/magnify.d.ts +28 -0
- package/package.json +30 -6
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import {
|
|
2
|
+
COLOR_SPACE_GLSL,
|
|
3
|
+
COLOR_SPACE_WGSL
|
|
4
|
+
} from "./index-6jkps947.mjs";
|
|
5
|
+
import {
|
|
6
|
+
assertOptionalFiniteNumber
|
|
7
|
+
} from "./index-wxhvgv2s.mjs";
|
|
8
|
+
import {
|
|
9
|
+
WEBGPU_SINGLE_PASS_VERTEX,
|
|
10
|
+
setupWebGpuSinglePass,
|
|
11
|
+
cleanupWebGpuSinglePass,
|
|
12
|
+
applyWebGpuSinglePass
|
|
13
|
+
} from "./index-tvfexb7s.mjs";
|
|
14
|
+
import {
|
|
15
|
+
assertEffectParamsObject
|
|
16
|
+
} from "./index-4fvp93ps.mjs";
|
|
17
|
+
|
|
18
|
+
// src/exposure.ts
|
|
19
|
+
import { Internals } from "remotion";
|
|
20
|
+
var { createEffect, createWebGL2ContextError } = Internals;
|
|
21
|
+
var DEFAULT_STOPS = 0;
|
|
22
|
+
var MIN_STOPS = -5;
|
|
23
|
+
var MAX_STOPS = 5;
|
|
24
|
+
var exposureSchema = {
|
|
25
|
+
stops: {
|
|
26
|
+
type: "number",
|
|
27
|
+
min: MIN_STOPS,
|
|
28
|
+
max: MAX_STOPS,
|
|
29
|
+
step: 0.1,
|
|
30
|
+
default: DEFAULT_STOPS,
|
|
31
|
+
description: "Stops",
|
|
32
|
+
hiddenFromList: false
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var resolve = (params) => ({
|
|
36
|
+
stops: params.stops ?? DEFAULT_STOPS
|
|
37
|
+
});
|
|
38
|
+
var validateExposureParams = (params) => {
|
|
39
|
+
assertEffectParamsObject(params, "Exposure");
|
|
40
|
+
assertOptionalFiniteNumber(params.stops, "stops");
|
|
41
|
+
const { stops } = resolve(params);
|
|
42
|
+
if (stops < MIN_STOPS) {
|
|
43
|
+
throw new TypeError(`"stops" must be >= ${MIN_STOPS}, but got ${JSON.stringify(stops)}`);
|
|
44
|
+
}
|
|
45
|
+
if (stops > MAX_STOPS) {
|
|
46
|
+
throw new TypeError(`"stops" must be <= ${MAX_STOPS}, but got ${JSON.stringify(stops)}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var VERTEX_SHADER = `#version 300 es
|
|
50
|
+
in vec2 aPos;
|
|
51
|
+
in vec2 aUv;
|
|
52
|
+
out vec2 vUv;
|
|
53
|
+
|
|
54
|
+
void main() {
|
|
55
|
+
vUv = aUv;
|
|
56
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
var FRAGMENT_SHADER = `#version 300 es
|
|
60
|
+
precision highp float;
|
|
61
|
+
|
|
62
|
+
in vec2 vUv;
|
|
63
|
+
out vec4 fragColor;
|
|
64
|
+
|
|
65
|
+
uniform sampler2D uSource;
|
|
66
|
+
uniform float uStops;
|
|
67
|
+
|
|
68
|
+
${COLOR_SPACE_GLSL}
|
|
69
|
+
|
|
70
|
+
void main() {
|
|
71
|
+
vec4 sourceColor = texture(uSource, vUv);
|
|
72
|
+
float alpha = sourceColor.a;
|
|
73
|
+
|
|
74
|
+
if (alpha <= 0.0) {
|
|
75
|
+
fragColor = vec4(0.0);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
vec3 unpremultiplied = sourceColor.rgb / alpha;
|
|
80
|
+
vec3 linear = srgbToLinear(unpremultiplied);
|
|
81
|
+
vec3 exposed = linear * exp2(uStops);
|
|
82
|
+
vec3 corrected = linearToSrgb(exposed);
|
|
83
|
+
|
|
84
|
+
fragColor = vec4(corrected * alpha, alpha);
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
var WEBGPU_SHADER = `
|
|
88
|
+
${WEBGPU_SINGLE_PASS_VERTEX}
|
|
89
|
+
struct Params {
|
|
90
|
+
stops: f32,
|
|
91
|
+
padding0: f32,
|
|
92
|
+
padding1: f32,
|
|
93
|
+
padding2: f32,
|
|
94
|
+
}
|
|
95
|
+
@group(0) @binding(0) var source: texture_2d<f32>;
|
|
96
|
+
@group(0) @binding(1) var sourceSampler: sampler;
|
|
97
|
+
@group(0) @binding(2) var<uniform> params: Params;
|
|
98
|
+
${COLOR_SPACE_WGSL}
|
|
99
|
+
|
|
100
|
+
@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
|
101
|
+
let sourceColor = textureSampleLevel(source, sourceSampler, input.uv, 0.0);
|
|
102
|
+
let alpha = sourceColor.a;
|
|
103
|
+
if (alpha <= 0.0) {
|
|
104
|
+
return vec4f(0.0);
|
|
105
|
+
}
|
|
106
|
+
let linear = srgbToLinear(sourceColor.rgb / alpha);
|
|
107
|
+
let exposed = linear * exp2(params.stops);
|
|
108
|
+
let corrected = linearToSrgb(exposed);
|
|
109
|
+
return vec4f(corrected * alpha, alpha);
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
var compileShader = (gl, type, source) => {
|
|
113
|
+
const shader = gl.createShader(type);
|
|
114
|
+
if (!shader) {
|
|
115
|
+
throw new Error("Failed to create exposure shader");
|
|
116
|
+
}
|
|
117
|
+
gl.shaderSource(shader, source);
|
|
118
|
+
gl.compileShader(shader);
|
|
119
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
120
|
+
const log = gl.getShaderInfoLog(shader);
|
|
121
|
+
gl.deleteShader(shader);
|
|
122
|
+
throw new Error(`Exposure shader compile failed: ${log ?? "(no log)"}`);
|
|
123
|
+
}
|
|
124
|
+
return shader;
|
|
125
|
+
};
|
|
126
|
+
var createProgram = (gl) => {
|
|
127
|
+
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
|
|
128
|
+
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
|
|
129
|
+
const program = gl.createProgram();
|
|
130
|
+
if (!program) {
|
|
131
|
+
throw new Error("Failed to create exposure shader program");
|
|
132
|
+
}
|
|
133
|
+
gl.attachShader(program, vertexShader);
|
|
134
|
+
gl.attachShader(program, fragmentShader);
|
|
135
|
+
gl.linkProgram(program);
|
|
136
|
+
gl.deleteShader(vertexShader);
|
|
137
|
+
gl.deleteShader(fragmentShader);
|
|
138
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
139
|
+
const log = gl.getProgramInfoLog(program);
|
|
140
|
+
gl.deleteProgram(program);
|
|
141
|
+
throw new Error(`Exposure shader link failed: ${log ?? "(no log)"}`);
|
|
142
|
+
}
|
|
143
|
+
return program;
|
|
144
|
+
};
|
|
145
|
+
var createTexture = (gl) => {
|
|
146
|
+
const texture = gl.createTexture();
|
|
147
|
+
if (!texture) {
|
|
148
|
+
throw new Error("Failed to create exposure texture");
|
|
149
|
+
}
|
|
150
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
151
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
152
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
153
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
154
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
155
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
156
|
+
return texture;
|
|
157
|
+
};
|
|
158
|
+
var setupExposure = (target) => {
|
|
159
|
+
const gl = target.getContext("webgl2", {
|
|
160
|
+
premultipliedAlpha: true,
|
|
161
|
+
alpha: true,
|
|
162
|
+
preserveDrawingBuffer: true
|
|
163
|
+
});
|
|
164
|
+
if (!gl) {
|
|
165
|
+
throw createWebGL2ContextError("exposure effect");
|
|
166
|
+
}
|
|
167
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
168
|
+
const program = createProgram(gl);
|
|
169
|
+
const vao = gl.createVertexArray();
|
|
170
|
+
if (!vao) {
|
|
171
|
+
throw new Error("Failed to create exposure vertex array");
|
|
172
|
+
}
|
|
173
|
+
const vbo = gl.createBuffer();
|
|
174
|
+
if (!vbo) {
|
|
175
|
+
throw new Error("Failed to create exposure vertex buffer");
|
|
176
|
+
}
|
|
177
|
+
gl.bindVertexArray(vao);
|
|
178
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
179
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
180
|
+
const aPos = gl.getAttribLocation(program, "aPos");
|
|
181
|
+
const aUv = gl.getAttribLocation(program, "aUv");
|
|
182
|
+
gl.enableVertexAttribArray(aPos);
|
|
183
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
|
|
184
|
+
gl.enableVertexAttribArray(aUv);
|
|
185
|
+
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
|
|
186
|
+
gl.bindVertexArray(null);
|
|
187
|
+
return {
|
|
188
|
+
gl,
|
|
189
|
+
program,
|
|
190
|
+
vao,
|
|
191
|
+
vbo,
|
|
192
|
+
textureSource: createTexture(gl),
|
|
193
|
+
uniforms: {
|
|
194
|
+
uSource: gl.getUniformLocation(program, "uSource"),
|
|
195
|
+
uStops: gl.getUniformLocation(program, "uStops")
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
var exposure = createEffect({
|
|
200
|
+
type: "remotion/exposure",
|
|
201
|
+
label: "exposure()",
|
|
202
|
+
documentationLink: "https://www.remotion.dev/docs/effects/exposure",
|
|
203
|
+
calculateKey: (params) => {
|
|
204
|
+
const { stops } = resolve(params);
|
|
205
|
+
return `exposure-${stops}`;
|
|
206
|
+
},
|
|
207
|
+
implementations: {
|
|
208
|
+
webgpu: Internals.createEffectImplementation({
|
|
209
|
+
setup: (target) => setupWebGpuSinglePass(target, "exposure"),
|
|
210
|
+
apply: ({ source, width, height, params, state, gpuDevice }) => {
|
|
211
|
+
if (!gpuDevice) {
|
|
212
|
+
throw new Error("A WebGPU device is required for the exposure effect");
|
|
213
|
+
}
|
|
214
|
+
const r = resolve(params);
|
|
215
|
+
applyWebGpuSinglePass({
|
|
216
|
+
state,
|
|
217
|
+
source,
|
|
218
|
+
width,
|
|
219
|
+
height,
|
|
220
|
+
device: gpuDevice,
|
|
221
|
+
shader: WEBGPU_SHADER,
|
|
222
|
+
uniformData: new Float32Array([r.stops, 0, 0, 0])
|
|
223
|
+
});
|
|
224
|
+
},
|
|
225
|
+
cleanup: cleanupWebGpuSinglePass
|
|
226
|
+
}),
|
|
227
|
+
webgl2: Internals.createEffectImplementation({
|
|
228
|
+
setup: setupExposure,
|
|
229
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
230
|
+
const { stops } = resolve(params);
|
|
231
|
+
const { gl, program, textureSource, uniforms, vao } = state;
|
|
232
|
+
gl.viewport(0, 0, width, height);
|
|
233
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
234
|
+
gl.clearColor(0, 0, 0, 0);
|
|
235
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
236
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
237
|
+
gl.bindTexture(gl.TEXTURE_2D, textureSource);
|
|
238
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
239
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
240
|
+
gl.useProgram(program);
|
|
241
|
+
if (uniforms.uSource)
|
|
242
|
+
gl.uniform1i(uniforms.uSource, 0);
|
|
243
|
+
if (uniforms.uStops)
|
|
244
|
+
gl.uniform1f(uniforms.uStops, stops);
|
|
245
|
+
gl.bindVertexArray(vao);
|
|
246
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
247
|
+
gl.bindVertexArray(null);
|
|
248
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
249
|
+
gl.useProgram(null);
|
|
250
|
+
},
|
|
251
|
+
cleanup: ({ gl, program, vao, vbo, textureSource }) => {
|
|
252
|
+
gl.deleteTexture(textureSource);
|
|
253
|
+
gl.deleteBuffer(vbo);
|
|
254
|
+
gl.deleteProgram(program);
|
|
255
|
+
gl.deleteVertexArray(vao);
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
},
|
|
259
|
+
schema: exposureSchema,
|
|
260
|
+
validateParams: validateExposureParams
|
|
261
|
+
});
|
|
262
|
+
export {
|
|
263
|
+
exposure
|
|
264
|
+
};
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import {
|
|
2
|
+
setupSinglePass,
|
|
3
|
+
prepareSinglePassSource,
|
|
4
|
+
drawSinglePass,
|
|
5
|
+
cleanupSinglePass
|
|
6
|
+
} from "./index-8p04sssx.mjs";
|
|
7
|
+
import {
|
|
8
|
+
assertOptionalFiniteNumber,
|
|
9
|
+
validateUnitInterval
|
|
10
|
+
} from "./index-wxhvgv2s.mjs";
|
|
11
|
+
import {
|
|
12
|
+
WEBGPU_SINGLE_PASS_VERTEX,
|
|
13
|
+
setupWebGpuSinglePass,
|
|
14
|
+
cleanupWebGpuSinglePass,
|
|
15
|
+
applyWebGpuSinglePass
|
|
16
|
+
} from "./index-tvfexb7s.mjs";
|
|
17
|
+
import {
|
|
18
|
+
assertEffectParamsObject,
|
|
19
|
+
assertRequiredFiniteNumber
|
|
20
|
+
} from "./index-4fvp93ps.mjs";
|
|
21
|
+
|
|
22
|
+
// src/film-burn.ts
|
|
23
|
+
import { Internals } from "remotion";
|
|
24
|
+
|
|
25
|
+
// src/film-burn-webgpu-shader.ts
|
|
26
|
+
var FILM_BURN_WEBGPU_SHADER = `
|
|
27
|
+
${WEBGPU_SINGLE_PASS_VERTEX}
|
|
28
|
+
@group(0) @binding(0) var source: texture_2d<f32>;
|
|
29
|
+
@group(0) @binding(1) var sourceSampler: sampler;
|
|
30
|
+
@group(0) @binding(2) var<uniform> params: Params;
|
|
31
|
+
|
|
32
|
+
struct Params { size: vec2f, progress: f32, seed: u32, center: vec2f, }
|
|
33
|
+
fn lattice(point: vec3i, seed: u32) -> f32 {
|
|
34
|
+
let p = bitcast<vec3u>(point);
|
|
35
|
+
var h = (p.x * 0x27d4eb2du) ^ (p.y * 0x165667b1u) ^ (p.z * 0x9e3779b9u) ^ (seed * 0x85ebca6bu);
|
|
36
|
+
h ^= h >> 15u; h *= 0x2c1b3c6du; h ^= h >> 12u; h *= 0x297a2d39u; h ^= h >> 15u;
|
|
37
|
+
return f32(h & 65535u) / 65535.0;
|
|
38
|
+
}
|
|
39
|
+
fn valueNoise(point: vec3f, seed: u32) -> f32 {
|
|
40
|
+
let cell = vec3i(floor(point));
|
|
41
|
+
let t = fract(point);
|
|
42
|
+
let fade = t * t * t * (t * (t * 6.0 - vec3f(15.0)) + vec3f(10.0));
|
|
43
|
+
let lower = mix(mix(lattice(cell,seed),lattice(cell+vec3i(1,0,0),seed),fade.x),mix(lattice(cell+vec3i(0,1,0),seed),lattice(cell+vec3i(1,1,0),seed),fade.x),fade.y);
|
|
44
|
+
let upper = mix(mix(lattice(cell+vec3i(0,0,1),seed),lattice(cell+vec3i(1,0,1),seed),fade.x),mix(lattice(cell+vec3i(0,1,1),seed),lattice(cell+vec3i(1,1,1),seed),fade.x),fade.y);
|
|
45
|
+
return mix(lower,upper,fade.z);
|
|
46
|
+
}
|
|
47
|
+
@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
|
48
|
+
let color = textureSampleLevel(source,sourceSampler,input.uv,0);
|
|
49
|
+
if (params.progress <= 0.0 || color.a == 0.0) { return color; }
|
|
50
|
+
if (params.progress >= 1.0) { return vec4f(0); }
|
|
51
|
+
let pixel = input.uv * params.size;
|
|
52
|
+
let distanceFromCenter = length(pixel-params.center*params.size)/max(length(params.size),1.0);
|
|
53
|
+
var noise = 0.0; var amplitude = 1.0; var frequency = 1.0;
|
|
54
|
+
for(var octave=0;octave<4;octave++) {
|
|
55
|
+
noise += valueNoise(vec3f(pixel/60.0*frequency,f32(octave)*7.31),params.seed+17u+u32(octave))*amplitude;
|
|
56
|
+
amplitude *= 0.5; frequency *= 2.0;
|
|
57
|
+
}
|
|
58
|
+
noise /= 1.875;
|
|
59
|
+
let field = noise*0.65+(1.0-min(distanceFromCenter,1.0))*0.35;
|
|
60
|
+
let threshold = 1.0-params.progress*1.25;
|
|
61
|
+
let band = 0.12*min(params.progress*10.0,1.0);
|
|
62
|
+
if(field>threshold+band) { return vec4f(0); }
|
|
63
|
+
if(field<=threshold-band*2.0) { return color; }
|
|
64
|
+
let scorch = smoothstep(threshold-band*2.0,threshold,field);
|
|
65
|
+
let hot = smoothstep(threshold,threshold+band,field);
|
|
66
|
+
var rgb = color.rgb/color.a*(1.0-scorch*0.85);
|
|
67
|
+
rgb = vec3f(rgb.r+(1.0-rgb.r)*hot*0.9,rgb.g+(0.45-rgb.g)*hot*0.9,rgb.b*(1.0-hot));
|
|
68
|
+
let alpha = color.a*(1.0-hot*0.6);
|
|
69
|
+
return vec4f(rgb*alpha,alpha);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
// src/film-burn.ts
|
|
75
|
+
var { createEffect } = Internals;
|
|
76
|
+
var DEFAULT_PROGRESS = 0;
|
|
77
|
+
var DEFAULT_CENTER = [0.5, 0.5];
|
|
78
|
+
var DEFAULT_SEED = 0;
|
|
79
|
+
var filmBurnSchema = {
|
|
80
|
+
progress: {
|
|
81
|
+
type: "number",
|
|
82
|
+
min: 0,
|
|
83
|
+
max: 1,
|
|
84
|
+
step: 0.01,
|
|
85
|
+
default: DEFAULT_PROGRESS,
|
|
86
|
+
description: "Progress",
|
|
87
|
+
hiddenFromList: false
|
|
88
|
+
},
|
|
89
|
+
center: {
|
|
90
|
+
type: "uv-coordinate",
|
|
91
|
+
min: 0,
|
|
92
|
+
max: 1,
|
|
93
|
+
step: 0.01,
|
|
94
|
+
default: DEFAULT_CENTER,
|
|
95
|
+
description: "Center"
|
|
96
|
+
},
|
|
97
|
+
seed: {
|
|
98
|
+
type: "number",
|
|
99
|
+
min: 0,
|
|
100
|
+
max: 4294967295,
|
|
101
|
+
step: 1,
|
|
102
|
+
integer: true,
|
|
103
|
+
default: DEFAULT_SEED,
|
|
104
|
+
description: "Seed",
|
|
105
|
+
hiddenFromList: false
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var resolve = (params) => ({
|
|
109
|
+
progress: params.progress ?? DEFAULT_PROGRESS,
|
|
110
|
+
center: params.center ?? DEFAULT_CENTER,
|
|
111
|
+
seed: params.seed ?? DEFAULT_SEED
|
|
112
|
+
});
|
|
113
|
+
var validateFilmBurnParams = (params) => {
|
|
114
|
+
assertEffectParamsObject(params, "Film burn");
|
|
115
|
+
assertOptionalFiniteNumber(params.progress, "progress");
|
|
116
|
+
assertOptionalFiniteNumber(params.seed, "seed");
|
|
117
|
+
if (params.center !== undefined) {
|
|
118
|
+
if (!Array.isArray(params.center) || params.center.length !== 2) {
|
|
119
|
+
throw new TypeError('"center" must be a [number, number] tuple');
|
|
120
|
+
}
|
|
121
|
+
assertRequiredFiniteNumber(params.center[0], "center[0]");
|
|
122
|
+
assertRequiredFiniteNumber(params.center[1], "center[1]");
|
|
123
|
+
validateUnitInterval(params.center[0], "center[0]");
|
|
124
|
+
validateUnitInterval(params.center[1], "center[1]");
|
|
125
|
+
}
|
|
126
|
+
const r = resolve(params);
|
|
127
|
+
validateUnitInterval(r.progress, "progress");
|
|
128
|
+
if (!Number.isInteger(r.seed) || r.seed < 0 || r.seed > 4294967295) {
|
|
129
|
+
throw new TypeError('"seed" must be an unsigned 32-bit integer');
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
var FRAGMENT_SHADER = `#version 300 es
|
|
133
|
+
precision highp float;
|
|
134
|
+
precision highp int;
|
|
135
|
+
|
|
136
|
+
in vec2 vUv;
|
|
137
|
+
out vec4 fragColor;
|
|
138
|
+
|
|
139
|
+
uniform sampler2D uSource;
|
|
140
|
+
uniform vec2 uResolution;
|
|
141
|
+
uniform float uProgress;
|
|
142
|
+
uniform vec2 uCenter;
|
|
143
|
+
uniform uint uSeed;
|
|
144
|
+
|
|
145
|
+
float lattice(ivec3 point, uint seed) {
|
|
146
|
+
uvec3 p = uvec3(point);
|
|
147
|
+
uint h = p.x * 0x27d4eb2du ^ p.y * 0x165667b1u
|
|
148
|
+
^ p.z * 0x9e3779b9u ^ seed * 0x85ebca6bu;
|
|
149
|
+
h ^= h >> 15;
|
|
150
|
+
h *= 0x2c1b3c6du;
|
|
151
|
+
h ^= h >> 12;
|
|
152
|
+
h *= 0x297a2d39u;
|
|
153
|
+
h ^= h >> 15;
|
|
154
|
+
return float(h & 65535u) / 65535.0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
float valueNoise(vec3 point, uint seed) {
|
|
158
|
+
ivec3 cell = ivec3(floor(point));
|
|
159
|
+
vec3 t = fract(point);
|
|
160
|
+
vec3 fade = t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
|
|
161
|
+
float lower = mix(
|
|
162
|
+
mix(lattice(cell, seed), lattice(cell + ivec3(1, 0, 0), seed), fade.x),
|
|
163
|
+
mix(lattice(cell + ivec3(0, 1, 0), seed), lattice(cell + ivec3(1, 1, 0), seed), fade.x),
|
|
164
|
+
fade.y
|
|
165
|
+
);
|
|
166
|
+
float upper = mix(
|
|
167
|
+
mix(lattice(cell + ivec3(0, 0, 1), seed), lattice(cell + ivec3(1, 0, 1), seed), fade.x),
|
|
168
|
+
mix(lattice(cell + ivec3(0, 1, 1), seed), lattice(cell + ivec3(1, 1, 1), seed), fade.x),
|
|
169
|
+
fade.y
|
|
170
|
+
);
|
|
171
|
+
return mix(lower, upper, fade.z);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
void main() {
|
|
175
|
+
vec4 source = texture(uSource, vUv);
|
|
176
|
+
if (uProgress <= 0.0 || source.a == 0.0) {
|
|
177
|
+
fragColor = source;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (uProgress >= 1.0) {
|
|
181
|
+
fragColor = vec4(0.0);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
vec2 pixel = vec2(vUv.x, 1.0 - vUv.y) * uResolution;
|
|
186
|
+
float distanceFromCenter = length(pixel - uCenter * uResolution)
|
|
187
|
+
/ max(length(uResolution), 1.0);
|
|
188
|
+
float noise = 0.0;
|
|
189
|
+
float amplitude = 1.0;
|
|
190
|
+
float frequency = 1.0;
|
|
191
|
+
for (int octave = 0; octave < 4; octave++) {
|
|
192
|
+
noise += valueNoise(
|
|
193
|
+
vec3(pixel / 60.0 * frequency, float(octave) * 7.31),
|
|
194
|
+
uSeed + 17u + uint(octave)
|
|
195
|
+
) * amplitude;
|
|
196
|
+
amplitude *= 0.5;
|
|
197
|
+
frequency *= 2.0;
|
|
198
|
+
}
|
|
199
|
+
noise /= 1.875;
|
|
200
|
+
float field = noise * 0.65 + (1.0 - min(distanceFromCenter, 1.0)) * 0.35;
|
|
201
|
+
float threshold = 1.0 - uProgress * 1.25;
|
|
202
|
+
float band = 0.12 * min(uProgress * 10.0, 1.0);
|
|
203
|
+
if (field > threshold + band) {
|
|
204
|
+
fragColor = vec4(0.0);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (field <= threshold - band * 2.0) {
|
|
208
|
+
fragColor = source;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
float scorch = smoothstep(threshold - band * 2.0, threshold, field);
|
|
213
|
+
float hot = smoothstep(threshold, threshold + band, field);
|
|
214
|
+
vec3 color = source.rgb / source.a * (1.0 - scorch * 0.85);
|
|
215
|
+
color = vec3(
|
|
216
|
+
color.r + (1.0 - color.r) * hot * 0.9,
|
|
217
|
+
color.g + (0.45 - color.g) * hot * 0.9,
|
|
218
|
+
color.b * (1.0 - hot)
|
|
219
|
+
);
|
|
220
|
+
float alpha = source.a * (1.0 - hot * 0.6);
|
|
221
|
+
fragColor = vec4(color * alpha, alpha);
|
|
222
|
+
}
|
|
223
|
+
`;
|
|
224
|
+
var filmBurn = createEffect({
|
|
225
|
+
type: "remotion/film-burn",
|
|
226
|
+
label: "filmBurn()",
|
|
227
|
+
documentationLink: "https://www.remotion.dev/docs/effects/film-burn",
|
|
228
|
+
calculateKey: (params) => {
|
|
229
|
+
const r = resolve(params);
|
|
230
|
+
return `film-burn-${r.progress}-${r.center.join(":")}-${r.seed}`;
|
|
231
|
+
},
|
|
232
|
+
implementations: {
|
|
233
|
+
webgpu: Internals.createEffectImplementation({
|
|
234
|
+
setup: (target) => setupWebGpuSinglePass(target, "film-burn"),
|
|
235
|
+
apply: ({ source, width, height, params, state, gpuDevice }) => {
|
|
236
|
+
if (!gpuDevice)
|
|
237
|
+
throw new Error("A WebGPU device is required for the film-burn effect");
|
|
238
|
+
const r = resolve(params);
|
|
239
|
+
const uniformData = new Float32Array([
|
|
240
|
+
width,
|
|
241
|
+
height,
|
|
242
|
+
r.progress,
|
|
243
|
+
0,
|
|
244
|
+
r.center[0],
|
|
245
|
+
r.center[1],
|
|
246
|
+
0,
|
|
247
|
+
0
|
|
248
|
+
]);
|
|
249
|
+
new Uint32Array(uniformData.buffer)[3] = r.seed;
|
|
250
|
+
applyWebGpuSinglePass({
|
|
251
|
+
state,
|
|
252
|
+
source,
|
|
253
|
+
width,
|
|
254
|
+
height,
|
|
255
|
+
device: gpuDevice,
|
|
256
|
+
shader: FILM_BURN_WEBGPU_SHADER,
|
|
257
|
+
uniformData
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
cleanup: cleanupWebGpuSinglePass
|
|
261
|
+
}),
|
|
262
|
+
webgl2: Internals.createEffectImplementation({
|
|
263
|
+
setup: (target) => setupSinglePass(target, FRAGMENT_SHADER, "film burn", [
|
|
264
|
+
"uResolution",
|
|
265
|
+
"uProgress",
|
|
266
|
+
"uCenter",
|
|
267
|
+
"uSeed"
|
|
268
|
+
]),
|
|
269
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
270
|
+
const r = resolve(params);
|
|
271
|
+
const { gl, uniforms } = state;
|
|
272
|
+
prepareSinglePassSource({
|
|
273
|
+
state,
|
|
274
|
+
source,
|
|
275
|
+
width,
|
|
276
|
+
height,
|
|
277
|
+
flipSourceY
|
|
278
|
+
});
|
|
279
|
+
if (uniforms.uResolution)
|
|
280
|
+
gl.uniform2f(uniforms.uResolution, width, height);
|
|
281
|
+
if (uniforms.uProgress)
|
|
282
|
+
gl.uniform1f(uniforms.uProgress, r.progress);
|
|
283
|
+
if (uniforms.uCenter)
|
|
284
|
+
gl.uniform2f(uniforms.uCenter, r.center[0], r.center[1]);
|
|
285
|
+
if (uniforms.uSeed)
|
|
286
|
+
gl.uniform1ui(uniforms.uSeed, r.seed);
|
|
287
|
+
drawSinglePass(state);
|
|
288
|
+
},
|
|
289
|
+
cleanup: cleanupSinglePass
|
|
290
|
+
})
|
|
291
|
+
},
|
|
292
|
+
schema: filmBurnSchema,
|
|
293
|
+
validateParams: validateFilmBurnParams
|
|
294
|
+
});
|
|
295
|
+
export {
|
|
296
|
+
filmBurn,
|
|
297
|
+
filmBurnSchema
|
|
298
|
+
};
|