react 에서의 three js

YOUNGJOO-YOON·2021년 6월 9일
5

tools

목록 보기
3/8

TOC

1.Three.js

2.React에서의 Three.js


1. Three.js

Three.js 자체는 제작된지 꽤나 많은 시간이 지난 js 3d modeling 라이브러리이다.

Three.js
공식 홈페이지에서 한글 설명을 어느정도 지원하고 있기 때문에 살펴보면 도움이 될 것이다.
Apple의 홈페이지에서도 사용할 정도로 인기있는 라이브러리임은 틀림 없다.

필자는 js를 알면 React는 알아서 따라온다고 생각하는 사람이다.
하지만 Three.js만큼은 뭔가 느낌이 다르다.

Three.js에서 제공하는 기본 튜토리얼을 확인해보자 아래는 캔버스에
녹색 정육각형을 생성하고 빙빙 돌려대는 예제이다.

import * as THREE from 'three';
let camera, scene, renderer;
let geometry, material, mesh;

init();

function init() {

	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
	camera.position.z = 1;

	scene = new THREE.Scene();

	geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
	material = new THREE.MeshNormalMaterial();

	mesh = new THREE.Mesh( geometry, material );
	scene.add( mesh );

	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setAnimationLoop( animation );
	document.body.appendChild( renderer.domElement );

}

function animation( time ) {

	mesh.rotation.x = time / 2000;
	mesh.rotation.y = time / 1000;

	renderer.render( scene, camera );

}

js파일은 위와 같다. 한 줄씩 훑어보자

function init() {

	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
	camera.position.z = 1;

	scene = new THREE.Scene();

	geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
	material = new THREE.MeshNormalMaterial();

	mesh = new THREE.Mesh( geometry, material );
	scene.add( mesh );

	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setAnimationLoop( animation );
	document.body.appendChild( renderer.domElement );

}

auto CAD 비슷한 것을 해보았다면 그것과 비슷한 것을 js로 한다고 보면 된다.

중요한 개념은 약 4가지

  1. camera
  2. scene
  3. mesh
  4. material
  1. camera

말 그대로 카메라의 시점을 말한다.

camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
	camera.position.z = 1;

아직 위의 PerspectiveCamera 함수가 무엇을 계산하는지는 모르지만
우리는 이게 카메라의 설정을 세팅하는 함수임을 알아낼 수 있다.


  1. scene

scene는 Three.js로 생성한 material을 담아내는 그릇이다. html의 캔버스 위에 담기는 최종적인 변수라고 생각해도 된다.


  1. mesh

    mesh는 Polygon mesh를 의미한다.
    기본적으로 폴리곤 모델링으로 만들어지며 실제 제작해보면 poly 수를 늘리면 둥글둥글해지고 낮추면 각진 모형이 된다.

그렇다고 전부 코딩으로 하나 하나 폴리곤을 만들어내야 하느냐?
그렇지 않다. 기본적으로 제공하는 기본 mesh도 존재한다.

const geometry = new THREE.BoxGeometry( 1, 1, 1 );

예를 들면 위와 같이 BoxGeometry는 이미 만들어진 박스를 제공해준다.

BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)


  1. material

실제 mesh에 담기는 모델링 된 물체를 말한다.
이 물체와 배경을 얻기 위해 three.js가 존재하는 것이다.


Three.js를 알아보았는데 바닐라 js를 사용하는 일은 거의 없으므로 React는 이 Three.js를 어떻게 사용하는지 알아보자.

2. React 에서의 Three.js

21/06/09일 기준 npm dependencies

npm i three
npm i react-three-fiber => @react-three/fiber
npm i drei => @react-three/drei
https://www.npmjs.com/package/drei

react에서 Three.js를 편히 사용하기 위해서는 적어도 위의 두 패키지는 설치해야 한다.

이전 버전인 react-three-fiber는 @react-three/fiber로 변경되었고 다운로드하려고 하면 에러창이 뜬다.


React에서 사용하기 전에 boiler plate code를 살펴보자.

import React from 'react';
import {Canvas,useFrame} from '@react-three/fiber';
//import {OrbitControls} from '@react-three/drei';

export default function(){
  return(
    <>
      <Canvas>
        
      </Canvas>
    </>
  )
}

코드를 보게되면 상당히 뭐 별거 없는 상태다.

Canvas는 우리가 제작한 mesh를 얹어 놓을 판이다.
frame은 three.js로 제작한 material에 animation 효과를 부여하는 동안 몇 frame으로 움직이게 할 것인지를 정의할 때 사용된다.

react-three/fiber를 사용해 코인을 만들고 돌리는 예제를 만들어보자.


검은색 코인이 빙빙 돌고 있다.

function CoinMesh() {
  const mesh = useRef(null);
  useFrame(() => (mesh.current.rotation.y =  mesh.current.rotation.z += 0.01)); // #2
  return (
    <mesh ref={mesh} scale={0.7}>
      <cylinderBufferGeometry args={[1, 1, 0.3, 50]} /> // #1
      <meshLambertMaterial attach="material" color="#ff9800" />
    </mesh>
  );
}

coin mesh는 위와 같이 만들어졌다.

#1의 설명

mesh는 material을 담는 matrix 판이라고 보면 된다.

material props를 주는 경우도 있고 mesh props를 주는 경우도 있으니 이를 잘 구분해야 한다.

<cylinderBufferGeometry args={[1, 1, 0.3, 50]} />

three.js에 기본 내장된 geometry를 사용하면 이처럼 props를 전달할 수 있게 되는데

위에서 살펴본 js는 .연산자를 통해 속성에 접근한다면 react에서는 props를 통해 속성에 접근할 수 있다.

또한 주의할 것이 react-fiber에서는 대소문자를 잘 구별해야 한다.

react-fiber는 BoxGeometry를 가져오는게 아닌 boxGeometry를 가져오는 것이다.

#2의 설명

  const mesh = useRef(null);
  useFrame(() => (mesh.current.rotation.y =  mesh.current.rotation.z += 0.01)); // #2
  return (
    <mesh ref={mesh} scale={0.7}>

mesh는 react hooks의 useRef를 사용하고 mesh 태그를 가리킨다
useFrame은 mesh를 어떻게 회전시킬 것인지를 나타내준다.

여기서 useRef를 사용했으므로 current를 통해 mesh에 접근해야 한다는 것을 잊지 말자.

또한 mesh의 props로 scale값이 주어졌는데 이는 css의 scale과 동일하게 작동한다.


정리하자면 이상하게도 react에서의 three.js가 더 쉬워보인다는 것이다.

아무래도 html과 js가 완전히 붙어있기 때문이 아닐까라는 생각을 하게 된다.

profile
이 블로그의 글은 제 생각을 정리한 글과 인터넷 어딘가에서 배운 것을 정리한 글입니다. 출처는 되도록 남기도록 하겠습니다. 수정 및 건의 오류 등이 있으면 언제든지 댓글 부탁드립니다.

0개의 댓글