@remotion/effects 4.0.506 → 4.0.508
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/exposure.mjs +318 -0
- package/dist/esm/levels.mjs +347 -0
- package/dist/esm/region-blur.mjs +554 -0
- package/dist/esm/shadows-highlights.mjs +337 -0
- package/dist/esm/vibrance.mjs +314 -0
- package/dist/esm/white-balance.mjs +333 -0
- package/dist/exposure.d.ts +7 -0
- package/dist/levels.d.ts +11 -0
- package/dist/region-blur/index.d.ts +61 -0
- package/dist/region-blur/region-blur-runtime.d.ts +44 -0
- package/dist/region-blur.d.ts +1 -0
- package/dist/shadows-highlights.d.ts +9 -0
- package/dist/vibrance.d.ts +7 -0
- package/dist/white-balance.d.ts +9 -0
- package/package.json +51 -3
- package/dist/effect-internals.d.ts +0 -8
- package/dist/entrypoints/blur.d.ts +0 -6
- package/dist/esm/page-turn.mjs +0 -521
- package/dist/page-turn.d.ts +0 -91
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
// src/region-blur/index.ts
|
|
2
|
+
import { Internals as Internals2 } 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/region-blur/region-blur-runtime.ts
|
|
110
|
+
import { Internals } from "remotion";
|
|
111
|
+
|
|
112
|
+
// src/gaussian-blur-shader.ts
|
|
113
|
+
var buildGaussianBlurFs = (direction) => {
|
|
114
|
+
const dirVec = direction === "horizontal" ? "vec2(1.0, 0.0)" : "vec2(0.0, 1.0)";
|
|
115
|
+
return `#version 300 es
|
|
116
|
+
precision highp float;
|
|
117
|
+
|
|
118
|
+
in vec2 vUv;
|
|
119
|
+
out vec4 fragColor;
|
|
120
|
+
|
|
121
|
+
uniform sampler2D uSource;
|
|
122
|
+
uniform float uRadius;
|
|
123
|
+
uniform vec2 uTexelSize;
|
|
124
|
+
|
|
125
|
+
const int MIN_KERNEL_HALF = 4;
|
|
126
|
+
const int MAX_KERNEL_HALF = 32;
|
|
127
|
+
const float TARGET_SAMPLE_DISTANCE_PX = 2.0;
|
|
128
|
+
const vec2 DIRECTION = ${dirVec};
|
|
129
|
+
|
|
130
|
+
void main() {
|
|
131
|
+
if (uRadius <= 0.0) {
|
|
132
|
+
fragColor = texture(uSource, vUv);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
int kernelHalf = int(
|
|
137
|
+
min(
|
|
138
|
+
float(MAX_KERNEL_HALF),
|
|
139
|
+
max(float(MIN_KERNEL_HALF), ceil(uRadius / TARGET_SAMPLE_DISTANCE_PX))
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
float pixelStride = uRadius / float(kernelHalf);
|
|
143
|
+
float sigma = uRadius / 3.0;
|
|
144
|
+
float twoSigmaSq = 2.0 * sigma * sigma;
|
|
145
|
+
|
|
146
|
+
vec4 sum = vec4(0.0);
|
|
147
|
+
float weightSum = 0.0;
|
|
148
|
+
|
|
149
|
+
for (int i = -MAX_KERNEL_HALF; i <= MAX_KERNEL_HALF; ++i) {
|
|
150
|
+
if (abs(i) > kernelHalf) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
float offsetPx = float(i) * pixelStride;
|
|
155
|
+
float w = exp(-(offsetPx * offsetPx) / twoSigmaSq);
|
|
156
|
+
vec2 uv = vUv + DIRECTION * uTexelSize * offsetPx;
|
|
157
|
+
sum += texture(uSource, uv) * w;
|
|
158
|
+
weightSum += w;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
fragColor = sum / weightSum;
|
|
162
|
+
}
|
|
163
|
+
`;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// src/blur/blur-shaders.ts
|
|
167
|
+
var BLUR_VS = `#version 300 es
|
|
168
|
+
layout(location = 0) in vec2 aPos;
|
|
169
|
+
layout(location = 1) in vec2 aUv;
|
|
170
|
+
out vec2 vUv;
|
|
171
|
+
void main() {
|
|
172
|
+
vUv = aUv;
|
|
173
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
var BLUR_FS_HORIZONTAL = buildGaussianBlurFs("horizontal");
|
|
177
|
+
var BLUR_FS_VERTICAL = buildGaussianBlurFs("vertical");
|
|
178
|
+
|
|
179
|
+
// src/uv-coordinate.ts
|
|
180
|
+
var publicUvToShaderUv = (uv) => {
|
|
181
|
+
return [uv[0], 1 - uv[1]];
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/region-blur/region-blur-runtime.ts
|
|
185
|
+
var { createWebGL2ContextError } = Internals;
|
|
186
|
+
var COMPOSITE_FRAGMENT_SHADER = `#version 300 es
|
|
187
|
+
precision highp float;
|
|
188
|
+
|
|
189
|
+
in vec2 vUv;
|
|
190
|
+
out vec4 fragColor;
|
|
191
|
+
|
|
192
|
+
uniform sampler2D uSource;
|
|
193
|
+
uniform sampler2D uBlurred;
|
|
194
|
+
uniform vec2 uResolution;
|
|
195
|
+
uniform vec2 uTopLeft;
|
|
196
|
+
uniform vec2 uBottomRight;
|
|
197
|
+
uniform float uFeather;
|
|
198
|
+
uniform float uRoundness;
|
|
199
|
+
|
|
200
|
+
float roundedBoxDistance(vec2 point, vec2 center, vec2 halfSize, float radius) {
|
|
201
|
+
vec2 offset = abs(point - center) - halfSize + vec2(radius);
|
|
202
|
+
return length(max(offset, vec2(0.0))) + min(max(offset.x, offset.y), 0.0) - radius;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
void main() {
|
|
206
|
+
vec2 minimum = vec2(uTopLeft.x, uBottomRight.y) * uResolution;
|
|
207
|
+
vec2 maximum = vec2(uBottomRight.x, uTopLeft.y) * uResolution;
|
|
208
|
+
vec2 halfSize = (maximum - minimum) * 0.5;
|
|
209
|
+
vec2 center = (minimum + maximum) * 0.5;
|
|
210
|
+
float cornerRadius = min(halfSize.x, halfSize.y) * uRoundness;
|
|
211
|
+
float distanceToRegion = roundedBoxDistance(
|
|
212
|
+
vUv * uResolution,
|
|
213
|
+
center,
|
|
214
|
+
halfSize,
|
|
215
|
+
cornerRadius
|
|
216
|
+
);
|
|
217
|
+
float mask = uFeather <= 0.0
|
|
218
|
+
? (distanceToRegion <= 0.0 ? 1.0 : 0.0)
|
|
219
|
+
: 1.0 - smoothstep(-uFeather * 0.5, uFeather * 0.5, distanceToRegion);
|
|
220
|
+
|
|
221
|
+
fragColor = mix(texture(uSource, vUv), texture(uBlurred, vUv), mask);
|
|
222
|
+
}
|
|
223
|
+
`;
|
|
224
|
+
var compileShader = (gl, type, source) => {
|
|
225
|
+
const shader = gl.createShader(type);
|
|
226
|
+
if (!shader) {
|
|
227
|
+
throw new Error("Failed to create WebGL shader");
|
|
228
|
+
}
|
|
229
|
+
gl.shaderSource(shader, source);
|
|
230
|
+
gl.compileShader(shader);
|
|
231
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
232
|
+
const log = gl.getShaderInfoLog(shader);
|
|
233
|
+
gl.deleteShader(shader);
|
|
234
|
+
throw new Error(`Shader compile failed: ${log ?? "(no log)"}`);
|
|
235
|
+
}
|
|
236
|
+
return shader;
|
|
237
|
+
};
|
|
238
|
+
var createProgram = (gl, vertexSource, fragmentSource) => {
|
|
239
|
+
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
|
|
240
|
+
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
|
|
241
|
+
const program = gl.createProgram();
|
|
242
|
+
if (!program) {
|
|
243
|
+
throw new Error("Failed to create WebGL program");
|
|
244
|
+
}
|
|
245
|
+
gl.attachShader(program, vertexShader);
|
|
246
|
+
gl.attachShader(program, fragmentShader);
|
|
247
|
+
gl.linkProgram(program);
|
|
248
|
+
gl.deleteShader(vertexShader);
|
|
249
|
+
gl.deleteShader(fragmentShader);
|
|
250
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
251
|
+
const log = gl.getProgramInfoLog(program);
|
|
252
|
+
gl.deleteProgram(program);
|
|
253
|
+
throw new Error(`Program link failed: ${log ?? "(no log)"}`);
|
|
254
|
+
}
|
|
255
|
+
return program;
|
|
256
|
+
};
|
|
257
|
+
var createTexture = (gl) => {
|
|
258
|
+
const texture = gl.createTexture();
|
|
259
|
+
if (!texture) {
|
|
260
|
+
throw new Error("Failed to create WebGL texture");
|
|
261
|
+
}
|
|
262
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
263
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
264
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
265
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
266
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
267
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
268
|
+
return texture;
|
|
269
|
+
};
|
|
270
|
+
var getBlurUniforms = (gl, program) => ({
|
|
271
|
+
source: gl.getUniformLocation(program, "uSource"),
|
|
272
|
+
radius: gl.getUniformLocation(program, "uRadius"),
|
|
273
|
+
texelSize: gl.getUniformLocation(program, "uTexelSize")
|
|
274
|
+
});
|
|
275
|
+
var setupRegionBlur = (target) => {
|
|
276
|
+
const gl = target.getContext("webgl2", {
|
|
277
|
+
premultipliedAlpha: true,
|
|
278
|
+
alpha: true,
|
|
279
|
+
preserveDrawingBuffer: true
|
|
280
|
+
});
|
|
281
|
+
if (!gl) {
|
|
282
|
+
throw createWebGL2ContextError("region blur effect");
|
|
283
|
+
}
|
|
284
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
285
|
+
const horizontalProgram = createProgram(gl, BLUR_VS, BLUR_FS_HORIZONTAL);
|
|
286
|
+
const verticalProgram = createProgram(gl, BLUR_VS, BLUR_FS_VERTICAL);
|
|
287
|
+
const compositeProgram = createProgram(gl, BLUR_VS, COMPOSITE_FRAGMENT_SHADER);
|
|
288
|
+
const vao = gl.createVertexArray();
|
|
289
|
+
const vbo = gl.createBuffer();
|
|
290
|
+
const framebuffer = gl.createFramebuffer();
|
|
291
|
+
if (!vao || !vbo || !framebuffer) {
|
|
292
|
+
throw new Error("Failed to create region blur WebGL resources");
|
|
293
|
+
}
|
|
294
|
+
gl.bindVertexArray(vao);
|
|
295
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
296
|
+
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);
|
|
297
|
+
gl.enableVertexAttribArray(0);
|
|
298
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 16, 0);
|
|
299
|
+
gl.enableVertexAttribArray(1);
|
|
300
|
+
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 16, 8);
|
|
301
|
+
gl.bindVertexArray(null);
|
|
302
|
+
return {
|
|
303
|
+
gl,
|
|
304
|
+
horizontalProgram,
|
|
305
|
+
verticalProgram,
|
|
306
|
+
compositeProgram,
|
|
307
|
+
vao,
|
|
308
|
+
vbo,
|
|
309
|
+
sourceTexture: createTexture(gl),
|
|
310
|
+
horizontalTexture: createTexture(gl),
|
|
311
|
+
blurredTexture: createTexture(gl),
|
|
312
|
+
framebuffer,
|
|
313
|
+
horizontalUniforms: getBlurUniforms(gl, horizontalProgram),
|
|
314
|
+
verticalUniforms: getBlurUniforms(gl, verticalProgram),
|
|
315
|
+
compositeUniforms: {
|
|
316
|
+
source: gl.getUniformLocation(compositeProgram, "uSource"),
|
|
317
|
+
blurred: gl.getUniformLocation(compositeProgram, "uBlurred"),
|
|
318
|
+
resolution: gl.getUniformLocation(compositeProgram, "uResolution"),
|
|
319
|
+
topLeft: gl.getUniformLocation(compositeProgram, "uTopLeft"),
|
|
320
|
+
bottomRight: gl.getUniformLocation(compositeProgram, "uBottomRight"),
|
|
321
|
+
feather: gl.getUniformLocation(compositeProgram, "uFeather"),
|
|
322
|
+
roundness: gl.getUniformLocation(compositeProgram, "uRoundness")
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
var draw = (state) => {
|
|
327
|
+
state.gl.bindVertexArray(state.vao);
|
|
328
|
+
state.gl.drawArrays(state.gl.TRIANGLE_STRIP, 0, 4);
|
|
329
|
+
state.gl.bindVertexArray(null);
|
|
330
|
+
};
|
|
331
|
+
var allocateTexture = (gl, texture, width, height) => {
|
|
332
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
333
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
334
|
+
};
|
|
335
|
+
var renderBlurPass = ({
|
|
336
|
+
state,
|
|
337
|
+
program,
|
|
338
|
+
uniforms,
|
|
339
|
+
input,
|
|
340
|
+
output,
|
|
341
|
+
width,
|
|
342
|
+
height,
|
|
343
|
+
radius
|
|
344
|
+
}) => {
|
|
345
|
+
const { gl } = state;
|
|
346
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, state.framebuffer);
|
|
347
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, output, 0);
|
|
348
|
+
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
|
|
349
|
+
throw new Error("Region blur framebuffer is incomplete");
|
|
350
|
+
}
|
|
351
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
352
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
353
|
+
gl.bindTexture(gl.TEXTURE_2D, input);
|
|
354
|
+
gl.useProgram(program);
|
|
355
|
+
if (uniforms.source)
|
|
356
|
+
gl.uniform1i(uniforms.source, 0);
|
|
357
|
+
if (uniforms.radius)
|
|
358
|
+
gl.uniform1f(uniforms.radius, radius);
|
|
359
|
+
if (uniforms.texelSize) {
|
|
360
|
+
gl.uniform2f(uniforms.texelSize, 1 / width, 1 / height);
|
|
361
|
+
}
|
|
362
|
+
draw(state);
|
|
363
|
+
};
|
|
364
|
+
var applyRegionBlur = ({
|
|
365
|
+
state,
|
|
366
|
+
source,
|
|
367
|
+
width,
|
|
368
|
+
height,
|
|
369
|
+
flipSourceY,
|
|
370
|
+
topLeft,
|
|
371
|
+
bottomRight,
|
|
372
|
+
blurRadius,
|
|
373
|
+
feather,
|
|
374
|
+
roundness
|
|
375
|
+
}) => {
|
|
376
|
+
const { gl } = state;
|
|
377
|
+
gl.viewport(0, 0, width, height);
|
|
378
|
+
gl.clearColor(0, 0, 0, 0);
|
|
379
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
380
|
+
gl.bindTexture(gl.TEXTURE_2D, state.sourceTexture);
|
|
381
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
382
|
+
allocateTexture(gl, state.horizontalTexture, width, height);
|
|
383
|
+
allocateTexture(gl, state.blurredTexture, width, height);
|
|
384
|
+
renderBlurPass({
|
|
385
|
+
state,
|
|
386
|
+
program: state.horizontalProgram,
|
|
387
|
+
uniforms: state.horizontalUniforms,
|
|
388
|
+
input: state.sourceTexture,
|
|
389
|
+
output: state.horizontalTexture,
|
|
390
|
+
width,
|
|
391
|
+
height,
|
|
392
|
+
radius: blurRadius
|
|
393
|
+
});
|
|
394
|
+
renderBlurPass({
|
|
395
|
+
state,
|
|
396
|
+
program: state.verticalProgram,
|
|
397
|
+
uniforms: state.verticalUniforms,
|
|
398
|
+
input: state.horizontalTexture,
|
|
399
|
+
output: state.blurredTexture,
|
|
400
|
+
width,
|
|
401
|
+
height,
|
|
402
|
+
radius: blurRadius
|
|
403
|
+
});
|
|
404
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
405
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
406
|
+
gl.useProgram(state.compositeProgram);
|
|
407
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
408
|
+
gl.bindTexture(gl.TEXTURE_2D, state.sourceTexture);
|
|
409
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
410
|
+
gl.bindTexture(gl.TEXTURE_2D, state.blurredTexture);
|
|
411
|
+
const topLeftShader = publicUvToShaderUv(topLeft);
|
|
412
|
+
const bottomRightShader = publicUvToShaderUv(bottomRight);
|
|
413
|
+
const uniforms = state.compositeUniforms;
|
|
414
|
+
if (uniforms.source)
|
|
415
|
+
gl.uniform1i(uniforms.source, 0);
|
|
416
|
+
if (uniforms.blurred)
|
|
417
|
+
gl.uniform1i(uniforms.blurred, 1);
|
|
418
|
+
if (uniforms.resolution)
|
|
419
|
+
gl.uniform2f(uniforms.resolution, width, height);
|
|
420
|
+
if (uniforms.topLeft) {
|
|
421
|
+
gl.uniform2f(uniforms.topLeft, topLeftShader[0], topLeftShader[1]);
|
|
422
|
+
}
|
|
423
|
+
if (uniforms.bottomRight) {
|
|
424
|
+
gl.uniform2f(uniforms.bottomRight, bottomRightShader[0], bottomRightShader[1]);
|
|
425
|
+
}
|
|
426
|
+
if (uniforms.feather)
|
|
427
|
+
gl.uniform1f(uniforms.feather, feather);
|
|
428
|
+
if (uniforms.roundness)
|
|
429
|
+
gl.uniform1f(uniforms.roundness, roundness);
|
|
430
|
+
draw(state);
|
|
431
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
432
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
433
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
434
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
435
|
+
gl.useProgram(null);
|
|
436
|
+
};
|
|
437
|
+
var cleanupRegionBlur = (state) => {
|
|
438
|
+
const { gl } = state;
|
|
439
|
+
gl.deleteFramebuffer(state.framebuffer);
|
|
440
|
+
gl.deleteTexture(state.sourceTexture);
|
|
441
|
+
gl.deleteTexture(state.horizontalTexture);
|
|
442
|
+
gl.deleteTexture(state.blurredTexture);
|
|
443
|
+
gl.deleteBuffer(state.vbo);
|
|
444
|
+
gl.deleteVertexArray(state.vao);
|
|
445
|
+
gl.deleteProgram(state.horizontalProgram);
|
|
446
|
+
gl.deleteProgram(state.verticalProgram);
|
|
447
|
+
gl.deleteProgram(state.compositeProgram);
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
// src/region-blur/index.ts
|
|
451
|
+
var { createEffect } = Internals2;
|
|
452
|
+
var DEFAULT_BLUR_RADIUS = 40;
|
|
453
|
+
var DEFAULT_FEATHER = 0;
|
|
454
|
+
var DEFAULT_ROUNDNESS = 0;
|
|
455
|
+
var regionBlurSchema = {
|
|
456
|
+
topLeft: {
|
|
457
|
+
type: "uv-coordinate",
|
|
458
|
+
min: -1,
|
|
459
|
+
max: 2,
|
|
460
|
+
step: 0.01,
|
|
461
|
+
default: undefined,
|
|
462
|
+
description: "Top left"
|
|
463
|
+
},
|
|
464
|
+
bottomRight: {
|
|
465
|
+
type: "uv-coordinate",
|
|
466
|
+
min: -1,
|
|
467
|
+
max: 2,
|
|
468
|
+
step: 0.01,
|
|
469
|
+
default: undefined,
|
|
470
|
+
description: "Bottom right"
|
|
471
|
+
},
|
|
472
|
+
blurRadius: {
|
|
473
|
+
type: "number",
|
|
474
|
+
min: 0,
|
|
475
|
+
max: 200,
|
|
476
|
+
step: 1,
|
|
477
|
+
default: DEFAULT_BLUR_RADIUS,
|
|
478
|
+
description: "Blur radius",
|
|
479
|
+
hiddenFromList: false
|
|
480
|
+
},
|
|
481
|
+
feather: {
|
|
482
|
+
type: "number",
|
|
483
|
+
min: 0,
|
|
484
|
+
max: 200,
|
|
485
|
+
step: 1,
|
|
486
|
+
default: DEFAULT_FEATHER,
|
|
487
|
+
description: "Feather",
|
|
488
|
+
hiddenFromList: false
|
|
489
|
+
},
|
|
490
|
+
roundness: {
|
|
491
|
+
type: "number",
|
|
492
|
+
min: 0,
|
|
493
|
+
max: 1,
|
|
494
|
+
step: 0.01,
|
|
495
|
+
default: DEFAULT_ROUNDNESS,
|
|
496
|
+
description: "Roundness",
|
|
497
|
+
hiddenFromList: false
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
var resolve = (params) => ({
|
|
501
|
+
topLeft: [...params.topLeft],
|
|
502
|
+
bottomRight: [...params.bottomRight],
|
|
503
|
+
blurRadius: params.blurRadius ?? DEFAULT_BLUR_RADIUS,
|
|
504
|
+
feather: params.feather ?? DEFAULT_FEATHER,
|
|
505
|
+
roundness: params.roundness ?? DEFAULT_ROUNDNESS
|
|
506
|
+
});
|
|
507
|
+
var assertRequiredUvCoordinate = (value, name) => {
|
|
508
|
+
if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "number" || !Number.isFinite(item))) {
|
|
509
|
+
throw new TypeError(`"${name}" must be a [number, number] tuple`);
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
var validateRegionBlurParams = (params) => {
|
|
513
|
+
assertEffectParamsObject(params, "Region blur");
|
|
514
|
+
assertRequiredUvCoordinate(params.topLeft, "topLeft");
|
|
515
|
+
assertRequiredUvCoordinate(params.bottomRight, "bottomRight");
|
|
516
|
+
assertOptionalFiniteNumber(params.blurRadius, "blurRadius");
|
|
517
|
+
assertOptionalFiniteNumber(params.feather, "feather");
|
|
518
|
+
assertOptionalFiniteNumber(params.roundness, "roundness");
|
|
519
|
+
const resolved = resolve(params);
|
|
520
|
+
validateNonNegative(resolved.blurRadius, "blurRadius");
|
|
521
|
+
validateNonNegative(resolved.feather, "feather");
|
|
522
|
+
validateUnitInterval(resolved.roundness, "roundness");
|
|
523
|
+
if (resolved.topLeft[0] >= resolved.bottomRight[0] || resolved.topLeft[1] >= resolved.bottomRight[1]) {
|
|
524
|
+
throw new TypeError('"topLeft" must be above and to the left of "bottomRight"');
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var regionBlur = createEffect({
|
|
528
|
+
type: "remotion/region-blur",
|
|
529
|
+
label: "regionBlur()",
|
|
530
|
+
documentationLink: "https://www.remotion.dev/docs/effects/region-blur",
|
|
531
|
+
backend: "webgl2",
|
|
532
|
+
calculateKey: (params) => {
|
|
533
|
+
const resolved = resolve(params);
|
|
534
|
+
return `region-blur-${resolved.topLeft.join(":")}-${resolved.bottomRight.join(":")}-${resolved.blurRadius}-${resolved.feather}-${resolved.roundness}`;
|
|
535
|
+
},
|
|
536
|
+
setup: (target) => setupRegionBlur(target),
|
|
537
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
538
|
+
const resolved = resolve(params);
|
|
539
|
+
applyRegionBlur({
|
|
540
|
+
state,
|
|
541
|
+
source,
|
|
542
|
+
width,
|
|
543
|
+
height,
|
|
544
|
+
flipSourceY,
|
|
545
|
+
...resolved
|
|
546
|
+
});
|
|
547
|
+
},
|
|
548
|
+
cleanup: (state) => cleanupRegionBlur(state),
|
|
549
|
+
schema: regionBlurSchema,
|
|
550
|
+
validateParams: validateRegionBlurParams
|
|
551
|
+
});
|
|
552
|
+
export {
|
|
553
|
+
regionBlur
|
|
554
|
+
};
|