@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,356 @@
|
|
|
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/speckle.ts
|
|
17
|
+
import { Internals } from "remotion";
|
|
18
|
+
|
|
19
|
+
// src/speckle-webgpu-shader.ts
|
|
20
|
+
var SPECKLE_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, density: f32, radius: f32, randomness: f32, }
|
|
27
|
+
|
|
28
|
+
fn hash21(p: vec2f) -> f32 {
|
|
29
|
+
var p3 = fract(p.xyx * vec3f(443.8975, 397.2973, 491.1871));
|
|
30
|
+
p3 += vec3f(dot(p3, p3.yzx + vec3f(19.19)));
|
|
31
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn hash22(p: vec2f) -> vec2f { return vec2f(hash21(p + vec2f(17.13)), hash21(p + vec2f(83.71))); }
|
|
35
|
+
@fragment fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
|
36
|
+
let color = textureSampleLevel(source, sourceSampler, input.uv, 0);
|
|
37
|
+
if (params.density <= 0.0 || params.radius <= 0.0) { return color; }
|
|
38
|
+
let fragPos = vec2f(input.uv.x, 1.0 - input.uv.y) * params.size;
|
|
39
|
+
let cellSize = max(params.radius * 2.5, 1.0);
|
|
40
|
+
let baseCell = floor(fragPos / cellSize);
|
|
41
|
+
var hole = 0.0;
|
|
42
|
+
for (var y = -1; y <= 1; y++) {
|
|
43
|
+
for (var x = -1; x <= 1; x++) {
|
|
44
|
+
let cell = baseCell + vec2f(f32(x), f32(y));
|
|
45
|
+
if (hash21(cell) <= params.density) {
|
|
46
|
+
let randomOffset = (hash22(cell + vec2f(11.7)) - vec2f(0.5)) * params.randomness;
|
|
47
|
+
let center = (cell + vec2f(0.5) + randomOffset) * cellSize;
|
|
48
|
+
let variation = mix(1.0, 0.35 + hash21(cell + vec2f(29.43)) * 0.65, params.randomness);
|
|
49
|
+
let radius = params.radius * 0.5 * variation;
|
|
50
|
+
let edge = min(1.0, max(radius * 0.5, 0.35));
|
|
51
|
+
hole = max(hole, 1.0 - smoothstep(radius - edge, radius + edge, length(fragPos - center)));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return color * (1.0 - clamp(hole, 0.0, 1.0));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
// src/speckle.ts
|
|
61
|
+
var { createEffect, createWebGL2ContextError } = Internals;
|
|
62
|
+
var DEFAULT_DENSITY = 0.08;
|
|
63
|
+
var DEFAULT_SIZE = 4;
|
|
64
|
+
var DEFAULT_RANDOMNESS = 1;
|
|
65
|
+
var speckleSchema = {
|
|
66
|
+
density: {
|
|
67
|
+
type: "number",
|
|
68
|
+
min: 0,
|
|
69
|
+
max: 1,
|
|
70
|
+
step: 0.01,
|
|
71
|
+
default: DEFAULT_DENSITY,
|
|
72
|
+
description: "Density",
|
|
73
|
+
hiddenFromList: false
|
|
74
|
+
},
|
|
75
|
+
size: {
|
|
76
|
+
type: "number",
|
|
77
|
+
min: 0,
|
|
78
|
+
max: 50,
|
|
79
|
+
step: 0.1,
|
|
80
|
+
default: DEFAULT_SIZE,
|
|
81
|
+
description: "Size",
|
|
82
|
+
hiddenFromList: false
|
|
83
|
+
},
|
|
84
|
+
randomness: {
|
|
85
|
+
type: "number",
|
|
86
|
+
min: 0,
|
|
87
|
+
max: 1,
|
|
88
|
+
step: 0.01,
|
|
89
|
+
default: DEFAULT_RANDOMNESS,
|
|
90
|
+
description: "Randomness",
|
|
91
|
+
hiddenFromList: false
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
var resolve = (p) => ({
|
|
95
|
+
density: p.density ?? DEFAULT_DENSITY,
|
|
96
|
+
size: p.size ?? DEFAULT_SIZE,
|
|
97
|
+
randomness: p.randomness ?? DEFAULT_RANDOMNESS
|
|
98
|
+
});
|
|
99
|
+
var validateSpeckleParams = (params) => {
|
|
100
|
+
assertEffectParamsObject(params, "Speckle");
|
|
101
|
+
assertOptionalFiniteNumber(params.density, "density");
|
|
102
|
+
assertOptionalFiniteNumber(params.size, "size");
|
|
103
|
+
assertOptionalFiniteNumber(params.randomness, "randomness");
|
|
104
|
+
const r = resolve(params);
|
|
105
|
+
validateUnitInterval(r.density, "density");
|
|
106
|
+
validateNonNegative(r.size, "size");
|
|
107
|
+
validateUnitInterval(r.randomness, "randomness");
|
|
108
|
+
};
|
|
109
|
+
var SPECKLE_VS = `#version 300 es
|
|
110
|
+
in vec2 aPos;
|
|
111
|
+
in vec2 aUv;
|
|
112
|
+
out vec2 vUv;
|
|
113
|
+
|
|
114
|
+
void main() {
|
|
115
|
+
vUv = aUv;
|
|
116
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
var SPECKLE_FS = `#version 300 es
|
|
120
|
+
precision highp float;
|
|
121
|
+
|
|
122
|
+
in vec2 vUv;
|
|
123
|
+
out vec4 fragColor;
|
|
124
|
+
|
|
125
|
+
uniform sampler2D uSource;
|
|
126
|
+
uniform vec2 uResolution;
|
|
127
|
+
uniform float uDensity;
|
|
128
|
+
uniform float uSize;
|
|
129
|
+
uniform float uRandomness;
|
|
130
|
+
|
|
131
|
+
float hash21(vec2 p) {
|
|
132
|
+
vec3 p3 = fract(vec3(p.xyx) * vec3(443.8975, 397.2973, 491.1871));
|
|
133
|
+
p3 += dot(p3, p3.yzx + 19.19);
|
|
134
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
vec2 hash22(vec2 p) {
|
|
138
|
+
return vec2(hash21(p + 17.13), hash21(p + 83.71));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void main() {
|
|
142
|
+
vec4 color = texture(uSource, vUv);
|
|
143
|
+
|
|
144
|
+
if (uDensity <= 0.0 || uSize <= 0.0) {
|
|
145
|
+
fragColor = color;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
vec2 fragPos = vUv * uResolution;
|
|
150
|
+
float cellSize = max(uSize * 2.5, 1.0);
|
|
151
|
+
vec2 baseCell = floor(fragPos / cellSize);
|
|
152
|
+
float hole = 0.0;
|
|
153
|
+
|
|
154
|
+
for (int y = -1; y <= 1; y++) {
|
|
155
|
+
for (int x = -1; x <= 1; x++) {
|
|
156
|
+
vec2 cell = baseCell + vec2(float(x), float(y));
|
|
157
|
+
float chance = hash21(cell);
|
|
158
|
+
|
|
159
|
+
if (chance <= uDensity) {
|
|
160
|
+
vec2 randomOffset = (hash22(cell + 11.7) - 0.5) * uRandomness;
|
|
161
|
+
vec2 center = (cell + 0.5 + randomOffset) * cellSize;
|
|
162
|
+
float sizeVariation = mix(1.0, 0.35 + hash21(cell + 29.43) * 0.65, uRandomness);
|
|
163
|
+
float radius = uSize * 0.5 * sizeVariation;
|
|
164
|
+
float edge = min(1.0, max(radius * 0.5, 0.35));
|
|
165
|
+
float coverage = 1.0 - smoothstep(radius - edge, radius + edge, length(fragPos - center));
|
|
166
|
+
hole = max(hole, coverage);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
fragColor = color * (1.0 - clamp(hole, 0.0, 1.0));
|
|
172
|
+
}
|
|
173
|
+
`;
|
|
174
|
+
var compileShader = (gl, type, source) => {
|
|
175
|
+
const shader = gl.createShader(type);
|
|
176
|
+
if (!shader) {
|
|
177
|
+
throw new Error("Failed to create WebGL shader");
|
|
178
|
+
}
|
|
179
|
+
gl.shaderSource(shader, source);
|
|
180
|
+
gl.compileShader(shader);
|
|
181
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
182
|
+
const log = gl.getShaderInfoLog(shader);
|
|
183
|
+
gl.deleteShader(shader);
|
|
184
|
+
throw new Error(`Speckle shader compile failed: ${log ?? "(no log)"}`);
|
|
185
|
+
}
|
|
186
|
+
return shader;
|
|
187
|
+
};
|
|
188
|
+
var linkProgram = (gl, vs, fs) => {
|
|
189
|
+
const program = gl.createProgram();
|
|
190
|
+
if (!program) {
|
|
191
|
+
throw new Error("Failed to create WebGL program");
|
|
192
|
+
}
|
|
193
|
+
gl.attachShader(program, vs);
|
|
194
|
+
gl.attachShader(program, fs);
|
|
195
|
+
gl.linkProgram(program);
|
|
196
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
197
|
+
const log = gl.getProgramInfoLog(program);
|
|
198
|
+
gl.deleteProgram(program);
|
|
199
|
+
throw new Error(`Speckle program link failed: ${log ?? "(no log)"}`);
|
|
200
|
+
}
|
|
201
|
+
return program;
|
|
202
|
+
};
|
|
203
|
+
var speckle = createEffect({
|
|
204
|
+
type: "dev.remotion.effects.speckle",
|
|
205
|
+
label: "speckle()",
|
|
206
|
+
documentationLink: "https://www.remotion.dev/docs/effects/speckle",
|
|
207
|
+
calculateKey: (params) => {
|
|
208
|
+
const r = resolve(params);
|
|
209
|
+
return `speckle-${r.density}-${r.size}-${r.randomness}`;
|
|
210
|
+
},
|
|
211
|
+
implementations: {
|
|
212
|
+
webgpu: Internals.createEffectImplementation({
|
|
213
|
+
setup: (target) => setupWebGpuSinglePass(target, "speckle"),
|
|
214
|
+
apply: ({ source, width, height, params, state, gpuDevice }) => {
|
|
215
|
+
if (!gpuDevice)
|
|
216
|
+
throw new Error("A WebGPU device is required for the speckle effect");
|
|
217
|
+
const r = resolve(params);
|
|
218
|
+
const uniformData = new Float32Array([
|
|
219
|
+
width,
|
|
220
|
+
height,
|
|
221
|
+
r.density,
|
|
222
|
+
r.size,
|
|
223
|
+
r.randomness,
|
|
224
|
+
0,
|
|
225
|
+
0,
|
|
226
|
+
0
|
|
227
|
+
]);
|
|
228
|
+
applyWebGpuSinglePass({
|
|
229
|
+
state,
|
|
230
|
+
source,
|
|
231
|
+
width,
|
|
232
|
+
height,
|
|
233
|
+
device: gpuDevice,
|
|
234
|
+
shader: SPECKLE_WEBGPU_SHADER,
|
|
235
|
+
uniformData
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
cleanup: cleanupWebGpuSinglePass
|
|
239
|
+
}),
|
|
240
|
+
webgl2: Internals.createEffectImplementation({
|
|
241
|
+
setup: (target) => {
|
|
242
|
+
const gl = target.getContext("webgl2", {
|
|
243
|
+
premultipliedAlpha: true,
|
|
244
|
+
alpha: true,
|
|
245
|
+
preserveDrawingBuffer: true
|
|
246
|
+
});
|
|
247
|
+
if (!gl) {
|
|
248
|
+
throw createWebGL2ContextError("speckle effect");
|
|
249
|
+
}
|
|
250
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
251
|
+
const vs = compileShader(gl, gl.VERTEX_SHADER, SPECKLE_VS);
|
|
252
|
+
const fs = compileShader(gl, gl.FRAGMENT_SHADER, SPECKLE_FS);
|
|
253
|
+
const program = linkProgram(gl, vs, fs);
|
|
254
|
+
gl.deleteShader(vs);
|
|
255
|
+
gl.deleteShader(fs);
|
|
256
|
+
const vao = gl.createVertexArray();
|
|
257
|
+
if (!vao) {
|
|
258
|
+
throw new Error("Failed to create WebGL vertex array");
|
|
259
|
+
}
|
|
260
|
+
gl.bindVertexArray(vao);
|
|
261
|
+
const data = new Float32Array([
|
|
262
|
+
-1,
|
|
263
|
+
-1,
|
|
264
|
+
0,
|
|
265
|
+
0,
|
|
266
|
+
1,
|
|
267
|
+
-1,
|
|
268
|
+
1,
|
|
269
|
+
0,
|
|
270
|
+
-1,
|
|
271
|
+
1,
|
|
272
|
+
0,
|
|
273
|
+
1,
|
|
274
|
+
1,
|
|
275
|
+
1,
|
|
276
|
+
1,
|
|
277
|
+
1
|
|
278
|
+
]);
|
|
279
|
+
const vbo = gl.createBuffer();
|
|
280
|
+
if (!vbo) {
|
|
281
|
+
throw new Error("Failed to create WebGL buffer");
|
|
282
|
+
}
|
|
283
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
284
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
285
|
+
const aPos = gl.getAttribLocation(program, "aPos");
|
|
286
|
+
const aUv = gl.getAttribLocation(program, "aUv");
|
|
287
|
+
gl.enableVertexAttribArray(aPos);
|
|
288
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
|
|
289
|
+
gl.enableVertexAttribArray(aUv);
|
|
290
|
+
gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
|
|
291
|
+
gl.bindVertexArray(null);
|
|
292
|
+
const texture = gl.createTexture();
|
|
293
|
+
if (!texture) {
|
|
294
|
+
throw new Error("Failed to create WebGL texture");
|
|
295
|
+
}
|
|
296
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
297
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
298
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
299
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
300
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
301
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
302
|
+
return {
|
|
303
|
+
gl,
|
|
304
|
+
program,
|
|
305
|
+
vao,
|
|
306
|
+
vbo,
|
|
307
|
+
texture,
|
|
308
|
+
uSource: gl.getUniformLocation(program, "uSource"),
|
|
309
|
+
uResolution: gl.getUniformLocation(program, "uResolution"),
|
|
310
|
+
uDensity: gl.getUniformLocation(program, "uDensity"),
|
|
311
|
+
uSize: gl.getUniformLocation(program, "uSize"),
|
|
312
|
+
uRandomness: gl.getUniformLocation(program, "uRandomness")
|
|
313
|
+
};
|
|
314
|
+
},
|
|
315
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => {
|
|
316
|
+
const r = resolve(params);
|
|
317
|
+
const { gl, program, vao, texture } = state;
|
|
318
|
+
gl.viewport(0, 0, width, height);
|
|
319
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
320
|
+
gl.clearColor(0, 0, 0, 0);
|
|
321
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
322
|
+
gl.useProgram(program);
|
|
323
|
+
gl.bindVertexArray(vao);
|
|
324
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
325
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
326
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
|
|
327
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
328
|
+
if (state.uSource)
|
|
329
|
+
gl.uniform1i(state.uSource, 0);
|
|
330
|
+
if (state.uResolution)
|
|
331
|
+
gl.uniform2f(state.uResolution, width, height);
|
|
332
|
+
if (state.uDensity)
|
|
333
|
+
gl.uniform1f(state.uDensity, r.density);
|
|
334
|
+
if (state.uSize)
|
|
335
|
+
gl.uniform1f(state.uSize, r.size);
|
|
336
|
+
if (state.uRandomness)
|
|
337
|
+
gl.uniform1f(state.uRandomness, r.randomness);
|
|
338
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
339
|
+
gl.bindVertexArray(null);
|
|
340
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
341
|
+
gl.useProgram(null);
|
|
342
|
+
},
|
|
343
|
+
cleanup: ({ gl, program, vao, vbo, texture }) => {
|
|
344
|
+
gl.deleteBuffer(vbo);
|
|
345
|
+
gl.deleteProgram(program);
|
|
346
|
+
gl.deleteVertexArray(vao);
|
|
347
|
+
gl.deleteTexture(texture);
|
|
348
|
+
}
|
|
349
|
+
})
|
|
350
|
+
},
|
|
351
|
+
schema: speckleSchema,
|
|
352
|
+
validateParams: validateSpeckleParams
|
|
353
|
+
});
|
|
354
|
+
export {
|
|
355
|
+
speckle
|
|
356
|
+
};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import {
|
|
2
|
+
setupWebGlProjection,
|
|
3
|
+
applyWebGlProjection,
|
|
4
|
+
cleanupWebGlProjection,
|
|
5
|
+
cleanupWebGpuProjection,
|
|
6
|
+
setupWebGpuProjection,
|
|
7
|
+
applyWebGpuProjection
|
|
8
|
+
} from "./index-vp56k1gj.mjs";
|
|
9
|
+
import {
|
|
10
|
+
assertOptionalFiniteNumber,
|
|
11
|
+
validateUnitInterval
|
|
12
|
+
} from "./index-wxhvgv2s.mjs";
|
|
13
|
+
import {
|
|
14
|
+
assertEffectParamsObject
|
|
15
|
+
} from "./index-4fvp93ps.mjs";
|
|
16
|
+
|
|
17
|
+
// src/sphere/index.ts
|
|
18
|
+
import { Internals } from "remotion";
|
|
19
|
+
|
|
20
|
+
// src/sphere/shader.ts
|
|
21
|
+
var SPHERE_SHADER = `
|
|
22
|
+
struct Params {
|
|
23
|
+
resolution: vec2f,
|
|
24
|
+
center: vec2f,
|
|
25
|
+
radius: f32,
|
|
26
|
+
padding: f32,
|
|
27
|
+
shading: f32,
|
|
28
|
+
faces: f32,
|
|
29
|
+
rotation: vec4f,
|
|
30
|
+
}
|
|
31
|
+
@group(0) @binding(0) var source: texture_2d<f32>;
|
|
32
|
+
@group(0) @binding(1) var sourceSampler: sampler;
|
|
33
|
+
@group(0) @binding(2) var<uniform> params: Params;
|
|
34
|
+
|
|
35
|
+
@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {
|
|
36
|
+
let positions = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
|
|
37
|
+
return vec4f(positions[index], 0, 1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fn sampleFace(normal: vec3f, inverse: mat3x3f) -> vec4f {
|
|
41
|
+
let local = inverse * normal;
|
|
42
|
+
// Longitude wraps at the seam; latitude spans the complete image height.
|
|
43
|
+
let uv = vec2f(fract(atan2(local.x, local.z) / 6.28318530718 + 0.5), asin(clamp(local.y, -1.0, 1.0)) / 3.14159265359 + 0.5);
|
|
44
|
+
let color = textureSampleLevel(source, sourceSampler, uv, 0);
|
|
45
|
+
let shade = mix(1.0, abs(normal.z), params.shading);
|
|
46
|
+
return vec4f(color.rgb * shade, color.a);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
50
|
+
let p = (position.xy - params.center) / params.radius;
|
|
51
|
+
let distanceSquared = dot(p, p);
|
|
52
|
+
let coverage = 1.0 - smoothstep(1.0 - fwidth(distanceSquared), 1.0, distanceSquared);
|
|
53
|
+
if (distanceSquared >= 1.0) { return vec4f(0); }
|
|
54
|
+
let z = sqrt(1.0 - distanceSquared);
|
|
55
|
+
let s = sin(params.rotation.xyz);
|
|
56
|
+
let c = cos(params.rotation.xyz);
|
|
57
|
+
let rx = mat3x3f(vec3f(1, 0, 0), vec3f(0, c.x, s.x), vec3f(0, -s.x, c.x));
|
|
58
|
+
let ry = mat3x3f(vec3f(c.y, 0, -s.y), vec3f(0, 1, 0), vec3f(s.y, 0, c.y));
|
|
59
|
+
let rz = mat3x3f(vec3f(c.z, s.z, 0), vec3f(-s.z, c.z, 0), vec3f(0, 0, 1));
|
|
60
|
+
let inverse = transpose(rz * ry * rx);
|
|
61
|
+
let front = sampleFace(vec3f(p, z), inverse);
|
|
62
|
+
let back = sampleFace(vec3f(p, -z), inverse);
|
|
63
|
+
if (params.faces == 1) { return front * coverage; }
|
|
64
|
+
if (params.faces == 2) { return back * coverage; }
|
|
65
|
+
return (front + back * (1.0 - front.a)) * coverage;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
// src/sphere/webgl-shader.ts
|
|
70
|
+
var SPHERE_WEBGL_SHADER = `#version 300 es
|
|
71
|
+
precision highp float;
|
|
72
|
+
uniform sampler2D uSource;
|
|
73
|
+
uniform vec4 uParams[3];
|
|
74
|
+
out vec4 fragColor;
|
|
75
|
+
vec4 sampleFace(vec3 normal, mat3 inverseRotation) {
|
|
76
|
+
vec3 local = inverseRotation * normal;
|
|
77
|
+
// Longitude wraps at the seam; latitude spans the complete image height.
|
|
78
|
+
vec2 uv = vec2(fract(atan(local.x, local.z) / 6.28318530718 + 0.5), asin(clamp(local.y, -1.0, 1.0)) / 3.14159265359 + 0.5);
|
|
79
|
+
vec4 color = textureLod(uSource, vec2(uv.x, 1.0 - uv.y), 0.0);
|
|
80
|
+
float shade = mix(1.0, abs(normal.z), uParams[1].z);
|
|
81
|
+
return vec4(color.rgb * shade, color.a);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
vec4 project(vec2 position) {
|
|
85
|
+
vec2 p = (position - uParams[0].zw) / uParams[1].x;
|
|
86
|
+
float distanceSquared = dot(p, p);
|
|
87
|
+
float coverage = 1.0 - smoothstep(1.0 - fwidth(distanceSquared), 1.0, distanceSquared);
|
|
88
|
+
if (distanceSquared >= 1.0) { return vec4(0); }
|
|
89
|
+
float z = sqrt(1.0 - distanceSquared);
|
|
90
|
+
vec3 s = sin(uParams[2].xyz);
|
|
91
|
+
vec3 c = cos(uParams[2].xyz);
|
|
92
|
+
mat3 rx = mat3(vec3(1, 0, 0), vec3(0, c.x, s.x), vec3(0, -s.x, c.x));
|
|
93
|
+
mat3 ry = mat3(vec3(c.y, 0, -s.y), vec3(0, 1, 0), vec3(s.y, 0, c.y));
|
|
94
|
+
mat3 rz = mat3(vec3(c.z, s.z, 0), vec3(-s.z, c.z, 0), vec3(0, 0, 1));
|
|
95
|
+
mat3 inverseRotation = transpose(rz * ry * rx);
|
|
96
|
+
vec4 front = sampleFace(vec3(p, z), inverseRotation);
|
|
97
|
+
vec4 back = sampleFace(vec3(p, -z), inverseRotation);
|
|
98
|
+
if (uParams[1].w == 1.0) { return front * coverage; }
|
|
99
|
+
if (uParams[1].w == 2.0) { return back * coverage; }
|
|
100
|
+
return (front + back * (1.0 - front.a)) * coverage;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void main() { fragColor = project(vec2(gl_FragCoord.x, uParams[0].y - gl_FragCoord.y)); }
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
// src/sphere/index.ts
|
|
107
|
+
var DEFAULT_RADIUS = 250;
|
|
108
|
+
var DEFAULT_ROTATION = 0;
|
|
109
|
+
var DEFAULT_POSITION = [0.5, 0.5];
|
|
110
|
+
var DEFAULT_RENDER = "both";
|
|
111
|
+
var DEFAULT_SHADING = 0.35;
|
|
112
|
+
var sphereSchema = {
|
|
113
|
+
radius: {
|
|
114
|
+
type: "number",
|
|
115
|
+
min: 1,
|
|
116
|
+
max: 1000,
|
|
117
|
+
step: 1,
|
|
118
|
+
default: DEFAULT_RADIUS,
|
|
119
|
+
description: "Radius",
|
|
120
|
+
hiddenFromList: false
|
|
121
|
+
},
|
|
122
|
+
rotationX: {
|
|
123
|
+
type: "rotation-degrees",
|
|
124
|
+
default: DEFAULT_ROTATION,
|
|
125
|
+
description: "X rotation"
|
|
126
|
+
},
|
|
127
|
+
rotationY: {
|
|
128
|
+
type: "rotation-degrees",
|
|
129
|
+
default: DEFAULT_ROTATION,
|
|
130
|
+
description: "Y rotation"
|
|
131
|
+
},
|
|
132
|
+
rotationZ: {
|
|
133
|
+
type: "rotation-degrees",
|
|
134
|
+
default: DEFAULT_ROTATION,
|
|
135
|
+
description: "Z rotation"
|
|
136
|
+
},
|
|
137
|
+
position: {
|
|
138
|
+
type: "uv-coordinate",
|
|
139
|
+
default: DEFAULT_POSITION,
|
|
140
|
+
description: "Position"
|
|
141
|
+
},
|
|
142
|
+
render: {
|
|
143
|
+
type: "enum",
|
|
144
|
+
variants: { both: {}, front: {}, back: {} },
|
|
145
|
+
default: DEFAULT_RENDER,
|
|
146
|
+
description: "Faces"
|
|
147
|
+
},
|
|
148
|
+
shading: {
|
|
149
|
+
type: "number",
|
|
150
|
+
min: 0,
|
|
151
|
+
max: 1,
|
|
152
|
+
step: 0.01,
|
|
153
|
+
default: DEFAULT_SHADING,
|
|
154
|
+
description: "Shading",
|
|
155
|
+
hiddenFromList: false
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var resolve = (params) => ({
|
|
159
|
+
radius: params.radius ?? DEFAULT_RADIUS,
|
|
160
|
+
rotationX: params.rotationX ?? DEFAULT_ROTATION,
|
|
161
|
+
rotationY: params.rotationY ?? DEFAULT_ROTATION,
|
|
162
|
+
rotationZ: params.rotationZ ?? DEFAULT_ROTATION,
|
|
163
|
+
position: params.position ?? DEFAULT_POSITION,
|
|
164
|
+
render: params.render ?? DEFAULT_RENDER,
|
|
165
|
+
shading: params.shading ?? DEFAULT_SHADING
|
|
166
|
+
});
|
|
167
|
+
var getUniformData = (params, width, height) => {
|
|
168
|
+
const r = resolve(params);
|
|
169
|
+
const radians = Math.PI / 180;
|
|
170
|
+
return new Float32Array([
|
|
171
|
+
width,
|
|
172
|
+
height,
|
|
173
|
+
r.position[0] * width,
|
|
174
|
+
r.position[1] * height,
|
|
175
|
+
r.radius,
|
|
176
|
+
0,
|
|
177
|
+
r.shading,
|
|
178
|
+
r.render === "front" ? 1 : r.render === "back" ? 2 : 0,
|
|
179
|
+
r.rotationX % 360 * radians,
|
|
180
|
+
r.rotationY % 360 * radians,
|
|
181
|
+
r.rotationZ % 360 * radians,
|
|
182
|
+
0
|
|
183
|
+
]);
|
|
184
|
+
};
|
|
185
|
+
var sphere = Internals.createEffect({
|
|
186
|
+
type: "remotion/sphere",
|
|
187
|
+
label: "sphere()",
|
|
188
|
+
documentationLink: "https://www.remotion.dev/docs/effects/sphere",
|
|
189
|
+
schema: sphereSchema,
|
|
190
|
+
validateParams: (params) => {
|
|
191
|
+
assertEffectParamsObject(params, "Sphere");
|
|
192
|
+
for (const key of [
|
|
193
|
+
"radius",
|
|
194
|
+
"rotationX",
|
|
195
|
+
"rotationY",
|
|
196
|
+
"rotationZ",
|
|
197
|
+
"shading"
|
|
198
|
+
]) {
|
|
199
|
+
assertOptionalFiniteNumber(params[key], key);
|
|
200
|
+
}
|
|
201
|
+
const r = resolve(params);
|
|
202
|
+
if (r.radius <= 0) {
|
|
203
|
+
throw new TypeError('"radius" must be greater than 0');
|
|
204
|
+
}
|
|
205
|
+
validateUnitInterval(r.shading, "shading");
|
|
206
|
+
if (params.position !== undefined && (!Array.isArray(params.position) || params.position.length !== 2 || !Number.isFinite(params.position[0]) || !Number.isFinite(params.position[1]))) {
|
|
207
|
+
throw new TypeError('"position" must contain two finite numbers');
|
|
208
|
+
}
|
|
209
|
+
if (params.render !== undefined && params.render !== "both" && params.render !== "front" && params.render !== "back") {
|
|
210
|
+
throw new TypeError('"render" must be "both", "front", or "back"');
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
calculateKey: (params) => {
|
|
214
|
+
const r = resolve(params);
|
|
215
|
+
return `sphere-${r.radius}-${r.rotationX}-${r.rotationY}-${r.rotationZ}-${r.position.join(",")}-${r.render}-${r.shading}`;
|
|
216
|
+
},
|
|
217
|
+
implementations: {
|
|
218
|
+
webgpu: Internals.createEffectImplementation({
|
|
219
|
+
setup: (target) => setupWebGpuProjection(target, "sphere"),
|
|
220
|
+
apply: ({ source, width, height, params, state, gpuDevice }) => {
|
|
221
|
+
if (!gpuDevice) {
|
|
222
|
+
throw new Error("A WebGPU device is required for the sphere effect");
|
|
223
|
+
}
|
|
224
|
+
applyWebGpuProjection({
|
|
225
|
+
source,
|
|
226
|
+
width,
|
|
227
|
+
height,
|
|
228
|
+
state,
|
|
229
|
+
device: gpuDevice,
|
|
230
|
+
shader: SPHERE_SHADER,
|
|
231
|
+
uniformData: getUniformData(params, width, height)
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
cleanup: cleanupWebGpuProjection
|
|
235
|
+
}),
|
|
236
|
+
webgl2: Internals.createEffectImplementation({
|
|
237
|
+
setup: (target) => setupWebGlProjection(target, SPHERE_WEBGL_SHADER),
|
|
238
|
+
apply: ({ source, width, height, params, state, flipSourceY }) => applyWebGlProjection({
|
|
239
|
+
source,
|
|
240
|
+
width,
|
|
241
|
+
height,
|
|
242
|
+
state,
|
|
243
|
+
flipSourceY,
|
|
244
|
+
uniformData: getUniformData(params, width, height)
|
|
245
|
+
}),
|
|
246
|
+
cleanup: cleanupWebGlProjection
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
export {
|
|
251
|
+
sphere
|
|
252
|
+
};
|