{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "liquid-chrome",
  "title": "Liquid Chrome",
  "description": "A smooth, mesmerizing liquid metal shader effect.",
  "dependencies": [
    "three",
    "@react-three/fiber",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/chamaac/liquid-chrome/liquid-chrome.tsx",
      "content": "\"use client\";\n\nimport { Canvas, useFrame } from \"@react-three/fiber\";\nimport { useRef, useMemo } from \"react\";\nimport * as THREE from \"three\";\nimport { cn } from \"@/lib/utils\";\n\nconst vertexShader = `\n  varying vec2 vUv;\n  void main() {\n    vUv = uv;\n    gl_Position = vec4(position, 1.0);\n  }\n`;\n\nconst fragmentShader = `\n  uniform float uTime;\n  uniform float uTimeScale;\n  uniform vec3 uColor;\n  uniform vec3 uColor2;\n  varying vec2 vUv;\n\n  // Simplex 2D noise\n  vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }\n\n  float snoise(vec2 v){\n    const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n             -0.577350269189626, 0.024390243902439);\n    vec2 i  = floor(v + dot(v, C.yy) );\n    vec2 x0 = v -   i + dot(i, C.xx);\n    vec2 i1;\n    i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n    vec4 x12 = x0.xyxy + C.xxzz;\n    x12.xy -= i1;\n    i = mod(i, 289.0);\n    vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n    + i.x + vec3(0.0, i1.x, 1.0 ));\n    vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),\n      dot(x12.zw,x12.zw)), 0.0);\n    m = m*m ;\n    m = m*m ;\n    vec3 x = 2.0 * fract(p * C.www) - 1.0;\n    vec3 h = abs(x) - 0.5;\n    vec3 ox = floor(x + 0.5);\n    vec3 a0 = x - ox;\n    m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n    vec3 g;\n    g.x  = a0.x  * x0.x  + h.x  * x0.y;\n    g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n    return 130.0 * dot(m, g);\n  }\n\n  void main() {\n    vec2 uv = vUv;\n    \n    // Domain Warping for \"Silk/Liquid Metal\" look\n    // Layer 1: Base Flow\n    vec2 q = vec2(0.0);\n    q.x = snoise(uv * 1.5 + uTime * uTimeScale);\n    q.y = snoise(uv * 1.5 + uTime * (uTimeScale * 1.2));\n    \n    // Layer 2: Distortion\n    vec2 r = vec2(0.0);\n    \n    r.x = snoise(uv * 2.0 + 1.0 * q + vec2(1.7, 9.2) + uTime * (uTimeScale * 1.5));\n    r.y = snoise(uv * 2.0 + 1.0 * q + vec2(8.3, 2.8) + uTime * (uTimeScale * 1.3));\n    \n    // Final Noise Value (The height/pattern)\n    float f = snoise(uv * 3.0 + r);\n    \n    // Mix factor - swirl the two colors together\n    float mixFactor = smoothstep(-1.0, 1.0, f + q.x); // Based on flow height\n    \n    vec3 col = mix(uColor, uColor2, mixFactor);\n    \n    // Bump Map / Normals for Lighting\n    float eps = 0.001;\n    float fx = snoise(uv * 3.0 + r + vec2(eps, 0.0)) - f;\n    float fy = snoise(uv * 3.0 + r + vec2(0.0, eps)) - f;\n    vec3 normal = normalize(vec3(fx * 20.0, fy * 20.0, 1.0));\n    \n    // Lighting\n    vec3 lightPos = vec3(0.5, 0.5, 2.0);\n    vec3 lightDir = normalize(lightPos);\n    \n    // Diffuse\n    float diff = max(dot(normal, lightDir), 0.0);\n    \n    // Specular (High gloss)\n    vec3 viewDir = vec3(0.0, 0.0, 1.0);\n    vec3 reflectDir = reflect(-lightDir, normal);\n    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 64.0);\n    \n    // Fresnel / Rim Light\n    float fresnel = pow(1.0 - max(dot(normal, viewDir), 0.0), 4.0);\n    \n    // Combine Lighting\n    col = col * (0.6 + 0.4 * diff); // Base color\n    col += vec3(1.0) * spec * 0.8; // White intense specular\n    col += uColor2 * fresnel * 1.0; // Glowing rim using the secondary color\n    \n    // Tone mapping to prevent washout\n    col = col / (1.0 + col * 0.2);\n\n    gl_FragColor = vec4(col, 1.0);\n  }\n`;\n\nconst LiquidEffect = ({\n  speed = 0.35,\n  timeScale = 0.225,\n  color = \"#C0C0C0\",\n  color2 = \"#4A4A4A\",\n}: {\n  speed?: number;\n  timeScale?: number;\n  color?: string;\n  color2?: string;\n}) => {\n  const material = useRef<THREE.ShaderMaterial>(null);\n\n  const uniforms = useMemo(\n    () => ({\n      uTime: { value: 0 },\n      uTimeScale: { value: timeScale },\n      uColor: { value: new THREE.Color(color) },\n      uColor2: { value: new THREE.Color(color2) },\n    }),\n\n    []\n  );\n\n  useFrame((state) => {\n    if (material.current) {\n      material.current.uniforms.uTime.value =\n        state.clock.getElapsedTime() * speed;\n      material.current.uniforms.uTimeScale.value = timeScale;\n      material.current.uniforms.uColor.value.set(color);\n      material.current.uniforms.uColor2.value.set(color2);\n    }\n  });\n\n  return (\n    <mesh>\n      <planeGeometry args={[2, 2]} />\n      <shaderMaterial\n        ref={material}\n        vertexShader={vertexShader}\n        fragmentShader={fragmentShader}\n        uniforms={uniforms}\n      />\n    </mesh>\n  );\n};\n\ninterface LiquidChromeProps {\n  className?: string;\n  speed?: number; // Overall speed of the animation\n  timeScale?: number; // Scale of the time-based noise movement\n  color?: string;\n  color2?: string;\n}\n\nexport default function LiquidChrome({\n  className,\n  speed = 0.35,\n  timeScale = 0.225,\n  color = \"#C0C0C0\",\n  color2 = \"#4A4A4A\",\n}: LiquidChromeProps) {\n  return (\n    <div\n      className={cn(\n        \"absolute inset-0 w-full h-full pointer-events-none\",\n        className\n      )}\n    >\n      <Canvas camera={{ position: [0, 0, 1] }} dpr={[1, 2]}>\n        <LiquidEffect\n          speed={speed}\n          timeScale={timeScale}\n          color={color}\n          color2={color2}\n        />\n      </Canvas>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}