{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "shader-lens-blur", "type": "registry:ui", "description": "WebGL shader component with lens blur effects and mouse interaction", "dependencies": [ "motion", "three", "jotai" ], "files": [ { "path": "registry/default/ui/shader-lens-blur.tsx", "content": "\"use client\"\n\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { atom, useAtom } from \"jotai\"\nimport { motion } from \"motion/react\"\nimport { useTheme } from \"next-themes\"\nimport * as THREE from \"three\"\n\nconst fragmentShader = `\nvarying vec2 v_texcoord;\n\nuniform vec2 u_mouse;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\nuniform float u_time;\nuniform vec3 u_color1;\nuniform vec3 u_color2;\nuniform vec3 u_color3;\nuniform vec3 u_color4;\nuniform float u_hoverStrength;\nuniform bool u_invertMouse;\nuniform bool u_isDarkMode;\n\n#define PI 3.1415926535897932384626433832795\n#define TWO_PI 6.2831853071795864769252867665590\n\nvec2 coord(in vec2 p) {\n p = p / u_resolution.xy;\n if (u_resolution.x > u_resolution.y) {\n p.x *= u_resolution.x / u_resolution.y;\n p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0;\n } else {\n p.y *= u_resolution.y / u_resolution.x;\n p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0;\n }\n p -= 0.5;\n p *= vec2(-1.0, 1.0);\n return p;\n}\n\n#define st0 coord(gl_FragCoord.xy)\n#define mx coord(u_mouse * u_pixelRatio)\n\nfloat sdRoundRect(vec2 p, vec2 b, float r) {\n vec2 d = abs(p - 0.5) * 4.2 - b + vec2(r);\n return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - r;\n}\n\nfloat sdCircle(in vec2 st, in vec2 center) {\n return length(st - center) * 2.0;\n}\n\nfloat sdPoly(in vec2 p, in float w, in int sides) {\n float a = atan(p.x, p.y) + PI;\n float r = TWO_PI / float(sides);\n float d = cos(floor(0.5 + a / r) * r - a) * length(max(abs(p) * 1.0, 0.0));\n return d * 2.0 - w;\n}\n\nfloat aastep(float threshold, float value) {\n float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;\n return smoothstep(threshold - afwidth, threshold + afwidth, value);\n}\n\nfloat fill(float x, float size, float edge) {\n return 1.0 - smoothstep(size - edge, size + edge, x);\n}\n\nfloat stroke(float x, float size, float w, float edge) {\n float d = smoothstep(size - edge, size + edge, x + w * 0.5) - smoothstep(size - edge, size + edge, x - w * 0.5);\n return clamp(d, 0.0, 1.0);\n}\n\nvoid main() {\n vec2 st = st0 + 0.5;\n vec2 posMouse = mx + 0.5;\n \n float size = 1.2 + sin(u_time) * 0.1;\n float roundness = 0.4 + sin(u_time * 0.5) * 0.1;\n float borderSize = 0.05 + sin(u_time * 0.7) * 0.02;\n float circleSize = 0.3 + sin(u_time * 0.8) * 0.05;\n float circleEdge = 0.5 + sin(u_time * 0.6) * 0.1;\n \n float sdfCircle = fill(\n sdCircle(st, posMouse),\n circleSize,\n circleEdge\n );\n \n float sdf;\n if (VAR == 0) {\n sdf = sdRoundRect(st, vec2(size), roundness);\n sdf = stroke(sdf, 0.0, borderSize, sdfCircle) * 4.0;\n } else if (VAR == 1) {\n sdf = sdCircle(st, vec2(0.5));\n sdf = fill(sdf, 0.6, sdfCircle) * 1.2;\n } else if (VAR == 2) {\n sdf = sdCircle(st, vec2(0.5));\n sdf = stroke(sdf, 0.58, 0.02, sdfCircle) * 4.0;\n } else if (VAR == 3) {\n sdf = sdPoly(st - vec2(0.5, 0.45), 0.3, 3);\n sdf = fill(sdf, 0.05, sdfCircle) * 1.4;\n }\n \n vec3 gradient = mix(\n mix(u_color1, u_color2, 0.5 + 0.5 * cos(u_time + st.x + 0.0)),\n mix(u_color3, u_color4, 0.5 + 0.5 * cos(u_time + st.y + 2.0)),\n 0.5 + 0.5 * cos(u_time + st.x + st.y + 4.0)\n );\n \n vec3 shapeColor = sdf * gradient;\n \n float mouseEffect = u_invertMouse ? 1.0 - sdfCircle : sdfCircle;\n shapeColor = mix(shapeColor, vec3(1.0) - shapeColor, u_hoverStrength * mouseEffect);\n \n if (u_isDarkMode) {\n shapeColor = mix(shapeColor, vec3(1.0), 0.2);\n } else {\n shapeColor = mix(shapeColor, vec3(0.0), 0.1);\n }\n \n gl_FragColor = vec4(shapeColor, sdf);\n}\n`\n\ninterface ShaderConfig {\n variation: number\n color1: string\n color2: string\n color3: string\n color4: string\n enableHover: boolean\n invertMouse: boolean\n width: string\n height: string\n}\n\nconst initialState: ShaderConfig = {\n variation: 3,\n color1: \"#D5F981\",\n color2: \"#A1BBE7\",\n color3: \"#F2BAE2\",\n color4: \"#68E8FA\",\n enableHover: true,\n invertMouse: true,\n width: \"100%\",\n height: \"400px\",\n}\n\nexport const configAtom = atom(initialState)\n\nexport function ShaderLensBlur() {\n const [config] = useAtom(configAtom)\n const containerRef = useRef(null)\n const canvasRef = useRef(null)\n const rendererRef = useRef(null)\n const sceneRef = useRef(null)\n const cameraRef = useRef(null)\n const materialRef = useRef(null)\n const rafRef = useRef(null)\n const pixelRatioRef = useRef(1)\n const [isInteracting, setIsInteracting] = useState(false)\n const { theme } = useTheme()\n\n const updateSize = useCallback(() => {\n if (\n !containerRef.current ||\n !canvasRef.current ||\n !rendererRef.current ||\n !cameraRef.current ||\n !materialRef.current\n )\n return\n\n const { clientWidth: w, clientHeight: h } = containerRef.current\n const aspect = w / h\n\n cameraRef.current.left = -aspect\n cameraRef.current.right = aspect\n cameraRef.current.top = 1\n cameraRef.current.bottom = -1\n cameraRef.current.updateProjectionMatrix()\n\n const pixelRatio = Math.min(window.devicePixelRatio || 1, 2)\n pixelRatioRef.current = pixelRatio\n\n rendererRef.current.setPixelRatio(pixelRatio)\n rendererRef.current.setSize(w, h)\n\n const drawingBufferSize = rendererRef.current.getDrawingBufferSize(\n new THREE.Vector2()\n )\n materialRef.current.uniforms.u_resolution.value.copy(drawingBufferSize)\n materialRef.current.uniforms.u_pixelRatio.value = pixelRatio\n }, [])\n\n const updateMousePosition = useCallback(\n (x: number, y: number) => {\n if (!containerRef.current || !materialRef.current) return\n const rect = containerRef.current.getBoundingClientRect()\n const mouseX = x - rect.left\n const mouseY = y - rect.top\n if (isInteracting || config.enableHover) {\n materialRef.current.uniforms.u_mouse.value.set(\n mouseX,\n rect.height - mouseY\n )\n }\n },\n [isInteracting, config.enableHover]\n )\n\n const animate = useCallback(\n (time: number) => {\n if (\n !rendererRef.current ||\n !sceneRef.current ||\n !cameraRef.current ||\n !materialRef.current\n )\n return\n\n const pixelRatio = Math.min(window.devicePixelRatio || 1, 2)\n if (pixelRatio !== pixelRatioRef.current) {\n updateSize()\n }\n\n materialRef.current.uniforms.u_time.value = time * 0.001\n materialRef.current.uniforms.u_hoverStrength.value =\n isInteracting || config.enableHover ? 0.3 : 0\n\n rendererRef.current.render(sceneRef.current, cameraRef.current)\n rafRef.current = requestAnimationFrame(animate)\n },\n [config.enableHover, isInteracting, updateSize]\n )\n\n useEffect(() => {\n if (!containerRef.current || !canvasRef.current) return\n\n const scene = new THREE.Scene()\n sceneRef.current = scene\n\n const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 1000)\n camera.position.z = 1\n cameraRef.current = camera\n\n const renderer = new THREE.WebGLRenderer({\n canvas: canvasRef.current,\n antialias: true,\n alpha: true,\n })\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))\n renderer.setClearColor(0x000000, 0)\n rendererRef.current = renderer\n\n const geometry = new THREE.PlaneGeometry(2, 2)\n const material = new THREE.ShaderMaterial({\n vertexShader: `\n varying vec2 v_texcoord;\n void main() {\n gl_Position = vec4(position, 1.0);\n v_texcoord = uv;\n }\n `,\n fragmentShader,\n uniforms: {\n u_mouse: { value: new THREE.Vector2() },\n u_resolution: { value: new THREE.Vector2() },\n u_pixelRatio: { value: Math.min(window.devicePixelRatio, 2) },\n u_time: { value: 0 },\n u_color1: { value: new THREE.Color(config.color1) },\n u_color2: { value: new THREE.Color(config.color2) },\n u_color3: { value: new THREE.Color(config.color3) },\n u_color4: { value: new THREE.Color(config.color4) },\n u_hoverStrength: { value: 0 },\n u_invertMouse: { value: config.invertMouse },\n u_isDarkMode: { value: theme === \"dark\" },\n },\n defines: {\n VAR: config.variation,\n },\n transparent: true,\n blending: THREE.NormalBlending,\n })\n materialRef.current = material\n\n const mesh = new THREE.Mesh(geometry, material)\n scene.add(mesh)\n\n updateSize()\n rafRef.current = requestAnimationFrame(animate)\n\n const resizeObserver = new ResizeObserver(updateSize)\n resizeObserver.observe(containerRef.current)\n\n return () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n if (rendererRef.current) rendererRef.current.dispose()\n if (containerRef.current) resizeObserver.unobserve(containerRef.current)\n }\n }, [config, updateSize, animate, theme])\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const handlePointerMove = (event: PointerEvent) =>\n updateMousePosition(event.clientX, event.clientY)\n const handleTouchMove = (event: TouchEvent) => {\n if (event.touches.length > 0) {\n const touch = event.touches[0]\n updateMousePosition(touch.clientX, touch.clientY)\n }\n }\n const handlePointerDown = () => setIsInteracting(true)\n const handlePointerUp = () => setIsInteracting(false)\n const handleTouchStart = () => setIsInteracting(true)\n const handleTouchEnd = () => setIsInteracting(false)\n\n container.addEventListener(\"pointermove\", handlePointerMove)\n container.addEventListener(\"touchmove\", handleTouchMove)\n container.addEventListener(\"pointerdown\", handlePointerDown)\n container.addEventListener(\"pointerup\", handlePointerUp)\n container.addEventListener(\"touchstart\", handleTouchStart)\n container.addEventListener(\"touchend\", handleTouchEnd)\n\n return () => {\n container.removeEventListener(\"pointermove\", handlePointerMove)\n container.removeEventListener(\"touchmove\", handleTouchMove)\n container.removeEventListener(\"pointerdown\", handlePointerDown)\n container.removeEventListener(\"pointerup\", handlePointerUp)\n container.removeEventListener(\"touchstart\", handleTouchStart)\n container.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [updateMousePosition])\n\n useEffect(() => {\n if (materialRef.current) {\n materialRef.current.uniforms.u_color1.value.set(config.color1)\n materialRef.current.uniforms.u_color2.value.set(config.color2)\n materialRef.current.uniforms.u_color3.value.set(config.color3)\n materialRef.current.uniforms.u_color4.value.set(config.color4)\n materialRef.current.uniforms.u_invertMouse.value = config.invertMouse\n materialRef.current.uniforms.u_isDarkMode.value = theme === \"dark\"\n materialRef.current.defines.VAR = config.variation\n materialRef.current.needsUpdate = true\n }\n }, [config, theme])\n\n return (\n \n \n \n {config.enableHover\n ? `${\n config.invertMouse ? \"Inverted mouse\" : \"Normal mouse\"\n } interaction`\n : \"Interact with the animation\"}{\" \"}\n using mouse or touch\n \n \n )\n}\n\nexport default ShaderLensBlur\n// \"use client\"\n\n// // npm install jotai three\n// import React, { useCallback, useEffect, useRef, useState } from \"react\"\n// import { motion } from \"motion/react\"\n// import { atom, useAtom } from \"jotai\"\n// import * as THREE from \"three\"\n\n// const fragmentShader = `\n// varying vec2 v_texcoord;\n\n// uniform vec2 u_mouse;\n// uniform vec2 u_resolution;\n// uniform float u_pixelRatio;\n// uniform float u_time;\n// uniform vec3 u_color1;\n// uniform vec3 u_color2;\n// uniform vec3 u_color3;\n// uniform vec3 u_color4;\n// uniform float u_hoverStrength;\n// uniform bool u_invertMouse;\n\n// #define PI 3.1415926535897932384626433832795\n// #define TWO_PI 6.2831853071795864769252867665590\n\n// vec2 coord(in vec2 p) {\n// p = p / u_resolution.xy;\n// if (u_resolution.x > u_resolution.y) {\n// p.x *= u_resolution.x / u_resolution.y;\n// p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0;\n// } else {\n// p.y *= u_resolution.y / u_resolution.x;\n// p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0;\n// }\n// p -= 0.5;\n// p *= vec2(-1.0, 1.0);\n// return p;\n// }\n\n// #define st0 coord(gl_FragCoord.xy)\n// #define mx coord(u_mouse)\n\n// float sdRoundRect(vec2 p, vec2 b, float r) {\n// vec2 d = abs(p - 0.5) * 4.2 - b + vec2(r);\n// return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - r;\n// }\n\n// float sdCircle(in vec2 st, in vec2 center) {\n// return length(st - center) * 2.0;\n// }\n\n// float sdPoly(in vec2 p, in float w, in int sides) {\n// float a = atan(p.x, p.y) + PI;\n// float r = TWO_PI / float(sides);\n// float d = cos(floor(0.5 + a / r) * r - a) * length(max(abs(p) * 1.0, 0.0));\n// return d * 2.0 - w;\n// }\n\n// float aastep(float threshold, float value) {\n// float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;\n// return smoothstep(threshold - afwidth, threshold + afwidth, value);\n// }\n\n// float fill(float x, float size, float edge) {\n// return 1.0 - smoothstep(size - edge, size + edge, x);\n// }\n\n// float stroke(float x, float size, float w, float edge) {\n// float d = smoothstep(size - edge, size + edge, x + w * 0.5) - smoothstep(size - edge, size + edge, x - w * 0.5);\n// return clamp(d, 0.0, 1.0);\n// }\n\n// void main() {\n// vec2 st = st0 + 0.5;\n// vec2 posMouse = mx + 0.5;\n\n// float size = 1.2 + sin(u_time) * 0.1;\n// float roundness = 0.4 + sin(u_time * 0.5) * 0.1;\n// float borderSize = 0.05 + sin(u_time * 0.7) * 0.02;\n// float circleSize = 0.3 + sin(u_time * 0.8) * 0.05;\n// float circleEdge = 0.5 + sin(u_time * 0.6) * 0.1;\n\n// float sdfCircle = fill(\n// sdCircle(st, posMouse),\n// circleSize,\n// circleEdge\n// );\n\n// float sdf;\n// if (VAR == 0) {\n// sdf = sdRoundRect(st, vec2(size), roundness);\n// sdf = stroke(sdf, 0.0, borderSize, sdfCircle) * 4.0;\n// } else if (VAR == 1) {\n// sdf = sdCircle(st, vec2(0.5));\n// sdf = fill(sdf, 0.6, sdfCircle) * 1.2;\n// } else if (VAR == 2) {\n// sdf = sdCircle(st, vec2(0.5));\n// sdf = stroke(sdf, 0.58, 0.02, sdfCircle) * 4.0;\n// } else if (VAR == 3) {\n// sdf = sdPoly(st - vec2(0.5, 0.45), 0.3, 3);\n// sdf = fill(sdf, 0.05, sdfCircle) * 1.4;\n// }\n\n// vec3 gradient = mix(\n// mix(u_color1, u_color2, 0.5 + 0.5 * cos(u_time + st.x + 0.0)),\n// mix(u_color3, u_color4, 0.5 + 0.5 * cos(u_time + st.y + 2.0)),\n// 0.5 + 0.5 * cos(u_time + st.x + st.y + 4.0)\n// );\n\n// vec3 shapeColor = sdf * gradient;\n\n// float mouseEffect = u_invertMouse ? 1.0 - sdfCircle : sdfCircle;\n// shapeColor = mix(shapeColor, vec3(1.0) - shapeColor, u_hoverStrength * mouseEffect);\n\n// gl_FragColor = vec4(shapeColor, sdf);\n// }\n// `\n\n// interface ShaderConfig {\n// variation: number\n// color1: string\n// color2: string\n// color3: string\n// color4: string\n// enableHover: boolean\n// invertMouse: boolean\n// width: string\n// height: string\n// }\n\n// const initialState: ShaderConfig = {\n// variation: 0,\n// color1: \"#ff0000\",\n// color2: \"#00ff00\",\n// color3: \"#0000ff\",\n// color4: \"#ffff00\",\n// enableHover: true,\n// invertMouse: true,\n// width: \"100%\",\n// height: \"400px\",\n// }\n\n// export const configAtom = atom(initialState)\n\n// export function ShaderLensBlur() {\n// const [config] = useAtom(configAtom)\n// const containerRef = useRef(null)\n// const canvasRef = useRef(null)\n// const rendererRef = useRef(null)\n// const sceneRef = useRef(null)\n// const cameraRef = useRef(null)\n// const materialRef = useRef(null)\n// const rafRef = useRef(null)\n// const [isInteracting, setIsInteracting] = useState(false)\n\n// const updateSize = useCallback(() => {\n// if (\n// !containerRef.current ||\n// !canvasRef.current ||\n// !rendererRef.current ||\n// !cameraRef.current ||\n// !materialRef.current\n// )\n// return\n\n// const { clientWidth: w, clientHeight: h } = containerRef.current\n// const aspect = w / h\n\n// cameraRef.current.left = -aspect\n// cameraRef.current.right = aspect\n// cameraRef.current.top = 1\n// cameraRef.current.bottom = -1\n// cameraRef.current.updateProjectionMatrix()\n\n// rendererRef.current.setSize(w, h)\n// materialRef.current.uniforms.u_resolution.value.set(w, h)\n// }, [])\n\n// const updateMousePosition = useCallback(\n// (x: number, y: number) => {\n// if (!containerRef.current || !materialRef.current) return\n// const rect = containerRef.current.getBoundingClientRect()\n// const mouseX = x - rect.left\n// const mouseY = y - rect.top\n// if (isInteracting || config.enableHover) {\n// materialRef.current.uniforms.u_mouse.value.set(\n// mouseX,\n// rect.height - mouseY\n// )\n// }\n// },\n// [isInteracting, config.enableHover]\n// )\n\n// const animate = useCallback(\n// (time: number) => {\n// if (\n// !rendererRef.current ||\n// !sceneRef.current ||\n// !cameraRef.current ||\n// !materialRef.current\n// )\n// return\n\n// materialRef.current.uniforms.u_time.value = time * 0.001\n// materialRef.current.uniforms.u_hoverStrength.value =\n// isInteracting || config.enableHover ? 0.3 : 0\n\n// rendererRef.current.render(sceneRef.current, cameraRef.current)\n// rafRef.current = requestAnimationFrame(animate)\n// },\n// [config.enableHover, isInteracting]\n// )\n\n// useEffect(() => {\n// if (!containerRef.current || !canvasRef.current) return\n\n// const scene = new THREE.Scene()\n// sceneRef.current = scene\n\n// const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 1000)\n// camera.position.z = 1\n// cameraRef.current = camera\n\n// const renderer = new THREE.WebGLRenderer({\n// canvas: canvasRef.current,\n// antialias: true,\n// alpha: true,\n// })\n// renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))\n// renderer.setClearColor(0x000000, 0)\n// rendererRef.current = renderer\n\n// const geometry = new THREE.PlaneGeometry(2, 2)\n// const material = new THREE.ShaderMaterial({\n// vertexShader: `\n// varying vec2 v_texcoord;\n// void main() {\n// gl_Position = vec4(position, 1.0);\n// v_texcoord = uv;\n// }\n// `,\n// fragmentShader,\n// uniforms: {\n// u_mouse: { value: new THREE.Vector2() },\n// u_resolution: { value: new THREE.Vector2() },\n// u_pixelRatio: { value: Math.min(window.devicePixelRatio, 2) },\n// u_time: { value: 0 },\n// u_color1: { value: new THREE.Color(config.color1) },\n// u_color2: { value: new THREE.Color(config.color2) },\n// u_color3: { value: new THREE.Color(config.color3) },\n// u_color4: { value: new THREE.Color(config.color4) },\n// u_hoverStrength: { value: 0 },\n// u_invertMouse: { value: config.invertMouse },\n// },\n// defines: {\n// VAR: config.variation,\n// },\n// transparent: true,\n// blending: THREE.NormalBlending,\n// })\n// materialRef.current = material\n\n// const mesh = new THREE.Mesh(geometry, material)\n// scene.add(mesh)\n\n// updateSize()\n// rafRef.current = requestAnimationFrame(animate)\n\n// const resizeObserver = new ResizeObserver(updateSize)\n// resizeObserver.observe(containerRef.current)\n\n// return () => {\n// if (rafRef.current) cancelAnimationFrame(rafRef.current)\n// if (rendererRef.current) rendererRef.current.dispose()\n// if (containerRef.current) resizeObserver.unobserve(containerRef.current)\n// }\n// }, [config, updateSize, animate])\n\n// useEffect(() => {\n// const container = containerRef.current\n// if (!container) return\n\n// const handlePointerMove = (event: PointerEvent) =>\n// updateMousePosition(event.clientX, event.clientY)\n// const handleTouchMove = (event: TouchEvent) => {\n// if (event.touches.length > 0) {\n// const touch = event.touches[0]\n// updateMousePosition(touch.clientX, touch.clientY)\n// }\n// }\n\n// container.addEventListener(\"pointermove\", handlePointerMove)\n// container.addEventListener(\"touchmove\", handleTouchMove)\n// container.addEventListener(\"pointerdown\", () => setIsInteracting(true))\n// container.addEventListener(\"pointerup\", () => setIsInteracting(false))\n// container.addEventListener(\"touchstart\", () => setIsInteracting(true))\n// container.addEventListener(\"touchend\", () => setIsInteracting(false))\n\n// return () => {\n// container.removeEventListener(\"pointermove\", handlePointerMove)\n// container.removeEventListener(\"touchmove\", handleTouchMove)\n// container.removeEventListener(\"pointerdown\", () => setIsInteracting(true))\n// container.removeEventListener(\"pointerup\", () => setIsInteracting(false))\n// container.removeEventListener(\"touchstart\", () => setIsInteracting(true))\n// container.removeEventListener(\"touchend\", () => setIsInteracting(false))\n// }\n// }, [updateMousePosition])\n\n// useEffect(() => {\n// if (materialRef.current) {\n// materialRef.current.uniforms.u_color1.value.set(config.color1)\n// materialRef.current.uniforms.u_color2.value.set(config.color2)\n// materialRef.current.uniforms.u_color3.value.set(config.color3)\n// materialRef.current.uniforms.u_color4.value.set(config.color4)\n// materialRef.current.uniforms.u_invertMouse.value = config.invertMouse\n// materialRef.current.defines.VAR = config.variation\n// materialRef.current.needsUpdate = true\n// }\n// }, [config])\n\n// return (\n// \n// \n//
\n// {config.enableHover\n// ? `${\n// config.invertMouse ? \"Inverted mouse\" : \"Normal mouse\"\n// } interaction`\n// : \"Interact with the animation\"}{\" \"}\n// using mouse or touch\n//
\n// \n// )\n// }\n\n// export default ShaderLensBlur\n", "type": "registry:ui" } ] }