"use client"; import { Canvas, useFrame } from "@react-three/fiber"; import { Bloom, EffectComposer } from "@react-three/postprocessing"; import { KernelSize } from "postprocessing"; import { useMemo, useRef } from "react"; import * as THREE from "three"; import { cn } from "@/lib/utils"; interface TorusFromSlicesProps { slices?: number; majorRadius?: number; sliceRadius?: number; sliceDepth?: number; bevelEnabled?: boolean; } function TorusFromSlices({ slices = 10, majorRadius = 1.0, sliceRadius = 5, sliceDepth = 1, bevelEnabled = true, }: TorusFromSlicesProps) { const meshRef = useRef(null); const dummy = useMemo(() => new THREE.Object3D(), []); const sliceGeometry = useMemo(() => { const shape = new THREE.Shape(); const points: THREE.Vector2[] = []; const steps = 256; const a = sliceRadius * 1.5; const b = sliceRadius * 0.25; const n = 2; for (let i = 0; i <= steps; i++) { const theta = (i / steps) * Math.PI * 2; const cosT = Math.cos(theta); const sinT = Math.sin(theta); const x = Math.sign(cosT) * Math.pow(Math.abs(cosT), 2 / n) * a; const y = Math.sign(sinT) * Math.pow(Math.abs(sinT), 2 / n) * b; points.push(new THREE.Vector2(x, y)); } shape.setFromPoints(points); const extrudeSettings = { depth: sliceDepth, bevelEnabled: bevelEnabled, bevelThickness: Math.min(sliceDepth * 0.5, 0.02), bevelSize: Math.min(sliceRadius * 0.04, 0.02), bevelSegments: 32, steps: 64, curveSegments: 128, }; const geom = new THREE.ExtrudeGeometry(shape, extrudeSettings); geom.center(); geom.computeVertexNormals(); return geom; }, [sliceRadius, sliceDepth, bevelEnabled]); useFrame((state) => { if (!meshRef.current) return; for (let i = 0; i < slices; i++) { const t = (i / slices) * Math.PI * 2; const x = majorRadius * Math.cos(t); const z = majorRadius * Math.sin(t); const radial = new THREE.Vector3(x, 0, z).normalize(); const q = new THREE.Quaternion(); q.setFromUnitVectors(new THREE.Vector3(0, 0, 1), radial); const edgeRotation = new THREE.Quaternion().setFromEuler( new THREE.Euler(0, Math.PI / 2, 0), ); q.multiply(edgeRotation); const animatedRotation = Math.sin(state.clock.elapsedTime * 0.8 + i * 0.3) * 0.25; const twistRotation = new THREE.Quaternion().setFromEuler( new THREE.Euler(animatedRotation, 0, 0), ); q.multiply(twistRotation); dummy.position.set(x, 0, z); dummy.quaternion.copy(q); dummy.updateMatrix(); meshRef.current.setMatrixAt(i, dummy.matrix); } meshRef.current.instanceMatrix.needsUpdate = true; }); return ( ); } function RotatingTorus() { const groupRef = useRef(null); useFrame((state) => { if (groupRef.current) { const t = state.clock.getElapsedTime(); groupRef.current.rotation.y = t * -0.15; } }); return ( ); } interface Shader11Props { className?: string; } const Shader11 = ({ className }: Shader11Props) => { return (
); }; export { Shader11 };