React-Three-Fiber 정리

robin Han·2024년 3월 17일

Three.js

three js 는 자바스크립를 기반으로한 WebGl엔진을 사용해서 3D인터렉티브한 웹을 쉽게 만들수있는 라이브러리이다
HTML5의 Canva로 그려진다.

three.js is a JavaScript-based WebGL engine that can run GPU-powered games and other graphics-powered apps straight from the browser. The three.js library provides many features and APIs for drawing 3D scenes in your browser.
-mdn web doc

그래픽을 계산하여 렌더링하는 Hardware rendering과 Software rendering 있는데

software rendering: cpu로만 계산하여 렌더링
Hardware rendering: GPU의 도움을 받아 그래픽을 계산하여 렌더링

GPU의 도움을 받아 렌더링을 하기때문에 cpu의 부담을 덜어주어 작업을 분산해준다.

HTML5의 canvas를 통해 좌표로 그려지는 2D 또 3D를 통해 여러 그래픽을 그려낼수있는데 코드가 상당히 복잡해지기 때문에 three.js를 통해 보다 쉽게 구현가능하고 이런 three.js 기반으로 만들어진 renderer가 R3F (React three fiber)이다.

R3F를 사용하는 큰이유는 여러가지 built-in hook(useFrame, useThree)을 사용해서 애니메이션또는 객체에 접근이 쉽고, 또한 개발 생태계에서 사용하는 여러 추가적인 요소들을 사용할수있어서이다 특히 drei 같은 helper 라이브러리는 three.js를 더욱 쉽게 구현하게 도와준다.

웹에서 그래픽을 표현하는 방식 3가지

  • DOM : Pixel 기반이라 자세히 들어가면 깨진다
  • SVG : Vector이기 때문에 자세히 들어가도 깨지지않는다
  • Canvas: Pixel 기반이라 자세히 들어가면 깨진다

DOM/SVG :
→ HTML , XML 문법으로 작성할수있다.
→ 검색기능이 가능하다. SEO 가능하다.
Canvas:
→ JS로 작성가능하지만 검색기능을 할수없다 텍스트 검색 불가
→ DOM와 같이 픽셀이기때문에 깨짐
→ 성능적인 측면으로 우수 하지만 많은 요소일때만 차이가 난다 . (10000개 이상 요소들)

대표적으로 사용하는 라이브러리
SVG: D3.js
Canvas:
2D → p5.js, pixi.js(2D-Game)
3D → Three.js, Babylon.js

R3F + Three.js 에서 사용하는 개념 정리

Object3D: 가장 base 클래스로 3D.공간을 만들기 위한 속성들과 오브젝트를 조절하게 해주는 클래스 Scene 또한 여기에 들어가 있다. 3D를 위한 컨테이너

Mesh: 실제 모델로 사용되는 도구들을 사용. (Geometry객체 + material 객체)들을 활용해서 mesh 객체를 생성하여 scene에 추가.

Scene: 실제 찍히고 있는 장면

Camera: Scene 을 찍고있는 카메라

Renderer: 카메라를 통해 보이는 화면단

영화촬용을 예로 들면...
scene: 실제 찍히는 인물과 사물들
camera: scene을 찍고있는 카메라(위치, 각도, etc.. )
renderer: 카메라로 보이는 화면, 촬영된 화면

속성들

  • position: 카메라 또는 화면의 위치
  • near: 가깝게 볼것인지 너무 멀리지정하면 앞부분이 짤린다
  • far : 얼마나 멀리 볼것인지 (인지할것인지) 너무가깝게 지정하면 뒤에부분이 짤린다
  • zoom: 가깝게 보는 시각
  • fov: 시야각

기존에 랜더링을 할때는 requestAnimationFrame 함수와 Renderer로 계속 호출을 해야한다, 하지만 R3F 에서는 useThree 랑 useFrame으로 미리 지정되어있는 함수를 호출해서 사용가능하다

useThree: size, gl ,camera, scene
useFrame: 
	state= webGL , frame으로 state 반영
	delta= 랜덩링된 시간

Camera

  • perspective camera (원근감)
  • orthographic camera (원근감 X)
  • three-fiber 카메라 기본 값은 perspective camera

