我一直在尝试将用vanilla JS编写的three.js转换为React Three fiber。
import * as THREE from 'three';
let scene, camera, renderer;
//Canvas
const canvas = document.querySelector('canvas')
//Number of line particles
let lineCount = 6000;
//adding buffer Geometry
let geom = new THREE.BufferGeometry();
//Giving the Buffer Geometry attributes
geom.setAttribute('position', new THREE.BufferAttribute(new Float32Array(6 * lineCount), 3));
geom.setAttribute('velocity', new THREE.BufferAttribute(new Float32Array(2 * lineCount), 1));
//creating array variable for the position
let pos = geom.getAttribute('position');
let posArray = pos.array;
//creating array variable for the velocity
let vel = geom.getAttribute('velocity');
let velArray = vel.array;
//function to initiate
const init = () => {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 1, 500);
camera.position.z = 200;
renderer = new THREE.WebGLRenderer({antialias: true, canvas: canvas});
renderer.setSize(window.innerWidth, window.innerHeight);
for (let lineIndex = 0; lineIndex < lineCount; lineIndex++){
let x = Math.random() * 400 - 200;
let y = Math.random() * 200 - 100;
let z = Math.random() * 500 - 100;
let xx = x;
let yy = y;
let zz = z;
//line starting position
posArray[6 * lineIndex] = x;
posArray[6 * lineIndex + 1] = y;
posArray[6 * lineIndex + 2] = z;
//line ending position
posArray[6 * lineIndex + 3] = xx;
posArray[6 * lineIndex + 4] = yy;
posArray[6 * lineIndex + 5] = zz;
velArray[2 * lineIndex] = velArray[2 * lineIndex + 1] = 0;
}
let lineMat = new THREE.LineBasicMaterial({color: '#ffffff'});
let lines = new THREE.LineSegments(geom, lineMat);
scene.add(lines);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth/ window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
animate();
}
const animate = () => {
for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {
velArray[2 * lineIndex] += 0.03;
velArray[2 * lineIndex + 1] += 0.025;
posArray[6 * lineIndex + 2] += velArray[2 * lineIndex];
posArray[6 * lineIndex + 5] += velArray[2 * lineIndex + 1];
if (posArray[6 * lineIndex + 5] > 200) {
let z = Math.random() * 200 - 100;
posArray[6 * lineIndex + 2] = z;
posArray[6 * lineIndex + 5] = z;
velArray[2 * lineIndex] = 0;
velArray[2 * lineIndex + 1] = 0;
}
}
pos.needsUpdate = true;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
我在转换init
和animate
函数时遇到困难。
这是我目前所拥有的,我已经添加了位置和速度作为bufferAttributes,并在for循环中指定了起始和结束坐标:
const StarLine = () => {
const warpFieldMesh = useRef();
const bufAtPos = useRef();
const bufAtVel = useRef();
const count = 100;
const [positions, velocity] = useMemo(() => {
let positions = []
let velocity = []
for (let lineIndex = 0; lineIndex < count; lineIndex++){
let x = Math.random() * 400 - 200;
let y = Math.random() * 200 - 100;
let z = Math.random() * 500 - 100;
let xx = x;
let yy = y;
let zz = z;
//line starting position
positions[6 * lineIndex] = x;
positions[6 * lineIndex + 1] = y;
positions[6 * lineIndex + 2] = z;
//line ending position
positions[6 * lineIndex + 3] = xx;
positions[6 * lineIndex + 4] = yy;
positions[6 * lineIndex + 5] = zz;
velocity[2 * lineIndex] = velocity[2 * lineIndex + 1] = 0;
}
return [new Float32Array(positions), new Float32Array(velocity)]
}, [])
useFrame(() => {
})
return (
<line ref={warpFieldMesh}>
<bufferGeometry attach="geometry">
<bufferAttribute
ref={bufAtPos}
attachObject={["attributes", "position"]}
count={positions.length / 3}
array={positions}
itemSize={3}
/>
<bufferAttribute
ref={bufAtVel}
attachObject={["attributes", "velocity"]}
count={velocity.length / 2}
array={velocity}
itemSize={1}
/>
</bufferGeometry>
<lineBasicMaterial
attach="material"
color={'#ffffff'}
/>
</line>
)
}
普通JavaScript生成:
1条答案
按热度按时间x759pob21#
animate函数中的内容可以放在useFrame钩子中,它是一个r3f钩子,在每一帧中都被调用