Created
February 9, 2024 08:20
-
-
Save blift/5cfa85b4688aea92cd4ebabcc5024d6b to your computer and use it in GitHub Desktop.
React Three Fiber with bufferGeometry, example how to generate random colors and animate custom points on Z axis only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use client" | |
import React, {useRef, useMemo} from 'react'; | |
import { Canvas, useFrame } from '@react-three/fiber'; | |
import { Mesh, BufferAttribute, Points } from "three"; | |
import { OrbitControls } from '@react-three/drei'; | |
const Scene: React.FC = () => { | |
const meshRef = useRef<Mesh>(null!); | |
// create 12x8 π³π³π³ ... | |
const BufferPoints = () => { | |
const columns: number = 12; | |
const rows: number = 8; | |
const marginX: number = 1; | |
const marginY: number = 1; | |
const pointsRef = useRef<Points>(null!); | |
// Function to update points position on each frame π | |
useFrame(({ clock }) => { | |
if (pointsRef.current) { | |
const positions = pointsRef.current.geometry.attributes.position.array; | |
for (let i = 0; i < positions.length; i += 6) { | |
positions[i + 2] += Math.sin(clock.getElapsedTime()) * 0.004; | |
} | |
pointsRef.current.geometry.attributes.position.needsUpdate = true; | |
} | |
}); | |
// Initialize points πΆ | |
const points = useMemo(() => { | |
const p: number[] = []; | |
const colors: number[] = []; | |
for (let y = -rows; y < rows; y++) { | |
for (let x = -columns; x < columns; x++) { | |
const yPos = y * (marginY + 0.2); | |
const xPos = x * (marginX + 0.2); | |
p.push(xPos, yPos, 0); | |
// Generate random colors π | |
const color = [Math.random(), Math.random(), Math.random()]; | |
colors.push(...color); | |
} | |
} | |
return { | |
position: new BufferAttribute(new Float32Array(p), 3), | |
color: new BufferAttribute(new Float32Array(colors), 3), | |
}; | |
}, [columns, rows]); | |
return ( | |
<points ref={pointsRef}> | |
<bufferGeometry attach="geometry"> | |
<bufferAttribute attach={'attributes-position'} {...points.position} /> | |
<bufferAttribute attach={'attributes-color'} {...points.color} /> | |
</bufferGeometry> | |
<pointsMaterial size={0.1} vertexColors={true} sizeAttenuation={true} /> | |
</points> | |
); | |
}; | |
return ( | |
<div className="relative h-[640px] w-full flex items-center justify-center"> | |
<Canvas> | |
<> | |
<color args={['#010124']} attach={"background"} /> | |
<OrbitControls enableZoom={false}/> | |
<BufferPoints/> | |
<mesh ref={meshRef}> | |
<boxGeometry args={[3, 3, 3]} /> | |
<meshNormalMaterial/> | |
</mesh> | |
</> | |
</Canvas> | |
</div> | |
) | |
} | |
export default Scene; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment