const ThreeScene = () => {
const sceneRef = useRef(null);
const stars = [];
const init = () => {
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.z = 5;
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
sceneRef.current.appendChild(renderer.domElement);
addSphere(scene);
const animateStars = () => {
for (let i = 0; i < stars.length; i++) {
const star = stars[i];
star.position.z += i / 10;
if (star.position.z > 1000) star.position.z -= 2000;
}
};
const render = () => {
requestAnimationFrame(render);
renderer.render(scene, camera);
animateStars();
};
render();
};
const addSphere = (scene) => {
for (let z = -1000; z < 1000; z += 20) {
const geometry = new THREE.SphereGeometry(0.5, 32, 32);
const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
const sphere = new THREE.Mesh(geometry, material);
sphere.position.x = Math.random() * 1000 - 500;
sphere.position.y = Math.random() * 1000 - 500;
sphere.position.z = z;
sphere.scale.x = sphere.scale.y = 2;
scene.add(sphere);
stars.push(sphere);
}
};
useEffect(() => {
init();
}, []);
return <div ref={sceneRef}/>;
};
i would start with some react basics. up to the point where translating that would be simple to you.
but when you eventually do, it’s bad practice to add hundreds of spheres with their own geometry and material to get something like stars, this would create tons of draw calls and bring performance down. use instancing.
here’s something similar, but using instances
1 Like