From 2d9230b8ea3f2486bb044f8a5a0bd2a04b23efab Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 25 Jan 2024 11:02:20 +0100 Subject: [PATCH] fix(game): implemented the InstancedMesh principle on the particle system for drifting --- src/App.jsx | 2 +- src/components/DriftParticlesLeft.jsx | 6 +-- src/components/DriftParticlesRight.jsx | 13 +---- src/components/Particles1.jsx | 72 ++++++++++++-------------- src/components/Particles2.jsx | 72 ++++++++++++-------------- src/components/PlayerController.jsx | 4 +- 6 files changed, 71 insertions(+), 98 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index d803a5c..159d6dc 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -43,7 +43,7 @@ function App() { - {/* */} + diff --git a/src/components/DriftParticlesLeft.jsx b/src/components/DriftParticlesLeft.jsx index 710d778..56545c3 100644 --- a/src/components/DriftParticlesLeft.jsx +++ b/src/components/DriftParticlesLeft.jsx @@ -10,16 +10,16 @@ export const DriftParticlesLeft = ({turboColor,scale, ...props}) => { return ( + {/* - - + */} - + {/* */} ) diff --git a/src/components/DriftParticlesRight.jsx b/src/components/DriftParticlesRight.jsx index 2d275db..fd72b4e 100644 --- a/src/components/DriftParticlesRight.jsx +++ b/src/components/DriftParticlesRight.jsx @@ -9,18 +9,7 @@ export const DriftParticlesRight = ({turboColor,scale, ...props}) => { return ( - - - - - - - - - - - - + ) diff --git a/src/components/Particles1.jsx b/src/components/Particles1.jsx index 3743470..b28f556 100644 --- a/src/components/Particles1.jsx +++ b/src/components/Particles1.jsx @@ -1,55 +1,47 @@ -import { useRef } from "react"; +import { useRef, useMemo } from "react"; import { useFrame } from "@react-three/fiber"; import * as THREE from 'three'; -export const Particles1 = ({ turboColor, scale, ...props }) => { - const ref = useRef(); - const velocity = useRef({ - x: -Math.random() * 0.05, - y: Math.random() * 0.05, - z: Math.random() * 0.02, - }); - const gravity = -0.003; - +export const Particles1 = ({ turboColor, scale, numParticles = 50, ...props }) => { + const instancedMeshRef = useRef(); + const particlesData = useMemo(() => { + return new Array(numParticles).fill().map(() => ({ + position: new THREE.Vector3(-0.6, 0.05, 0.5), + velocity: new THREE.Vector3(-Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02), + gravity: -0.003 + })); + }, [numParticles]); + useFrame((state, delta) => { - let position = ref.current.position; - let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z); - - // Adjust gravity and velocity based on delta - velocity.current.y += gravity * delta * 144; // Multiply by 144 to scale for 144 FPS - - // Scale velocity changes by delta - position.x += velocity.current.x * delta * 144; - position.y += velocity.current.y * delta * 144; - position.z += velocity.current.z * delta * 144; - - if (!velocityVector.equals(new THREE.Vector3(0, 0, 0))) { - const alignmentQuaternion = new THREE.Quaternion(); - alignmentQuaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), velocityVector.normalize()); - ref.current.quaternion.slerp(alignmentQuaternion, 0.1); - } - - if (position.y < 0.05) { - position.set(-0.6, 0.05, 0.5); - velocity.current = { - x: -Math.random() * 0.05, - y: Math.random() * 0.05, - z: Math.random() * 0.02, - }; - } - - ref.current.position.set(position.x, position.y, position.z); + const deltaScaled = delta * 144; // Scale for 144 FPS + particlesData.forEach((particle, i) => { + particle.velocity.y += particle.gravity * deltaScaled; + + particle.position.x += particle.velocity.x * deltaScaled; + particle.position.y += particle.velocity.y * deltaScaled; + particle.position.z += particle.velocity.z * deltaScaled; + + if (particle.position.y < 0.05) { + particle.position.set(-0.6, 0.05, 0.5); + particle.velocity.set(-Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02); + } + + const matrix = new THREE.Matrix4(); + matrix.setPosition(particle.position); + instancedMeshRef.current.setMatrixAt(i, matrix); + }); + + instancedMeshRef.current.instanceMatrix.needsUpdate = true; }); - return ( - + - + ); }; diff --git a/src/components/Particles2.jsx b/src/components/Particles2.jsx index 6b8fea1..af14cd3 100644 --- a/src/components/Particles2.jsx +++ b/src/components/Particles2.jsx @@ -1,55 +1,47 @@ -import { useRef } from "react"; +import { useRef, useMemo } from "react"; import { useFrame } from "@react-three/fiber"; import * as THREE from 'three'; -export const Particles2 = ({ turboColor, scale, ...props }) => { - const ref = useRef(); - const velocity = useRef({ - x: Math.random() * 0.05, - y: Math.random() * 0.05, - z: Math.random() * 0.02, - }); - const gravity = -0.003; - +export const Particles2 = ({ turboColor, scale, numParticles = 50, ...props }) => { + const instancedMeshRef = useRef(); + const particlesData = useMemo(() => { + return new Array(numParticles).fill().map(() => ({ + position: new THREE.Vector3(0.6, 0.05, 0.5), + velocity: new THREE.Vector3(Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02), + gravity: -0.003 + })); + }, [numParticles]); + useFrame((state, delta) => { - let position = ref.current.position; - let velocityVector = new THREE.Vector3(velocity.current.x, velocity.current.y, velocity.current.z); - - // Adjust gravity and velocity based on delta - velocity.current.y += gravity * delta * 144; // Multiply by 144 to scale for 144 FPS - - // Scale velocity changes by delta - position.x += velocity.current.x * delta * 144; - position.y += velocity.current.y * delta * 144; - position.z += velocity.current.z * delta * 144; - - if (!velocityVector.equals(new THREE.Vector3(0, 0, 0))) { - const alignmentQuaternion = new THREE.Quaternion(); - alignmentQuaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), velocityVector.normalize()); - ref.current.quaternion.slerp(alignmentQuaternion, 0.1); - } - - if (position.y < 0.05) { - position.set(0.6, 0.05, 0.5); - velocity.current = { - x: Math.random() * 0.05, - y: Math.random() * 0.05, - z: Math.random() * 0.02, - }; - } - - ref.current.position.set(position.x, position.y, position.z); + const deltaScaled = delta * 144; // Scale for 144 FPS + particlesData.forEach((particle, i) => { + particle.velocity.y += particle.gravity * deltaScaled; + + particle.position.x += particle.velocity.x * deltaScaled; + particle.position.y += particle.velocity.y * deltaScaled; + particle.position.z += particle.velocity.z * deltaScaled; + + if (particle.position.y < 0.05) { + particle.position.set(0.6, 0.05, 0.5); + particle.velocity.set(Math.random() * 0.05, Math.random() * 0.05, Math.random() * 0.02); + } + + const matrix = new THREE.Matrix4(); + matrix.setPosition(particle.position); + instancedMeshRef.current.setMatrixAt(i, matrix); + }); + + instancedMeshRef.current.instanceMatrix.needsUpdate = true; }); - return ( - + - + ); }; diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx index bc4781f..c5de690 100644 --- a/src/components/PlayerController.jsx +++ b/src/components/PlayerController.jsx @@ -387,13 +387,13 @@ export const PlayerController = () => { /> - - + */} {/* */}