Post

R3F기초

R3F기초

Overview

국비학원이 1주일밖에 남지 않았다. 지금까지 했던 프로젝틀르 노션에 정리해두었는데, 프론트엔드라면 예쁜! 포트폴리오도 있어야하지 않겠는가!!라는 생각으로 인터렉티브한 포트폴리오를 많이 봤다. 학원 시작 전부터 배우고 싶었던 3D구현을 포트폴리오에서 사용하고싶어서 이제와서 인프런 강의를 결제 했다. 다들 빨리 취업하고 싶으면 다른사람들이 만들어둔 템플릿을 이용하면 금방이라고 하지만, 디자이너 출신을 강조하면서 어떻게 그럴 수 있겠습니까… 남들과 똑같이 생긴 포트폴리오는 생각해본적이 없어서 신선했달까? 여튼 코딩의세계 한태재님의 R3F를 공부하면서 블로그로 가볍게 정리 해두려고 한다.

3D구성요소

image

  1. Scene : 물체, 카메라 및 조명을 배치할 수 있는 공간
  2. Camera : 공간을 바라보는 것
  3. Renderer : 공간을 바라보는것(Camera)을 보여주는 것

install

1
2
3
npm install three @types/three @react-three/fiber  //R3F
npm install @react-three/drei //마우스 컨트롤
npm install leva@0.9.34 --save-dev //GUI 컴트롤

R3F(React Three Fiber)

Canvas

Canvas안에서 모든 3D요소를 그릴수 있다. 내부에 div같은 태그가 들어가면 에러가 뜨니 주의!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Canvas } from "@react-three/fiber";
import ThreeElement from "./ThreeElement";

function App() {
  return (
    <>
      <Canvas>
        <ThreeElement />
      </Canvas>
    </>
  );
}

export default App;

mesh

mesh는 형태(Geometry)와 질감(meshStandardMaterial)을 포함한다. Geometry는 꼭 필요하지만, meshStandardMaterial는 꼭 필요하지는 않다. 하지만 이미지처럼 명암없는 회색이 형태가 보인다. image
그런 의미에서 빛(directionalLight)도 없으면 이미지처럼 까만 형태만 보인다. image

1
2
3
4
5
6
7
8
9
10
11
export default function ThreeElement() {
  return (
    <>
      <directionalLight position={[5, 5, 5]} />
      <mesh>
        <boxGeometry />
        <meshStandardMaterial color="red" />
      </mesh>
    </>
  );
}

Renderer

@react-three/fiber의 useThree, useFrame는 Canvas와 동일한 파일에서 사용하면 에러가 뜨니 주의해야한다. useThree는 필요한 값을 가져와서 사용하면 된다, size(뷰포트), gl(렌더러), scene, camera 같은것을 불러올 수 있다. useFrame은 화면을 프레임별로 새로 그려준다. 동작이 들어간다면 useFrame을 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import React, { useRef } from "react";
import * as THREE from "three";
import { useThree, useFrame } from "@react-three/fiber";

export default function ThreeElement() {
  const { size, gl, scene, camera } = useThree();
  const boxRef = useRef<THREE.Mesh>(null);


  useFrame((state, delta) => {
    boxRef.current.rotation.x += delta; //delta만큼씩 X축으로 회전
    boxRef.current.position.y -= 0.01; //-0.01만큼씩 y축으로 이동
    boxRef.current.scale.z += 0.01; //0.01만큼씩 Z축으로 크기 증가
  });

  return (
    <>
      <directionalLight position={[5, 5, 5]} />
      <mesh
        ref={boxRef}
        rotation={[
          THREE.MathUtils.degToRad(45),
          THREE.MathUtils.degToRad(45),
          0,
        ]}
      >
        <boxGeometry />
        <meshStandardMaterial color="red" />
      </mesh>
    </>
  );
}

Camera

Perspective Camera(3D)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Canvas } from "@react-three/fiber";
import ThreeElement from "./ThreeElement";

function App() {
  return (
    <>
      <Canvas
        camera=
      >
        <ThreeElement />
      </Canvas>
    </>
  );
}

export default App;

Orthographic Camera(2D)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import "./App.css";
import { Canvas } from "@react-three/fiber";
import ThreeElement from "./ThreeElement";

function App() {
  return (
    <>
      <Canvas
        orthographic 
        camera=
      >
        <ThreeElement />
      </Canvas>
    </>
  );
}

export default App;

참고자료

인프런 React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
Camera helper demo

This post is licensed under CC BY 4.0 by the author.