orthographic camera 사용할려면 canvas에 orthographic 프로퍼티 따로 사용 따로 추가해줘야한다. + zoom(default 1)

  • orthographic camera 는 2D여서 따로 fov(field of view)가 존재하지않는다. 그래서 zoom을 이용해서 거리를 바꾸어준다
<Canvas
	//orthographic
	camera={{
		zoom: 100,
		near: 1, 
		far: 20,
		fov: 75, 
		position:[3,3,0]
	}}
> 
<ThreeElement/>
</Canvas>

Scene

Mesh :scene에 추가되는 객체 (geometry, material)

  • geometry : 모형, 구조 - HTML
    Triangle 로 이루어진 모형, 삼각형으로 모형을 만드는데 최소한의 삼각형으로 만들수있는걸 목표로 해야된다 (예: rectangle → 최소 2개)

three.js에 원하는 모형이 없을때 직접 만들거나 인테넷에서 찾을수있다.

3D-modeling: 모델링은 4각형이 만들기 편하다 하지만 컴퓨터가 이해하기위해서는 3각형으로 변환해야된다.

  • material: 컬러, 텍스쳐 - CSS

geometry는 mesh 없이 사용불가하고, material은 geometry없이 사용이 불가능하다, 모형이 없기 때문에 당연하다.


const geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 
const cube = new THREE.Mesh( geometry, material ); 
scene.add( cube );
....
<mesh
        ref={boxRef}
        rotation={[
          THREE.MathUtils.degToRad(45),
          THREE.MathUtils.degToRad(45),
          0,
        ]}>
        <boxGeometry />
        <meshStandardMaterial color="red" />
 </mesh>

list of geometry
https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry

Control & Helper

구현을 하다보면 다양한 각도에서 보고, 특히 leva 같은 helper는 구현한 결과를 확인할때 도움이 많이 되었다

  • gridHelper :
    바탕에 grid를 표시해준다
    args={[size ,division, colorCenterLine, colorGrid]}
    - size: size of the grid (default: 10)//10meter
    - division : number of division (default: 10)//10meter
    - colorCenterLine: color of center line
    - color Grid : color of lines of the grid

  • leva
    GUI component that you can interact with scene
    leva는 useControls를 사용할수있게 도와주는거일뿐, 바탕색을바꾸는건 three.js만으로도 가능하다. 미리보기 가능

....control 
const grid = useControls({
    segment: { value: 10, min: 2, max: 100, step: 1 },
  });
<gridHelper args={[10, grid.segment]} />
  
.....

import {useControls} from 'leva'
const color = useControls({
  value: 'green',
})

//Cavas 바탕색 바꾸기 
<Canvas>
  <color attach="background" args={[color.value]} />
	<color attach="background" args={[green]}/>
</Canvas>

Object: Rotation, Position , Scale

Position: 해당 Object에 위치
Scale: Object의 크기
Rotation: Object 의 각도, Radiant를 사용하고 있어서, THREE.MathUtils.degToRad(0) 을 사용해서 degree로 바꾸는 작업을 해줘야한다.

R3F mesh 구현 3가지 방법

  1. scene.add(mesh)
const geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 
const cube = new THREE.Mesh( geometry, material ); 
scene.add( cube );
  1. mesh Properties
<mesh geometry={new THREE.BoxGeometry(1,1,1)}>
	<meshStandardMaterial color="blue"/>
</mesh>
  1. Box R3F/drei
import {Box} from "@react-three/drei"
<Box position={[-2,0,0]}>
	<meshStandardMaterial color="blue"/>
</Box>

Wireframe:
mesh 하나에 하나의 material 이 들어간다 따라서 wireframe 처럼 표시하고싶으면 따로 mesh를 추가해서 해야된다.

이번에 three.js + R3F을 배우면서 공부하며서 많은 속성들과 3D 그래픽을 다룰수있게되어 재밌으면서도 어떻게 프로젝트에 반영할지 고민이 많이 되었다. 여러가지 시도를 할수있고 무궁무진한 가능성을 가지고있어서 다양한걸 시도해보면서 추가할예정이다.

0개의 댓글