@remotion/effects 4.0.541 → 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,584 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertOptionalFiniteNumber,
|
|
3
|
+
validateUnitInterval
|
|
4
|
+
} from "./index-wxhvgv2s.mjs";
|
|
5
|
+
import {
|
|
6
|
+
WEBGPU_SINGLE_PASS_VERTEX,
|
|
7
|
+
setupWebGpuSinglePass,
|
|
8
|
+
cleanupWebGpuSinglePass,
|
|
9
|
+
applyWebGpuSinglePass
|
|
10
|
+
} from "./index-tvfexb7s.mjs";
|
|
11
|
+
import {
|
|
12
|
+
assertEffectParamsObject,
|
|
13
|
+
assertRequiredFiniteNumber
|
|
14
|
+
} from "./index-4fvp93ps.mjs";
|
|
15
|
+
|
|
16
|
+
// src/noise-displacement.ts
|
|
17
|
+
import { Internals } from "remotion";
|
|
18
|
+
|
|
19
|
+
// src/noise-displacement-webgpu-shader.ts
|
|
20
|
+
var NOISE_DISPLACEMENT_WEBGPU_SHADER = `
|
|
21
|
+
${WEBGPU_SINGLE_PASS_VERTEX}
|
|
22
|
+
@group(0) @binding(0) var source: texture_2d<f32>;
|
|
23
|
+
@group(0) @binding(1) var sourceSampler: sampler;
|
|
24
|
+
@group(0) @binding(2) var<uniform> params: Params;
|
|
25
|
+
|
|
26
|
+
struct Params { size: vec2f, center: vec2f, radius: f32, strength: f32, seed: f32, grainSize: f32, passes: f32, blur: f32, feather: f32, biasDirection: f32, biasAmount: f32, }
|
|
27
|
+
const DISC = array<vec2f,9>(vec2f(0),vec2f(1,0),vec2f(-1,0),vec2f(0,1),vec2f(0,-1),vec2f(0.707,0.707),vec2f(-0.707,0.707),vec2f(0.707,-0.707),vec2f(-0.707,-0.707));
|
|
28
|
+
const DISC_W = array<f32,9>(1.0,0.7,0.7,0.7,0.7,0.5,0.5,0.5,0.5);
|
|
29
|
+
fn hash12(p: vec2f) -> f32 {
|
|
30
|
+
var p3=fract(p.xyx*0.1031+vec3f(params.seed*0.0973));
|
|
31
|
+
p3 += vec3f(dot(p3,p3.yzx+vec3f(33.33)));
|
|
32
|
+
return fract((p3.x+p3.y)*p3.z);
|
|
33
|
+
}
|
|
34
|
+
fn valueNoise(p: vec2f) -> f32 {
|
|
35
|
+
let i=floor(p); let f=fract(p); let u=f*f*(vec2f(3.0)-2.0*f);
|
|
36
|
+
return mix(mix(hash12(i),hash12(i+vec2f(1,0)),u.x),mix(hash12(i+vec2f(0,1)),hash12(i+vec2f(1,1)),u.x),u.y);
|
|
37
|
+
}
|
|
38
|
+
fn noiseVector(p: vec2f) -> vec2f { return vec2f(valueNoise(p+vec2f(17.13,71.79)),valueNoise(p+vec2f(83.41,29.67)))*2.0-vec2f(1.0); }
|
|
39
|
+
fn effectMask(pixel: vec2f) -> f32 {
|
|
40
|
+
let radius=params.radius*min(params.size.x,params.size.y);
|
|
41
|
+
let distance=length(pixel-params.center*params.size);
|
|
42
|
+
if(distance>=radius) { return 0.0; }
|
|
43
|
+
if(params.feather<=0.0001) { return 1.0; }
|
|
44
|
+
return 1.0-smoothstep(radius*(1.0-params.feather),radius,distance);
|
|
45
|
+
}
|
|
46
|
+
fn sampleSource(pixel: vec2f) -> vec4f { return textureSampleLevel(source,sourceSampler,clamp(pixel/params.size,vec2f(0),vec2f(1)),0); }
|
|
47
|
+
@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
|
48
|
+
let pixel=input.uv*params.size;
|
|
49
|
+
let mask=effectMask(pixel);
|
|
50
|
+
if(mask<=0.0 || params.strength<=0.0) { return textureSampleLevel(source,sourceSampler,input.uv,0); }
|
|
51
|
+
let noiseCoord=pixel/max(params.grainSize,0.001);
|
|
52
|
+
let direction=params.biasDirection*3.141592653589793/180.0;
|
|
53
|
+
let displacement=(noiseVector(noiseCoord)+vec2f(cos(direction),sin(direction))*params.biasAmount)*params.strength*mask;
|
|
54
|
+
let passes=max(i32(params.passes),1);
|
|
55
|
+
let blurRadius=params.blur*mask;
|
|
56
|
+
let blurTaps=select(1,9,blurRadius>0.5);
|
|
57
|
+
var color=vec4f(0); var totalWeight=0.0;
|
|
58
|
+
for(var s=0;s<12;s++) {
|
|
59
|
+
if(s>=passes) { break; }
|
|
60
|
+
let t=select(f32(s)/f32(max(passes-1,1)),1.0,passes==1);
|
|
61
|
+
let samplePixel=pixel+displacement*t;
|
|
62
|
+
let passWeight=1.0-t*0.6;
|
|
63
|
+
for(var b=0;b<9;b++) {
|
|
64
|
+
if(b>=blurTaps) { break; }
|
|
65
|
+
let weight=passWeight*DISC_W[b];
|
|
66
|
+
color += sampleSource(samplePixel+DISC[b]*blurRadius)*weight;
|
|
67
|
+
totalWeight += weight;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return color/totalWeight;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
// src/noise-displacement.ts
|
|
76
|
+
var { createEffect, createWebGL2ContextError } = Internals;
|
|
77
|
+
var DEFAULT_STRENGTH = 36;
|
|
78
|
+
var DEFAULT_SEED = 0;
|
|
79
|
+
var DEFAULT_GRAIN_SIZE = 8;
|
|
80
|
+
var DEFAULT_PASSES = 6;
|
|
81
|
+
var DEFAULT_BLUR = 0;
|
|
82
|
+
var DEFAULT_FEATHER = 0.25;
|
|
83
|
+
var DEFAULT_BIAS_DIRECTION = 0;
|
|
84
|
+
var DEFAULT_BIAS_AMOUNT = 0;
|
|
85
|
+
var MAX_PASSES = 12;
|
|
86
|
+
var noiseDisplacementSchema = {
|
|
87
|
+
center: {
|
|
88
|
+
type: "uv-coordinate",
|
|
89
|
+
step: 0.01,
|
|
90
|
+
default: undefined,
|
|
91
|
+
description: "Center"
|
|
92
|
+
},
|
|
93
|
+
radius: {
|
|
94
|
+
type: "number",
|
|
95
|
+
min: 0.001,
|
|
96
|
+
max: 1,
|
|
97
|
+
step: 0.01,
|
|
98
|
+
default: undefined,
|
|
99
|
+
description: "Radius",
|
|
100
|
+
hiddenFromList: false
|
|
101
|
+
},
|
|
102
|
+
strength: {
|
|
103
|
+
type: "number",
|
|
104
|
+
min: 0,
|
|
105
|
+
max: 200,
|
|
106
|
+
step: 0.1,
|
|
107
|
+
default: DEFAULT_STRENGTH,
|
|
108
|
+
description: "Strength",
|
|
109
|
+
hiddenFromList: false
|
|
110
|
+
},
|
|
111
|
+
seed: {
|
|
112
|
+
type: "number",
|
|
113
|
+
step: 1,
|
|
114
|
+
default: DEFAULT_SEED,
|
|
115
|
+
description: "Seed",
|
|
116
|
+
hiddenFromList: false
|
|
117
|
+
},
|
|
118
|
+
grainSize: {
|
|
119
|
+
type: "number",
|
|
120
|
+
min: 0.1,
|
|
121
|
+
max: 100,
|
|
122
|
+
step: 0.1,
|
|
123
|
+
default: DEFAULT_GRAIN_SIZE,
|
|
124
|
+
description: "Grain size",
|
|
125
|
+
hiddenFromList: false
|
|
126
|
+
},
|
|
127
|
+
passes: {
|
|
128
|
+
type: "number",
|
|
129
|
+
min: 1,
|
|
130
|
+
max: MAX_PASSES,
|
|
131
|
+
step: 1,
|
|
132
|
+
integer: true,
|
|
133
|
+
default: DEFAULT_PASSES,
|
|
134
|
+
description: "Passes",
|
|
135
|
+
hiddenFromList: false
|
|
136
|
+
},
|
|
137
|
+
blur: {
|
|
138
|
+
type: "number",
|
|
139
|
+
min: 0,
|
|
140
|
+
max: 100,
|
|
141
|
+
step: 0.1,
|
|
142
|
+
default: DEFAULT_BLUR,
|
|
143
|
+
description: "Blur",
|
|
144
|
+
hiddenFromList: false
|
|
145
|
+
},
|
|
146
|
+
feather: {
|
|
147
|
+
type: "number",
|
|
148
|
+
min: 0,
|
|
149
|
+
max: 1,
|
|
150
|
+
step: 0.01,
|
|
151
|
+
default: DEFAULT_FEATHER,
|
|
152
|
+
description: "Feather",
|
|
153
|
+
hiddenFromList: false
|
|
154
|
+
},
|
|
155
|
+
biasDirection: {
|
|
156
|
+
type: "rotation-degrees",
|
|
157
|
+
step: 1,
|
|
158
|
+
default: DEFAULT_BIAS_DIRECTION,
|
|
159
|
+
description: "Bias direction"
|
|
160
|
+
},
|
|
161
|
+
biasAmount: {
|
|
162
|
+
type: "number",
|
|
163
|
+
min: 0,
|
|
164
|
+
max: 1,
|
|
165
|
+
step: 0.01,
|
|
166
|
+
default: DEFAULT_BIAS_AMOUNT,
|
|
167
|
+
description: "Bias amount",
|
|
168
|
+
hiddenFromList: false
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
var resolve = (p) => ({
|
|
172
|
+
center: [...p.center],
|
|
173
|
+
radius: p.radius,
|
|
174
|
+
strength: p.strength ?? DEFAULT_STRENGTH,
|
|
175
|
+
seed: p.seed ?? DEFAULT_SEED,
|
|
176
|
+
grainSize: p.grainSize ?? DEFAULT_GRAIN_SIZE,
|
|
177
|
+
passes: p.passes ?? DEFAULT_PASSES,
|
|
178
|
+
blur: p.blur ?? DEFAULT_BLUR,
|
|
179
|
+
feather: p.feather ?? DEFAULT_FEATHER,
|
|
180
|
+
biasDirection: p.biasDirection ?? DEFAULT_BIAS_DIRECTION,
|
|
181
|
+
biasAmount: p.biasAmount ?? DEFAULT_BIAS_AMOUNT
|
|
182
|
+
});
|
|
183
|
+
var assertRequiredUvCoordinate = (value, name) => {
|
|
184
|
+
if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "number" || !Number.isFinite(item))) {
|
|
185
|
+
throw new TypeError(`"${name}" must be a [number, number] tuple`);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var assertOptionalIntegerNumber = (value, name) => {
|
|
189
|
+
if (value === undefined) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (!Number.isInteger(value)) {
|
|
193
|
+
throw new TypeError(`"${name}" must be an integer, but got ${JSON.stringify(value)}`);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var validatePositive = (value, name) => {
|
|
197
|
+
if (value <= 0) {
|
|
198
|
+
throw new TypeError(`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
var validateMax = (value, max, name) => {
|
|
202
|
+
if (value > max) {
|
|
203
|
+
throw new TypeError(`"${name}" must be <= ${max}, but got ${JSON.stringify(value)}`);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var validateNoiseDisplacementParams = (params) => {
|
|
207
|
+
assertEffectParamsObject(params, "Noise Displacement");
|
|
208
|
+
assertRequiredUvCoordinate(params.center, "center");
|
|
209
|
+
assertRequiredFiniteNumber(params.radius, "radius");
|
|
210
|
+
assertOptionalFiniteNumber(params.strength, "strength");
|
|
211
|
+
assertOptionalFiniteNumber(params.seed, "seed");
|
|
212
|
+
assertOptionalFiniteNumber(params.grainSize, "grainSize");
|
|
213
|
+
assertOptionalFiniteNumber(params.passes, "passes");
|
|
214
|
+
assertOptionalIntegerNumber(params.passes, "passes");
|
|
215
|
+
assertOptionalFiniteNumber(params.blur, "blur");
|
|
216
|
+
assertOptionalFiniteNumber(params.feather, "feather");
|
|
217
|
+
assertOptionalFiniteNumber(params.biasDirection, "biasDirection");
|
|
218
|
+
assertOptionalFiniteNumber(params.biasAmount, "biasAmount");
|
|
219
|
+
const r = resolve(params);
|
|
220
|
+
validateUnitInterval(r.center[0], "center[0]");
|
|
221
|
+
validateUnitInterval(r.center[1], "center[1]");
|
|
222
|
+
validatePositive(r.radius, "radius");
|
|
223
|
+
validateUnitInterval(r.radius, "radius");
|
|
224
|
+
if (r.strength < 0) {
|
|
225
|
+
throw new TypeError(`"strength" must be >= 0, but got ${JSON.stringify(r.strength)}`);
|
|
226
|
+
}
|
|
227
|
+
validatePositive(r.grainSize, "grainSize");
|
|
228
|
+
validatePositive(r.passes, "passes");
|
|
229
|
+
validateMax(r.passes, MAX_PASSES, "passes");
|
|
230
|
+
if (r.blur < 0) {
|
|
231
|
+
throw new TypeError(`"blur" must be >= 0, but got ${JSON.stringify(r.blur)}`);
|
|
232
|
+
}
|
|
233
|
+
validateUnitInterval(r.feather, "feather");
|
|
234
|
+
if (r.biasAmount < 0) {
|
|
235
|
+
throw new TypeError(`"biasAmount" must be >= 0, but got ${JSON.stringify(r.biasAmount)}`);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
var NOISE_DISPLACEMENT_VS = `#version 300 es
|
|
239
|
+
in vec2 aPos;
|
|
240
|
+
in vec2 aUv;
|
|
241
|
+
out vec2 vUv;
|
|
242
|
+
|
|
243
|
+
void main() {
|
|
244
|
+
vUv = aUv;
|
|
245
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
246
|
+
}
|
|
247
|
+
`;
|
|
248
|
+
var NOISE_DISPLACEMENT_FS = `#version 300 es
|
|
249
|
+
precision highp float;
|
|
250
|
+
|
|
251
|
+
in vec2 vUv;
|
|
252
|
+
out vec4 fragColor;
|
|
253
|
+
|
|
254
|
+
uniform sampler2D uSource;
|
|
255
|
+
uniform vec2 uResolution;
|
|
256
|
+
uniform vec2 uCenter;
|
|
257
|
+
uniform float uRadius;
|
|
258
|
+
uniform float uStrength;
|
|
259
|
+
uniform float uSeed;
|
|
260
|
+
uniform float uGrainSize;
|
|
261
|
+
uniform int uPasses;
|
|
262
|
+
uniform float uBlur;
|
|
263
|
+
uniform float uFeather;
|
|
264
|
+
uniform float uBiasDirection;
|
|
265
|
+
uniform float uBiasAmount;
|
|
266
|
+
|
|
267
|
+
const float PI = 3.141592653589793;
|
|
268
|
+
const vec2 DISC[9] = vec2[9](
|
|
269
|
+
vec2(0.0, 0.0),
|
|
270
|
+
vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0),
|
|
271
|
+
vec2(0.707, 0.707), vec2(-0.707, 0.707),
|
|
272
|
+
vec2(0.707, -0.707), vec2(-0.707, -0.707)
|
|
273
|
+
);
|
|
274
|
+
const float DISC_W[9] = float[9](1.0, 0.7, 0.7, 0.7, 0.7, 0.5, 0.5, 0.5, 0.5);
|
|
275
|
+
|
|
276
|
+
float hash12(vec2 p) {
|
|
277
|
+
vec3 p3 = fract(vec3(p.xyx) * 0.1031 + uSeed * 0.0973);
|
|
278
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
279
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
float valueNoise(vec2 p) {
|
|
283
|
+
vec2 i = floor(p);
|
|
284
|
+
vec2 f = fract(p);
|
|
285
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
286
|
+
return mix(
|
|
287
|
+
mix(hash12(i), hash12(i + vec2(1.0, 0.0)), u.x),
|
|
288
|
+
mix(hash12(i + vec2(0.0, 1.0)), hash12(i + vec2(1.0, 1.0)), u.x),
|
|
289
|
+
u.y
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
vec2 noiseVector(vec2 p) {
|
|
294
|
+
return vec2(
|
|
295
|
+
valueNoise(p + vec2(17.13, 71.79)),
|
|
296
|
+
valueNoise(p + vec2(83.41, 29.67))
|
|
297
|
+
) * 2.0 - 1.0;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
float effectMask(vec2 pixel) {
|
|
301
|
+
vec2 centerPx = uCenter * uResolution;
|
|
302
|
+
float radiusPx = uRadius * min(uResolution.x, uResolution.y);
|
|
303
|
+
float dist = length(pixel - centerPx);
|
|
304
|
+
|
|
305
|
+
if (dist >= radiusPx) {
|
|
306
|
+
return 0.0;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (uFeather <= 0.0001) {
|
|
310
|
+
return 1.0;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
float inner = radiusPx * (1.0 - uFeather);
|
|
314
|
+
return 1.0 - smoothstep(inner, radiusPx, dist);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
vec4 sampleSource(vec2 pixel) {
|
|
318
|
+
vec2 uv = clamp(
|
|
319
|
+
vec2(pixel.x / uResolution.x, 1.0 - pixel.y / uResolution.y),
|
|
320
|
+
vec2(0.0),
|
|
321
|
+
vec2(1.0)
|
|
322
|
+
);
|
|
323
|
+
return texture(uSource, uv);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
void main() {
|
|
327
|
+
vec2 pixel = vec2(vUv.x, 1.0 - vUv.y) * uResolution;
|
|
328
|
+
float mask = effectMask(pixel);
|
|
329
|
+
|
|
330
|
+
if (mask <= 0.0 || uStrength <= 0.0) {
|
|
331
|
+
fragColor = texture(uSource, vUv);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
vec2 noiseCoord = pixel / max(uGrainSize, 0.001);
|
|
336
|
+
vec2 biasDir = vec2(
|
|
337
|
+
cos(uBiasDirection * PI / 180.0),
|
|
338
|
+
sin(uBiasDirection * PI / 180.0)
|
|
339
|
+
);
|
|
340
|
+
vec2 displacement = (noiseVector(noiseCoord) + biasDir * uBiasAmount) * uStrength * mask;
|
|
341
|
+
int passes = max(uPasses, 1);
|
|
342
|
+
float blurRadius = uBlur * mask;
|
|
343
|
+
int blurTaps = blurRadius > 0.5 ? 9 : 1;
|
|
344
|
+
|
|
345
|
+
vec4 color = vec4(0.0);
|
|
346
|
+
float totalWeight = 0.0;
|
|
347
|
+
for (int s = 0; s < 12; s++) {
|
|
348
|
+
if (s >= passes) {
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
float t = passes == 1 ? 1.0 : float(s) / float(passes - 1);
|
|
353
|
+
vec2 samplePixel = pixel + displacement * t;
|
|
354
|
+
float passWeight = 1.0 - t * 0.6;
|
|
355
|
+
|
|
356
|
+
for (int b = 0; b < 9; b++) {
|
|
357
|
+
if (b >= blurTaps) {
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
float weight = passWeight * DISC_W[b];
|
|
362
|
+
color += sampleSource(samplePixel + DISC[b] * blurRadius) * weight;
|
|
363
|
+
totalWeight += weight;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
fragColor = color / totalWeight;
|
|
368
|
+
}
|
|
369
|
+
`;
|
|
370
|
+
var compileShader = (gl, type, source) => {
|
|
371
|
+
const shader = gl.createShader(type);
|
|
372
|
+
if (!shader) {
|
|
373
|
+
throw new Error("Failed to create WebGL shader");
|
|
374
|
+
}
|
|
375
|
+
gl.shaderSource(shader, source);
|
|
376
|
+
gl.compileShader(shader);
|
|
377
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
378
|
+
const log = gl.getShaderInfoLog(shader);
|
|
379
|
+
gl.deleteShader(shader);
|
|
380
|
+
throw new Error(`Noise displacement shader compile failed: ${log ?? "(no log)"}`);
|
|
381
|
+
}
|
|
382
|
+
return shader;
|
|
383
|
+
};
|
|
384
|
+
var linkProgram = (gl, vs, fs) => {
|
|
385
|
+
const program = gl.createProgram();
|
|
386
|
+
if (!program) {
|
|
387
|
+
throw new Error("Failed to create WebGL program");
|
|
388
|
+
}
|
|
389
|
+
gl.attachShader(program, vs);
|
|
390
|
+
gl.attachShader(program, fs);
|
|
391
|
+
gl.linkProgram(program);
|
|
392
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
393
|
+
const log = gl.getProgramInfoLog(program);
|
|
394
|
+
gl.deleteProgram(program);
|
|
395
|
+
throw new Error(`Noise displacement program link failed: ${log ?? "(no log)"}`);
|
|
396
|
+
}
|
|
397
|
+
return program;
|
|
398
|
+
};
|
|
399
|
+
var setupNoiseDisplacement = (target) => {
|
|
400
|
+
const gl = target.getContext("webgl2", {
|
|
401
|
+
premultipliedAlpha: true,
|
|
402
|
+
alpha: true,
|
|
403
|
+
preserveDrawingBuffer: true
|
|
404
|
+
});
|
|
405
|
+
if (!gl) {
|
|
406
|
+
throw createWebGL2ContextError("noise displacement effect");
|
|
407
|
+
}
|
|
408
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
409
|
+
const vs = compileShader(gl, gl.VERTEX_SHADER, NOISE_DISPLACEMENT_VS);
|
|
410
|
+
const fs = compileShader(gl, gl.FRAGMENT_SHADER, NOISE_DISPLACEMENT_FS);
|
|
411
|
+
const program = linkProgram(gl, vs, fs);
|
|
412
|
+
gl.deleteShader(vs);
|
|
413
|
+
gl.deleteShader(fs);
|
|
414
|
+
const vao = gl.createVertexArray();
|
|
415
|
+
if (!vao) {
|
|
416
|
+
throw new Error("Failed to create WebGL vertex array");
|
|
417
|
+
}
|
|
418
|
+
gl.bindVertexArray(vao);
|
|
419
|
+
const data = new Float32Array([
|
|
420
|
+
-1,
|
|
421
|
+
-1,
|
|
422
|
+
0,
|
|
423
|
+
0,
|
|
424
|
+
1,
|
|
425
|
+
-1,
|
|
426
|
+
1,
|
|
427
|
+
0,
|
|
428
|
+
-1,
|
|
429
|
+
1,
|
|
430
|
+
0,
|
|
431
|
+
1,
|
|
432
|
+
1,
|
|
433
|
+
1,
|
|
434
|
+
1,
|
|
435
|
+
1
|
|
436
|
+
]);
|
|
437
|
+
const vbo = gl.createBuffer();
|
|
438
|
+
if (!vbo) {
|
|
439
|
+
throw new Error("Failed to create WebGL buffer");
|
|
440
|
+
}
|
|
441
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
442
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
443
|
+
const aPos = gl.getAttribLocation(program, "aPos");
|
|
444
|
+
const aUv = gl.getAttribLocation(program, "aUv");
|
|
445
|
+
gl.enableVertexAttribArray(aPos);
|
|
446
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
|
|
447
|
+
gl.enableVertexAttribArray(aUv);
|
|
448
|
+
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
|
|
449
|
+
gl.bindVertexArray(null);
|
|
450
|
+
const texture = gl.createTexture();
|
|
451
|
+
if (!texture) {
|
|
452
|
+
throw new Error("Failed to create WebGL texture");
|
|
453
|
+
}
|
|
454
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
455
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
456
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
457
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
458
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
459
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
460
|
+
return {
|
|
461
|
+
gl,
|
|
462
|
+
program,
|
|
463
|
+
vao,
|
|
464
|
+
vbo,
|
|
465
|
+
texture,
|
|
466
|
+
uniforms: {
|
|
467
|
+
uSource: gl.getUniformLocation(program, "uSource"),
|
|
468
|
+
uResolution: gl.getUniformLocation(program, "uResolution"),
|
|
469
|
+
uCenter: gl.getUniformLocation(program, "uCenter"),
|
|
470
|
+
uRadius: gl.getUniformLocation(program, "uRadius"),
|
|
471
|
+
uStrength: gl.getUniformLocation(program, "uStrength"),
|
|
472
|
+
uSeed: gl.getUniformLocation(program, "uSeed"),
|
|
473
|
+
uGrainSize: gl.getUniformLocation(program, "uGrainSize"),
|
|
474
|
+
uPasses: gl.getUniformLocation(program, "uPasses"),
|
|
475
|
+
uBlur: gl.getUniformLocation(program, "uBlur"),
|
|
476
|
+
uFeather: gl.getUniformLocation(program, "uFeather"),
|
|
477
|
+
uBiasDirection: gl.getUniformLocation(program, "uBiasDirection"),
|
|
478
|
+
uBiasAmount: gl.getUniformLocation(program, "uBiasAmount")
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
var noiseDisplacement = createEffect({
|
|
483
|
+
type: "dev.remotion.effects.noiseDisplacement",
|
|
484
|
+
label: "noiseDisplacement()",
|
|
485
|
+
documentationLink: "https://www.remotion.dev/docs/effects/noise-displacement",
|
|
486
|
+
calculateKey: (params) => {
|
|
487
|
+
const r = resolve(params);
|
|
488
|
+
return `noise-displacement-${r.center.join(":")}-${r.radius}-${r.strength}-${r.seed}-${r.grainSize}-${r.passes}-${r.blur}-${r.feather}-${r.biasDirection}-${r.biasAmount}`;
|
|
489
|
+
},
|
|
490
|
+
implementations: {
|
|
491
|
+
webgpu: Internals.createEffectImplementation({
|
|
492
|
+
setup: (target) => setupWebGpuSinglePass(target, "noise-displacement"),
|
|
493
|
+
apply: ({ source, width, height, params, state, gpuDevice }) => {
|
|
494
|
+
if (!gpuDevice)
|
|
495
|
+
throw new Error("A WebGPU device is required for the noise-displacement effect");
|
|
496
|
+
const r = resolve(params);
|
|
497
|
+
const uniformData = new Float32Array([
|
|
498
|
+
width,
|
|
499
|
+
height,
|
|
500
|
+
r.center[0],
|
|
501
|
+
r.center[1],
|
|
502
|
+
r.radius,
|
|
503
|
+
r.strength,
|
|
504
|
+
r.seed,
|
|
505
|
+
r.grainSize,
|
|
506
|
+
r.passes,
|
|
507
|
+
r.blur,
|
|
508
|
+
r.feather,
|
|
509
|
+
r.biasDirection,
|
|
510
|
+
r.biasAmount,
|
|
511
|
+
0,
|
|
512
|
+
0,
|
|
513
|
+
0
|
|
514
|
+
]);
|
|
515
|
+
applyWebGpuSinglePass({
|
|
516
|
+
state,
|
|
517
|
+
source,
|
|
518
|
+
width,
|
|
519
|
+
height,
|
|
520
|
+
device: gpuDevice,
|
|
521
|
+
shader: NOISE_DISPLACEMENT_WEBGPU_SHADER,
|
|
522
|
+
uniformData
|
|
523
|
+
});
|
|
524
|
+
},
|
|
525
|
+
cleanup: cleanupWebGpuSinglePass
|
|
526
|
+
}),
|
|
527
|
+
webgl2: Internals.createEffectImplementation({
|
|
528
|
+
setup: (target) => setupNoiseDisplacement(target),
|
|
529
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
530
|
+
const r = resolve(params);
|
|
531
|
+
const { gl, program, texture, vao, uniforms } = state;
|
|
532
|
+
gl.viewport(0, 0, width, height);
|
|
533
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
534
|
+
gl.clearColor(0, 0, 0, 0);
|
|
535
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
536
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
537
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
538
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
539
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
540
|
+
gl.useProgram(program);
|
|
541
|
+
if (uniforms.uSource)
|
|
542
|
+
gl.uniform1i(uniforms.uSource, 0);
|
|
543
|
+
if (uniforms.uResolution)
|
|
544
|
+
gl.uniform2f(uniforms.uResolution, width, height);
|
|
545
|
+
if (uniforms.uCenter)
|
|
546
|
+
gl.uniform2f(uniforms.uCenter, r.center[0], r.center[1]);
|
|
547
|
+
if (uniforms.uRadius)
|
|
548
|
+
gl.uniform1f(uniforms.uRadius, r.radius);
|
|
549
|
+
if (uniforms.uStrength)
|
|
550
|
+
gl.uniform1f(uniforms.uStrength, r.strength);
|
|
551
|
+
if (uniforms.uSeed)
|
|
552
|
+
gl.uniform1f(uniforms.uSeed, r.seed);
|
|
553
|
+
if (uniforms.uGrainSize)
|
|
554
|
+
gl.uniform1f(uniforms.uGrainSize, r.grainSize);
|
|
555
|
+
if (uniforms.uPasses)
|
|
556
|
+
gl.uniform1i(uniforms.uPasses, r.passes);
|
|
557
|
+
if (uniforms.uBlur)
|
|
558
|
+
gl.uniform1f(uniforms.uBlur, r.blur);
|
|
559
|
+
if (uniforms.uFeather)
|
|
560
|
+
gl.uniform1f(uniforms.uFeather, r.feather);
|
|
561
|
+
if (uniforms.uBiasDirection)
|
|
562
|
+
gl.uniform1f(uniforms.uBiasDirection, r.biasDirection);
|
|
563
|
+
if (uniforms.uBiasAmount)
|
|
564
|
+
gl.uniform1f(uniforms.uBiasAmount, r.biasAmount);
|
|
565
|
+
gl.bindVertexArray(vao);
|
|
566
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
567
|
+
gl.bindVertexArray(null);
|
|
568
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
569
|
+
gl.useProgram(null);
|
|
570
|
+
},
|
|
571
|
+
cleanup: ({ gl, program, vao, vbo, texture }) => {
|
|
572
|
+
gl.deleteTexture(texture);
|
|
573
|
+
gl.deleteBuffer(vbo);
|
|
574
|
+
gl.deleteProgram(program);
|
|
575
|
+
gl.deleteVertexArray(vao);
|
|
576
|
+
}
|
|
577
|
+
})
|
|
578
|
+
},
|
|
579
|
+
schema: noiseDisplacementSchema,
|
|
580
|
+
validateParams: validateNoiseDisplacementParams
|
|
581
|
+
});
|
|
582
|
+
export {
|
|
583
|
+
noiseDisplacement
|
|
584
|
+
};
|