![[R3F] About R3F's Hooks](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0l31x%2FbtsI896NVAg%2FfVajx5WwaFFgbOMOG8TdEK%2Fimg.png)
GitHub - Indigochi1d/IntroduceWith3Dweb: R3F로 구현한 Dancing Scroll Introduce 3D Web
R3F로 구현한 Dancing Scroll Introduce 3D Web. Contribute to Indigochi1d/IntroduceWith3Dweb development by creating an account on GitHub.
github.com
🔎서론
위의 프로젝트를 R3F로 구현하면서 사용했던 Hooks들을 자세히 다뤄보려고 한다.
다뤄볼 Hooks들은 아래와 같다.
- useThree
- useFrame
- useGLTF
- useAnimations
- useProgress
- useScroll
1️⃣useThree
useThree | React Three Fiber
React Three Fiber is a React reconciler for Threejs on the web and react-native.
gracious-keller-98ef35.netlify.app
📌제공하는 것
① 기본 객체(renderer, scene, camera 등)에 대한 접근.
② 화면 또는 뷰포트에서 현재 canvas의 사이즈
import { useThree } from "react-three-fiber";
const {
gl, /* WebGL renderer */
scene, /* Default scene */
camera, /* Default camera */
raycaster, /* Default raycaster */
size, /* Bounds of the view (which stretches 100% and auto-adjusts) */
viewport, /* Bounds of the viewport in 3d units + factor (size/viewport) */
aspect, /* Aspect ratio (size.width / size.height) */
mouse, /* Current, centered, normalized 2D mouse coordinates */
clock, /* THREE.Clock (useful for useFrame deltas) */
invalidate, /* Invalidates a single frame (for <Canvas invalidateFrameloop />) */
intersect, /* Calls onMouseMove handlers for objects underneath the cursor */
setDefaultCamera, /* Sets the default camera */
} = useThree();
✏️사용법
import { useThree } from "@react-three/fiber";
export const useThreeExample = () => {
const three = useThree();
useEffect(() => {
three.scene.background = new THREE.Color("black");
},[three.scene])
}
2️⃣useFrame
useFrame | React Three Fiber
React Three Fiber is a React reconciler for Threejs on the web and react-native.
gracious-keller-98ef35.netlify.app
📌기본 형태
useFrame((callback: (state, delta) => void), (renderPriority: number = 0));
📌주요 기능
이 Hook는 매 프레임마다 실행된다.
따라서 효과 실행이나 컨트롤 업데이트와 같은 기민하게 렌더링되어야하는 요소사항에 적합하다.
📌매개변수
매개변수로는 아래의 두 가지를 가진다.
- 콜백함수
- 필수 매개변수
- (state, delta)
- state: 현재 렌더링 상태를 포함하며, 카메라, 시간, Three.js의 주요 객체들을 다룸.
- delta: 이전 프레임 이후 경과된 시간으로, 애니메이션 속도를 시간에 맞춰 조정할 수 있음
- renderPriority
- 선택적 매개변수
- number
- css의 z-index속성과 결은 비슷하지만 이 값이 작을수록 우선순위를 가진다.
- 여러개의 useFrame 콜백이 있을때 이 우선순위대로 적용된다.
import { useFrame } from "react-three-fiber";
const controls = useRef();
useFrame((state) => controls.current.update());
return <orbitControls ref={controls} />;
3️⃣useGLTF
GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber
🥉 useful helpers for react-three-fiber. Contribute to pmndrs/drei development by creating an account on GitHub.
github.com
📌기본 형태
const { scene, nodes, materials, animations } = useGLTF('/path/to/model.glb');
useLoader와 GLTFLoader를 편리하게 쓰기위해 묶은 Hook이다.
📌주요 기능
GLB 파일 형식의 3D 모델을 R3F 애플리케이션에 쉽게 로드하고 사용할 수 있게 해준다.
- GLTF 파일로드
- useGLTF는 주어진 URL경로에서 GLTF파일을 비동기적으로 로드한다.
- 이 때 ①모델 데이터 ②메쉬 ③애니메이션 등을 자동으로 파싱하여 반환한다.
- 로컬 및 원격 파일 지원
- useGLTF는 로컬에 저장된 GLTF파일과 원격 서버에서 제공하는 파일도 쉽게 로드할 수 있다.
📌매개변수
const { scene, nodes, materials, animations } = useGLTF(
'/path/to/model.glb', /* GLTF 파일 경로 */
'/draco-gltf/', /* Draco 압축 해제를 위한 경로 */
(loader) => { /* 확장 기능 적용 */
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco-gltf/') /* Draco 디코더 경로 설정 */
loader.setDRACOLoader(dracoLoader) /* GLTFLoader에 DracoLoader를 추가 */
}
)
- path
- useGLTF 훅의 첫 번째 인수로, 로드할 GLTF 파일의 경로(URL)를 문자열로 전달한다.
- extensions (선택적)
- GLTF 파일 로드 시 사용할 확장 프로그램(예: DRACOLoader 등)을 설정할 수 있다.
- draco (선택적)
- Draco 압축을 해제하기 위한 옵션으로, 압축된 GLTF 파일을 로드할 때 사용된다.
📌반환값
아래에 있는 속성들을 포함할 수 있는 객체를 반환한다. 모든 속성들이 객체안에 반드시 적히지 않아도 된다는 뜻
- scene: 로드된 GLTF 모델의 기본 Scene 객체다. Three.js의 Scene 객체로 반환됨
- nodes: Scene 안에 포함된 모든 노드를 객체 형태로 반환한다. 각 노드는 메쉬, 카메라, 라이트 등 다양한 3D 요소를 포함
- materials: Scene에 사용된 모든 재질(Material)을 객체 형태로 반환한다.
- animations: 모델에 포함된 모든 애니메이션 클립을 배열 형태로 반환한다. 이 클립들은 useAnimations 훅과 함께 사용됨.
- cameras: Scene에 포함된 카메라들을 배열 형태로 반환한다.
- extensions: GLTF 파일에 적용된 확장 기능들을 포함한 객체다.
✏️사용법
import { useGLTF } from '@react-three/drei'
import { useAnimations } from '@react-three/drei'
import { useEffect } from 'react'
function AnimatedModel() {
const { scene, animations } = useGLTF('/model-path.glb')
const { actions, names, mixer } = useAnimations(animations, scene)
useEffect(() => {
/* 특정 애니메이션을 실행 */
const action = actions['AnimationName']
action.play()
/* 컴포넌트가 언마운트될 때 애니메이션 정지 */
return () => {
action.stop()
}
}, [actions])
return <primitive object={scene} />
}
4️⃣useAnimations
GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber
🥉 useful helpers for react-three-fiber. Contribute to pmndrs/drei development by creating an account on GitHub.
github.com
📌기본 형태
const { actions, names, mixer } = useAnimations(animations, scene)
📌주요 기능
이 Hook은 GLTFLoader를 사용해 로드한 3D 모델에 포함된 애니메이션을 다루는데 유용하다.
- 애니메이션 클립 관리: useAnimations는 GLTF 모델에서 로드된 여러 애니메이션 클립을 관리한다.
- 애니메이션 재생 및 중지: 특정 애니메이션 클립을 선택해서 재생하거나 중지할 수 있다.
- 애니메이션의 상태 관리: 각 애니메이션의 진행 상태를 관리하고 제어한다.
📌매개변수
매개변수로는 아래의 두 가지를 가진다.
const { actions, names, mixer } = useAnimations(animations, root)
/*
root의 예 : scene
*/
- animations
- useAnimations Hook의 첫 번째 인수이다.
- GLTF 모델에서 로드한 애니메이션 클립 배열을 전달한다.
- root
- useAnimations Hook의 두 번째 인수이다.
- 애니메이션이 적용될 Root Object를 전달한다.
📌반환값
- actions: 애니메이션 클립들을 key-value 쌍으로 반환한다.
- key는 애니메이션 이름이고, value은 THREE.AnimationAction 객체이다.
- 이를 통해 특정 애니메이션을 재생, 정지, 일시 중지, 속도 조절 등의 작업을 할 수 있다.
- names: 로드된 애니메이션 클립의 이름들을 배열 형태로 반환한다.
- mixer: THREE.AnimationMixer 객체를 반환한다. 애니메이션 혼합 및 조절을 담당하는 Three.js의 핵심 클래스다.
✏️사용법
import { useGLTF } from '@react-three/drei'
import { useAnimations } from '@react-three/drei'
import { useEffect } from 'react'
function AnimatedModel() {
const { scene, animations } = useGLTF('/model-path.glb')
const { actions, names, mixer } = useAnimations(animations, scene)
useEffect(() => {
/* 특정 애니메이션을 실행*/
const action = actions['AnimationName']
action.play()
/* 컴포넌트가 언마운트될 때 애니메이션 정지*/
return () => {
action.stop()
}
}, [actions])
return <primitive object={scene} />
}
- useGLTF Hook으로 GLTF모델을 로드한다.
- useAnimations Hook에 로드된 animations와 scene을 전달해서 애니메이션을 초기화한다.
- useEffect를 사용해서 컴포넌트가 마운트될때 특정 애니메이션을 재생하고 언마운트 될때 애니메이션을 정지한다.
5️⃣useProgress
Loading Models - React Three Fiber
3D Software to the web!
r3f.docs.pmnd.rs
useProgress는 3D모델을 로드하는 동안 진행상태를 추적하는데 사용된다.
📌기본 형태
function Loader() {
const { progress } = useProgress()
return <Html center>{progress.toFixed(2)}% loaded</Html>
}
📌주요 기능
- 로딩 진행 상태 제공
- useProgress는 현재 로드 중인 리소스의 진행률을 백분율로 제공한다.
- 로드된 항목과 남은 항목 추적
- 로드가 완료된 항목의 개수와 남은 항목의 개수를 확인할 수 있다.
- 오류 처리
- 로딩 중에 발생한 오류를 추적할 수 있다.
📌반환값
- progress: 현재 로딩 진행 상태를 백분율(%)로 나타낸 값.
- total: 로드해야 할 전체 항목의 개수
- loaded: 현재까지 로드된 항목의 개수
- errors: 로드 중에 발생한 오류
- item: 현재 로드 중인 항목의 이름
- active: 현재 로딩이 활성화되어 있는지 여부를 나타내는 boolean값.
✏️사용법 ①
import { Canvas } from '@react-three/fiber'
import { useProgress, Html } from '@react-three/drei'
function Loader() {
const { progress } = useProgress()
return <Html center>{progress.toFixed(2)}% loaded</Html>
}
function MyScene() {
return (
<Canvas>
{/* 로더 컴포넌트 */}
<Loader />
{/* 여기서 로드할 모델이나 3D 요소를 추가 */}
{/* <MyModel /> */}
</Canvas>
)
}
export default MyScene
useProgress는 여태껏 정리했던 것처럼 로딩상태에 따라 UI의 업데이트를 관장할 수 있다.
하지만 기본적으로 ThreeJS는 (HTML태그로 봤을때)canvas요소위에 그려지기 때문에 3D Scene내부에서 HTML태그요소를 사용하지 못한다.
이 때 사용되는 것이 HTML 컴포넌트이다.
HTML 컴포넌트를 사용하면 3D Scene내부에서 HTML 태그를 사용할 수 있다.
✏️사용법 ②
function Loader() {
const { progress, loaded, total, item } = useProgress()
return (
<Html center>
<div>
<p>{item}</p>
<p>{progress.toFixed(2)}% loaded</p>
<p>{loaded}/{total} items loaded</p>
</div>
</Html>
)
}
이렇게 하면 현재 로드 중인 파일의 이름과 전체 진행 상태를 포함한 정보를 사용자에게 제공할 수 있다.
6️⃣useScroll
GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber
🥉 useful helpers for react-three-fiber. Contribute to pmndrs/drei development by creating an account on GitHub.
github.com
📌기본 형태
const scroll = useScroll();
📌주요 기능
- scroll 위치 감지
- useScroll은 페이지에서의 현재 위치를 offset인 0~1사이의 값으로 반환한다.
- 예를 들어, 페이지의 50% 지점에 스크롤이 도달하면 scroll.offset 값이 0.5
✏️사용법
import { Canvas } from '@react-three/fiber';
import { ScrollControls, useScroll } from '@react-three/drei';
function Box() {
const scroll = useScroll();
useFrame(() => {
/* 예시: 스크롤에 따라 박스의 y 위치를 변경 */
const y = scroll.offset * 10;
meshRef.current.position.y = y;
});
return (
<mesh ref={meshRef}>
<boxGeometry />
<meshStandardMaterial color="orange" />
</mesh>
);
}
export default function App() {
return (
<Canvas>
<ScrollControls pages={3}>
<Box />
</ScrollControls>
</Canvas>
);
}
'FrontEnd > 3D Web' 카테고리의 다른 글
[R3F] Migration - ThreeJs to R3F (0) | 2024.08.16 |
---|---|
[ThreeJS] 자주쓰이는 속성과 클래스 정리Note (0) | 2024.01.13 |
[ThreeJS] ThreeJS 기본 구성 요소 (0) | 2024.01.11 |
[ThreeJS] ThreeJS 환경 세팅 (0) | 2024.01.10 |
안녕하세요? 개발자입니다.