Metaballs
threecn/metaballsFreeComponent
Liquid metaballs that merge and split as they orbit each other, tinted with --primary.
Install it
npx shadcn@latest add https://threecn.dev/r/metaballs.jsonSource
1"use client"23import * as React from "react"4import { useFrame } from "@react-three/fiber"5import { MarchingCube, MarchingCubes } from "@react-three/drei"6import * as THREE from "three"78import {9 SceneContainer,10 type SceneContainerProps,11} from "@/components/threecn/scene-container"12import {13 useShadcnTheme,14 type ThemeMode,15} from "@/components/hooks/use-shadcn-theme"1617type BlobSeed = {18 ax: number19 ay: number20 az: number21 px: number22 py: number23 pz: number24}2526function seedBlobs(count: number): BlobSeed[] {27 return Array.from({ length: count }, () => ({28 ax: 0.7 + Math.random() * 0.7,29 ay: 0.7 + Math.random() * 0.7,30 az: 0.7 + Math.random() * 0.7,31 px: Math.random() * Math.PI * 2,32 py: Math.random() * Math.PI * 2,33 pz: Math.random() * Math.PI * 2,34 }))35}3637function Blobs({38 blobs,39 speed,40 resolution,41 roughness,42 theme,43}: {44 blobs: number45 speed: number46 resolution: number47 roughness: number48 theme: ThemeMode49}) {50 const { primaryColor, accentColor } = useShadcnTheme(theme)51 const refs = React.useRef<(THREE.Object3D | null)[]>([])52 const seeds = React.useMemo(() => seedBlobs(blobs), [blobs])5354 // drei feeds each ball's WORLD position into the field as55 // `0.5 + worldPos * 0.5`, and the balls are children of the scaled56 // MarchingCubes mesh. So local position × SCALE must stay well inside57 // [-1, 1] (≈ [0, 1] in field space) or the blobs clip flat against the cube.58 const AMP = 0.25960 useFrame(({ clock }) => {61 const t = clock.getElapsedTime() * speed62 for (let i = 0; i < seeds.length; i++) {63 const o = refs.current[i]64 if (!o) continue65 const s = seeds[i]66 o.position.set(67 Math.sin(t * s.ax + s.px) * AMP,68 Math.cos(t * s.ay + s.py) * AMP,69 Math.sin(t * s.az + s.pz) * AMP70 )71 }72 })7374 return (75 <MarchingCubes76 resolution={resolution}77 maxPolyCount={60000}78 enableUvs={false}79 enableColors={false}80 scale={2.6}81 >82 {seeds.map((_, i) => (83 <MarchingCube84 key={i}85 ref={(el: THREE.Object3D | null) => {86 refs.current[i] = el87 }}88 strength={0.5}89 subtract={12}90 />91 ))}92 <meshStandardMaterial93 color={primaryColor}94 emissive={accentColor}95 emissiveIntensity={0.25}96 roughness={roughness}97 metalness={0.25}98 />99 </MarchingCubes>100 )101}102103export type MetaballsProps = {104 /** Number of blobs. */105// … truncated
What it pulls in
npm packages
Files it writes
More from threecn
All 28 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AuroraRibbonsaurora-ribbons | threecn | Components | Free | 3 deps · 3 files | |
| Boidsboids | threecn | Components | Free | 3 deps · 3 files | |
| Clothcloth | threecn | Components | Free | 3 deps · 3 files | |
| Crystalcrystal | threecn | Components | Free | 3 deps · 3 files | |
| CubeWavecube-wave | threecn | Components | Free | 3 deps · 3 files | |
| CurlFlowcurl-flow | threecn | Components | Free | 3 deps · 3 files | |
| DnaHelixdna-helix | threecn | Components | Free | 3 deps · 3 files | |
| FloatingCard3Dfloating-card-3d | threecn | Components | Free | 3 deps · 3 files |
