[React] Three.js를 적용해보자.

Lee JuHyeon·2021년 10월 21일
16

React

목록 보기
1/6
post-thumbnail

리액트를 이용해 포트폴리오 사이트를 만들던 중 문제에 봉착했다.

HTML, CSS, JS 만으로 인터랙티브한 웹을 만드는게 너무 어려워!

그래서 Awwwards 사이트를 구경해보니 많은 웹페이지들이 WebGL을 사용한 것을 알게되었다.

1. WebGL

WebGL

웹쮜엘...?

SI업체를 다닐때 디자이너들이 어썸하고 인터랙티브한 디자인의 웹페이지를 얘기하면
webgl을 사용해야 가능하다며 입구컷하던 개발자들을 자주 보고는 했었다.

나도 어떻게 작동되는 녀석인지는 잘 모르고 어렴풋이 이름만 알고 있던 건데
사실 인터랙티브한 웹페이지를 만들고 싶었기에 이참에 배워보려고 한다!

WebGL이란

Web Graphics Library의 약자로 웹에서 2D 및 3D를 렌더링하기위한 JavaScript API이다.
OpenGL ES 2.0 기반으로 HTML5의 canvas 위에 그려진다는데 사실 잘 모르겠다.

아무튼 WebGL을 사용하면 웹상에서 구현하기 힘들었던 동적인 화면을 효과적으로 보여줄 수 있는 모양이다.


2. Three.js

나같은 개발찐따는 WebGL에 대해 찾아봐도 도통 어떻게 쓰는지 모른다! (파워당당)
그래서 일반적인 웹개발자들이 쉽게 webgl을 활용할 수 있도록 친절히 라이브러리를 만들어 놓았다.

Three.js 기초

Three.js는 Renderer , Scene , Camera 라는 핵심 객체들로 이루어져 있다.
RendererSceneCamera의 객체를 넘겨받아 카메라 안의 3D 씬의 일부를 2D 이미지로 렌더링 한다.

Scene에는 다수의 Mesh , Light , group , Object3D가 트리구조로 쌓여있고,
Camera 객체는 Scene 안에 포함할 수도 있고, 밖에 둘 수도 있다.

Mesh 객체는 어떠한 Material 안에 하나의 geomatry를 그리는 객체인데,

geometry는 기하학 객체의 정점 데이터라고 한다. 구, 정육면체, 면, 사람, 강아지 등등 다양한 것이 될수 있다. Three.js내에 기본적으로 built-in 되어있는 객체도 존재한다.

Material은 기하학 객체를 그리는데 사용하는 표면 속성으로, 색이나 밝기 등을 지정할 수 있다고 한다.

이제 기본적으로 three.js 라는 놈이 어떻게 작동하는지 알았으니 적용해보도록 하자!


리액트에 적용하기

먼저 리액트에서 three.js를 사용하기 위해서는 몇가지 패키지를 설치해야한다.

  • Three
  • react-three-fiber
  • react-three/drei
  • react-three-fiber는 three.js를 리액트 문법에 맞게 사용할 수 있도록 해주는 패키지이고,
    react-three/drei는 그걸 더 쉽게 도와주는 라이브러리이다.

    npm install three
    npm install @react-three/fiber
    npm install @react-three/drei
    

    이렇게 설치해주면 끝!
    이 외에도 몇가지 라이브러리들이 더 있는데
    https://docs.pmnd.rs/react-three-fiber 여기서 확인할 수 있다.


    기본 뼈대

    react-three-fiber를 이용하여 코드를 작성하면 이렇다

       
       import {Canvas} from '@react-three/fiber';
       
       
       const Cube = () => {
       	return(
           <div className="App">
             <Canvas>
             </Canvas>
           </div>
         );
       };

    이것이 리액트에서 three js를 사용하기 위한 기본이다.

    vanilla js에서는 three js를 사용하기 위해

    var scene = new THREE.Scene(); 
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); 
    var renderer = new THREE.WebGLRenderer(); 

    위와 같은 코드를 선언해 놓아야 하지만 리액트에서는 라이브러리가 기본적으로 처리해 주는듯.
    (그래도 기본적인 것 외에는 리액트도 선언해줄것이 많다.)


    정육면체 만들기

    three js에 내장된 코드들을 이용하여 간단한 정육면체 큐브를 만들어 보았다.

    const Cube = () => {
        return(
        <div className="App">
          <Canvas>
            <Mesh position={[0,0,0]}>
              <boxBufferGeometry attatch="geometry" />
              <meshLambertMaterial attatch="material" color="orange" />
            </Mesh>
          </Canvas>
        </div>
      );
    };
    

    canvas안에 mesh 객체를 넣어주면 geometry와 material을 따로 선언할 필요없이 정육면체가 만들어질 것이다.

    boxBufferGeometry는 three js에 내장되어있는 박스모양의 객체이다.

    하지만 아마 이대로라면 검은색 사각형만 덩그러니 있을 것이다.
    이리저리 건드려도 움직이지 않는 그냥 사각형이다.


    three-fiber/drei

    그래서 사용할 라이브러리 three-fiber/drei.
    이 라이브러리를 이용하면 렌더링한 물체의 컨트롤이나 광원 등을 조작하기 편리해진다.

        
    import {OrbitControls} from '@react-three/drei';    
    
    const Cube = () => {
        return(
        <div className="App">
          <Canvas>
            <OrbitControls/>
            <Mesh position={[0,0,0]}>
              <boxBufferGeometry attatch="geometry" />
              <meshLambertMaterial attatch="material" color="orange" />
            </Mesh>
          </Canvas>
        </div>
      );
    };
    

    Cansvas 요소에 <OrbitControls>를 추가한 것 만으로도 물체를 이리저리 움직일 수 있다!
    이 외에도 다양한 컨트롤 방법이 존재함.

    그러나 아직 검은 물체일 것이다

    여기에

        
    import {OrbitControls} from '@react-three/drei';    
    
    const Cube = () => {
        return(
        <div className="App">
          <Canvas>
            <OrbitControls/>
            <ambientLight intensity={0.5}/>
            <spotLight position={[10, 15, 10]} angle={0.3}/>
            <Mesh position={[0,0,0]}>
              <boxBufferGeometry attatch="geometry" />
              <meshLambertMaterial attatch="material" color="orange" />
            </Mesh>
          </Canvas>
        </div>
      );
    };
    

    ambientLight , spotLight 를 추가하여 광원을 입혀주면 입체적인 큐브가 리액트 웹에서 구현되었다!

    이걸 좀더 꾸미고 싶다면

        import {Stars} from '@react-three/drei'
        <Canvas>
          ...
          <Stars/>
          ...
        </Canvas>

    요렇게 추가해주면 별이 빛나는 우주공간이 뚝딱 만들어진다.


    마치며

    리액트에서 three js를 사용하는 아주아주아주아주 기본적인 예제를 만들어봤다.
    three js 자체가 만들어진지 오래되었기도 하고 리액트로도 잘 변환되어있어서
    오히려 바닐라js에서 만드는 것보다 간단하지 않나싶다.

    하지만 내가 만들고 싶은건 이런 사각형이 아니기 때문에 여러가지를 만들어볼 예정.
    다음엔 텍스트를 3D로 구현하는 부분을 공부해봐야겠다

    profile
    인터랙티브 웹에 관심이 많습니다

    1개의 댓글

    comment-user-thumbnail
    2023년 2월 8일

    예제 정말 도움이 되었습니다! 블로깅 감사합니다👍

    답글 달기