Skip to content

Instantly share code, notes, and snippets.

@blift
Created February 9, 2024 08:20
Show Gist options
  • Save blift/5cfa85b4688aea92cd4ebabcc5024d6b to your computer and use it in GitHub Desktop.
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
"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