summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/effects/definitions
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-01 01:32:09 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-01 01:32:09 +0100
commit5e7c27f542e94ffee5d2106ce318b6f43cc7e738 (patch)
treeb33c3370c01b9b2ee685f1039543bc02f8764f7b /apps/web/src/lib/effects/definitions
parent744419469da403be57d30b5b19f6b43246caa57d (diff)
parent354f4dec67ef7eb39d34fca941ca34025a68136b (diff)
downloadopencut-5e7c27f542e94ffee5d2106ce318b6f43cc7e738.tar.gz
Merge branch 'dev' into ripple-editing
Diffstat (limited to 'apps/web/src/lib/effects/definitions')
-rw-r--r--apps/web/src/lib/effects/definitions/blur.frag.glsl25
-rw-r--r--apps/web/src/lib/effects/definitions/blur.ts50
-rw-r--r--apps/web/src/lib/effects/definitions/index.ts13
3 files changed, 88 insertions, 0 deletions
diff --git a/apps/web/src/lib/effects/definitions/blur.frag.glsl b/apps/web/src/lib/effects/definitions/blur.frag.glsl
new file mode 100644
index 00000000..2c015725
--- /dev/null
+++ b/apps/web/src/lib/effects/definitions/blur.frag.glsl
@@ -0,0 +1,25 @@
+precision mediump float;
+
+uniform sampler2D u_texture;
+uniform vec2 u_resolution;
+uniform float u_sigma;
+uniform vec2 u_direction;
+
+varying vec2 v_texCoord;
+
+void main() {
+ vec2 texelSize = 1.0 / u_resolution;
+
+ vec4 color = vec4(0.0);
+ float totalWeight = 0.0;
+
+ // step=1 texel — scaling step size instead causes discrete ghosting artifacts
+ for (int i = -30; i <= 30; i++) {
+ float fi = float(i);
+ float weight = exp(-(fi * fi) / (2.0 * u_sigma * u_sigma));
+ color += texture2D(u_texture, v_texCoord + texelSize * u_direction * fi) * weight;
+ totalWeight += weight;
+ }
+
+ gl_FragColor = color / totalWeight;
+}
diff --git a/apps/web/src/lib/effects/definitions/blur.ts b/apps/web/src/lib/effects/definitions/blur.ts
new file mode 100644
index 00000000..3a8f691a
--- /dev/null
+++ b/apps/web/src/lib/effects/definitions/blur.ts
@@ -0,0 +1,50 @@
+import type { EffectDefinition } from "@/types/effects";
+import blurFragmentShader from "./blur.frag.glsl";
+
+export const blurEffectDefinition: EffectDefinition = {
+ type: "blur",
+ name: "Blur",
+ keywords: ["blur", "soft", "defocus"],
+ params: [
+ {
+ key: "intensity",
+ label: "Intensity",
+ type: "number",
+ default: 15,
+ min: 0,
+ max: 100,
+ step: 1,
+ },
+ ],
+ renderer: {
+ type: "webgl",
+ passes: [
+ {
+ fragmentShader: blurFragmentShader,
+ uniforms: ({ effectParams }) => {
+ const intensity =
+ typeof effectParams.intensity === "number"
+ ? effectParams.intensity
+ : Number.parseFloat(String(effectParams.intensity));
+ return {
+ u_sigma: Math.max(intensity / 5, 0.001),
+ u_direction: [1, 0],
+ };
+ },
+ },
+ {
+ fragmentShader: blurFragmentShader,
+ uniforms: ({ effectParams }) => {
+ const intensity =
+ typeof effectParams.intensity === "number"
+ ? effectParams.intensity
+ : Number.parseFloat(String(effectParams.intensity));
+ return {
+ u_sigma: Math.max(intensity / 5, 0.001),
+ u_direction: [0, 1],
+ };
+ },
+ },
+ ],
+ },
+};
diff --git a/apps/web/src/lib/effects/definitions/index.ts b/apps/web/src/lib/effects/definitions/index.ts
new file mode 100644
index 00000000..1742b1d7
--- /dev/null
+++ b/apps/web/src/lib/effects/definitions/index.ts
@@ -0,0 +1,13 @@
+import { hasEffect, registerEffect } from "../registry";
+import { blurEffectDefinition } from "./blur";
+
+const defaultEffects = [blurEffectDefinition];
+
+export function registerDefaultEffects(): void {
+ for (const definition of defaultEffects) {
+ if (hasEffect({ effectType: definition.type })) {
+ continue;
+ }
+ registerEffect({ definition });
+ }
+}