将Three.js从普通JavaScript转换为React Three Fiber

gijlo24d  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(129)

我一直在尝试将用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();

我在转换initanimate函数时遇到困难。
这是我目前所拥有的,我已经添加了位置和速度作为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生成:

x759pob2

x759pob21#

animate函数中的内容可以放在useFrame钩子中,它是一个r3f钩子,在每一帧中都被调用

相关问题