[1](images/1.png)



Β
--- title: "Three.js" author: "μν" date: 2024-11-01T14:00:04+09:00 category: ["POSTS"] tags: ["React"] og_image: "/images/gamer.png" keywords: ['React', 'Three.js'] --- ## Three.jsλ  - Renderer : Sceneκ³Ό Cameraκ°μ²΄λ₯Ό λ겨 λ°λλ€. 3Dμ¬μ νλ©΄(2μ°¨μ) μ΄λ―Έμ§λ‘ λ λλ§νλ€. - Scene Graph : Node(μμ)λ₯Ό κ³μΈ΅κ΅¬μ‘°λ‘ κ·Έλ¦ΌμΌλ‘ λνλΈ κ².   * μ§μκ³΅κ° : νμμ΄ λ΄€μλ, νμμ 곡μ νλ μ§κ΅¬, μ§κ΅¬λ₯Ό 곡μ νλ λ¬ , κ΄μ μ°¨μ΄λ‘ μ§μ곡κ°μ΄ νμ±λλ€. ## Three.js + react κΈ°λ³Έ νν λ¦¬μΌ + μ½λ - Three jsλ λΈλΌμ°μ μμ 3D κ·Έλν½μ λ μ½κ² μμ±ν μ μκ² ν΄μ£Όλ λΌμ΄λΈλ¬λ¦¬μ λλ€ - μΊλ²μ€ + WebGLμ μ¬μ© νμ¬ 3D λͺ¨λΈκ³Ό μ λλ©μ΄μ μ νμν©λλ€. - react-three-fiber λ μΉ λ° react-nativeμ© React λ λλ¬ λ‘, Three.jsλ₯Ό μ¬μ©νμ¬ 3D λͺ¨λΈ λ° μ λλ©μ΄μ μ μμ±νλ μλλ₯Ό ν₯μμν΅λλ€. ### react-three-fiberthreeJSReact μν, νν¬ λ° μνμ μ¬μ©νμ¬ μ½λ κ΅¬μ± μμ - mesh : λͺ¨λΈμ λͺ¨μμ μ μνλ λ° λμμ΄ λλ μμ± - hooks : react-three-fiberμ μ νν¬ λμμ΄ μ°λ¦¬μ λμκ³Ό κ°μ μ¬μ©μ μ΄λ²€νΈλ₯Ό μ μνλ κ²μ΄ ν¨μλ₯Ό μμ±νλ κ²μ΄ onClick λ° onPointOver ```jsx import React, { useRef, useState, useMemo } from "react"; import { Canvas, useFrame } from "@react-three/fiber"; import * as THREE from "three"; import Doge from "./assets/streamline-icon-dogecoin@400x400.png"; import { OrbitControls, Stars } from "@react-three/drei"; import "./app.css"; const Box = (props) => { const mesh = useRef(); const [active, setActive] = useState(false); useFrame(() => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01; }); const texture = useMemo(() => new THREE.TextureLoader().load(Doge), []); return ( <mesh {...props} ref={mesh} scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]} onClick={(e) => setActive(!active)} > <boxBufferGeometry args={[1, 1, 1]} /> <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}> <primitive attach="map" object={texture} /> </meshBasicMaterial> </mesh> ); }; function App() { return ( <Canvas> <Stars /> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} /> <pointLight position={[-10, -10, -10]} /> <Box position={[-1, 0, 0]} /> <Box position={[2.5, 0, 0]} /> </Canvas> ); } export default App; ``` ### `<BoxBufferGeometry>` vs `<BoxGeometry>` * `<BoxGeometry>`λ μ‘°μμ μ’λ€. μ μ₯μ΄ μμλλ λ¨μ ```js μ μ μ μμ νλ €λ©΄.. //with Geometry you just get vertex 5 and have access to it's x... //AND the methods of the class -> Vector3.add(Vector3) myGeom.vertices[5].add(new THREE.Vector3(1,2,3)) ``` * `<BoxBufferGeometry>` WebGL μΉνμ μΈ νμ, λ λλ§μ μ’κ³ μ μ₯νκΈ° μ’μ§λ§ μ‘°μμ΄ νλ€λ€. ```js μ μ μ μμ νλ €λ©΄.. //xyz are just numbers, so with a stride of 3 //we select x , and then the next two for y and z //we have to know that the 15th number in this array is x of vertex 5... const stride = 3 const index = 5 let offset = index * stride myGeom.attributes.position.array[offset++] += 1 myGeom.attributes.position.array[offset++] += 2 myGeom.attributes.position.array[offset ] += 3 ``` * Mesh μ΄λ²€νΈνΈλ€λ¬  [Load 3D Models in glTF Format](https://discoverthreejs.com/book/first-steps/load-models/)