![[R3F] Migration - ThreeJs to R3F](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfBsBa%2FbtsI1UWPW0V%2FdtbqORFCDmWDN2qmaaeSKK%2Fimg.png)
🔍ThreeJs에서 R3F로 마이그레이션하기
[ThreeJS] ThreeJS 기본 구성 요소
ThreeJS란?ThreeJS란 WebGL(Web Graphic's Library)을 쉽게 사용할 수 있도록 해주는 JS기반 라이브러리이다. Graphic들은 html canvas 위에 그려지는데 이를 개발자가 좀 더 편하게 다루기 위해서 사용된다.ThreeJS
indigochi1d.tistory.com
전에 포스팅했던 ThreeJS의 기본 구성요소에는 4가지가 있었다.
- Renderer
- Scene
- Camera
- Mesh
아래에서는 기본 구성요소의 선언 : ThreeJS vs R3F 에 대해서 코드로 작성하며 설명하도록 하겠다.
1️⃣Renderer
ThreeJS
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.render(scene,camera);
R3F
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
<!--index.html-->
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
/* main.jsx */
/* App컴포넌트안에 MainCanvas 컴포넌트가 하위컴포넌트로 선언되어있음 */
ThreeJS에서는 new 를 통해 새로운 WebGLRenderer 인스턴스를 선언한 후 직접 domElement를 삽입해서 rendering 한다.
반면, R3F는 React Three Fiber라는 이름 그대로 React에서 사용되는 컴포넌트화된 App.jsx를 id-root에 createRoot 메서드를 통해 렌더링한다.
2️⃣Scene
ThreeJS
const scene = new THREE.Scene();
scene.add(mesh);
R3F
/* eslint-disable react/no-unknown-property*/
import {Canvas} from "@react-three/fiber";
import {Color} from "three";
import {OrbitControls} from "@react-three/drei";
import Meshes from "./Meshes.jsx";
const MainCanvas = () => {
return (
<Canvas gl={{antialias: true}} shadows={"soft"} camera={{
fov:60,
aspect: window.innerWidth / window.innerHeight,
near:0.1,
far:100,
position: [5,5,5]
}}
scene={{background: new Color(0x000000)}}>
<OrbitControls />
<Meshes/>
</Canvas>
);
};
export default MainCanvas;
ThreeJS에서는 인스턴스를 선언해서 mesh들을 scene에 add하는 방식으로 scene을 사용했다면
R3F에서는 Canvas 컴포넌트(R3F에서 제공함)의 속성에 scene을 넣어줌으로써 scene을 선언하고 사용할 수 있다.
3️⃣Camera
ThreeJS
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth/window.innerHeight,
0.1,
100
);
R3F
/* eslint-disable react/no-unknown-property*/
import {Canvas} from "@react-three/fiber";
import {Color} from "three";
import {OrbitControls} from "@react-three/drei";
import Meshes from "./Meshes.jsx";
const MainCanvas = () => {
return (
<Canvas gl={{antialias: true}} shadows={"soft"} camera={{
fov:60,
aspect: window.innerWidth / window.innerHeight,
near:0.1,
far:100,
position: [5,5,5]
}}
scene={{background: new Color(0x000000)}}>
<OrbitControls />
<Meshes/>
</Canvas>
);
};
export default MainCanvas;
Perspective Camera의 경우로 예를 들때,
ThreeJS는 새로운 인스턴스를 선언해 사용하지만 R3F에서는 그저 Canvas의 camera 속성에 필요한 값들을 넣어준다.
4️⃣Mesh
ThreeJS
const geometry = new THREE.BoxGeometry(1,1,1);
const material = new THREE.MeshBasicMaterial({
color: 0xff0000
});
const mesh = new THREE.Mesh(geometry,material);
R3F
/* eslint-disable react/no-unknown-property*/
import {Plane, TorusKnot} from "@react-three/drei";
const Meshes = () => {
return (
<>
<Plane args={[40,40]} rotation-x={-Math.PI/2}
receiveShadow={true}>
<meshStandardMaterial/>
</Plane>
<TorusKnot
args={[1,0.2,128,128,2,3]}
position={[-3,1.6,0]}
castShadow={true}
receiveShadow={true}
>
<meshStandardMaterial color={0xff0000}/>
</TorusKnot>
</>
);
};
export default Meshes;
/* Meshes.jsx */
ThreeJS는 mesh를 만들 때 인스턴스를 새로 선언하고 geometry와 material를 Mesh의 new Instance로 선언하여 만든다.
반면, R3F는 R3F/drei에서 제공하는 다양한 Geometry 컴포넌트 하위에 mesh 컴포넌트를 선언하며 사용한다.
즉, 위의 코드에서 Plane, TorusKnot에 해당하는 것은 Geometry 이고 meshStandardMaterial이 material이라고 볼 수 있다.
💡Light
BasicMaterial을 제외한 나머지 Material들은 조명(light)이 없으면 시각화되지 않는다.
ThreeJS
const directionalLight = new THREE.DirectionalLight("white", 10);
directionalLight.castShadow = true; /*빛이 그림자를 드리울 수 있게함*/
directionalLight.position.set(0, 3, 2); /*객체의 x,y,z 좌표값을 설정함. 즉, 조명의 위치를 설정함.*/
directionalLight.lookAt(0, 0, 0); /* 조명이 어느 좌표에서 쏘이는지 설정*/
scene.add(directionalLight);
R3F
/* eslint-disable react/no-unknown-property*/
import {useRef} from "react";
import {useHelper} from "@react-three/drei";
import * as THREE from "three";
export const Lights= () => {
const lightRef = useRef(null);
/* useHelper(lightRef,THREE.DirectionalLightHelper,3,0xffff00);*/
return (
<>
<directionalLight
ref={lightRef}
castShadow={true}
ars={[0xffffff, 5]}
position={[5, 5, 5]}
shadow-camera-left={-25}
shadow-camera-right={25}
shadow-camera-top={25}
shadow-camera-bottom={-25}
shadow-camera-near={0.1}
shadow-camera-far={1000}
shadow-mapSize-width={4096}
shadow-mapSize-height={4096}
/>
<ambientLight args={[0xffffff,10]}/>
</>
)
}
/* Lights.jsx */
이전과 똑같이 ThreeJS는 새로운 light 인스턴스를 선언한다.
R3F는 다양한 Light 컴포넌트를 사용할 수 있다.
또한 useHelper Hook을 통해 helper기능도 이용할 수 있다.
'FrontEnd > 3D Web' 카테고리의 다른 글
[R3F] About R3F's Hooks (0) | 2024.08.22 |
---|---|
[ThreeJS] 자주쓰이는 속성과 클래스 정리Note (0) | 2024.01.13 |
[ThreeJS] ThreeJS 기본 구성 요소 (0) | 2024.01.11 |
[ThreeJS] ThreeJS 환경 세팅 (0) | 2024.01.10 |
안녕하세요? 개발자입니다.