Threejs

Posted on October 2, 2021
Tags: javascript

1 Summary

  1. make a scene holds the {objects, lights, camera}
  2. make a camera : choose perspective projection(3D), orthographic projection(2D)
  3. make a webgl renderer and append it to DOM
  4. Make the objects
  5. Add object to scene
  6. make animation function which calls renderer.render(scene,camera)

1.1 React three fiber

  1. Threejs object constructors are react components, pass in args={[arg1,arg2,...]}
import React from 'react';
import './App.css';

import { Canvas } from '@react-three/fiber'

function App() {
  return (
    <div className="App">

        <Canvas orthographic={true} camera={{ left: 0.5 *600 * 1 / - 2, right: 0.5 * 600 / 2, top: 600 / 2, bottom: 600 / - 2, near: 0, far: 600}}>
          <mesh >
            <boxGeometry args={[400,400,1]} />
            <meshStandardMaterial />
          </mesh>
        </Canvas>
        
    </div>
  );
}
export default App;

2 How to convert THREE to fiber

				const geometry = new THREE.BufferGeometry();
				const material = new THREE.LineBasicMaterial( { vertexColors: true } );

				const positions = [];
				const colors = [];

				for ( let i = 0; i < segments; i ++ ) {

					const x = Math.random() * r - r / 2;
					const y = Math.random() * r - r / 2;
					const z = Math.random() * r - r / 2;

					// positions

					positions.push( x, y, z );

					// colors

					colors.push( ( x / r ) + 0.5 );
					colors.push( ( y / r ) + 0.5 );
					colors.push( ( z / r ) + 0.5 );

				}

				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
				geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
line = new THREE.Line( geometry, material );
function Line({ defaultStart, defaultEnd }: any) {
  const [start, setStart] = useState(defaultStart)
  const [end, setEnd] = useState(defaultEnd)
  const positions = useMemo(() => new Float32Array([...start, ...end]), [start, end])
  const lineRef = useRef<THREE.Line>(null!)
  useEffect(() => {
    const { current } = lineRef
    current.geometry.attributes.position.needsUpdate = true
    current.geometry.computeBoundingSphere()
  }, [lineRef, start, end])

  return (
    <>
      <line ref={lineRef as any}>
        <bufferGeometry>
          <bufferAttribute attach="attributes-position" count={positions.length / 3} array={positions} itemSize={3} />
        </bufferGeometry>
        <lineBasicMaterial color="black" />
      </line>
  )}