import type { EffectDefinition } from "@/effects/types"; import { GAUSSIAN_BLUR_SHADER, intensityToSigma } from "./blur"; const MAX_SINGLE_PASS_SIGMA = 10; const MIN_SIGMA = 0.001; function parseNumericParam({ effectParams, key, }: { effectParams: Record; key: string; }): number { const raw = effectParams[key]; return typeof raw === "number" ? raw : Number.parseFloat(String(raw)); } export const motionBlurEffectDefinition: EffectDefinition = { type: "motion-blur", name: "Motion Blur", keywords: ["motion blur", "smear", "directional", "speed", "streak"], category: "lens", params: [ { key: "amount", label: "Amount", type: "number", default: 40, min: 0, max: 100, step: 1, }, { key: "angle", label: "Angle", type: "number", default: 0, min: -180, max: 180, step: 1, }, ], renderer: { passes: [], buildPasses: ({ effectParams, width }) => { const sigma = intensityToSigma({ intensity: parseNumericParam({ effectParams, key: "amount" }), resolution: width, reference: 1920, }); if (sigma < MIN_SIGMA) return []; const angleRad = (parseNumericParam({ effectParams, key: "angle" }) * Math.PI) / 180; return [ { shader: GAUSSIAN_BLUR_SHADER, uniforms: { u_sigma: Math.min(sigma, MAX_SINGLE_PASS_SIGMA), u_step: Math.max(1, sigma / MAX_SINGLE_PASS_SIGMA), u_direction: [Math.cos(angleRad), Math.sin(angleRad)], }, }, ]; }, }, };