본문 바로가기
Web Study/React 관련

babylonjs + react 간단하게 다뤄보기

by 쿠리의일상 2023. 9. 29.

https://doc.babylonjs.com/communityExtensions/Babylon.js+ExternalLibraries/BabylonJS_and_ReactJS#how-to-usebabylonjs-with-react 

 

Babylon.js and React | Babylon.js Documentation

Babylon.js and React How to useBabylon.js with React For anyone interested, it is not difficult to integrate Babylon.js into a React application. What you need It's up to you if you choose Create React App or a custom project; only how to load Babylon.js i

doc.babylonjs.com

 

업무 중에 혹시 사용될까 싶어서 공부 중인 바빌론... threejs 도 찍먹해봤는데 마이크로소프트가 만든 라이브러리라 그런지 완성도가 높은 것 같다. 다만 문서가 다 영어라 열심히 해석하면서 배워나가야겠다...ㅜㅜ

 

 

기본 씬 컴포넌트

engine 과 scene 을 설정해준다.

import { useEffect, useRef } from "react";
import { Engine, Scene } from "@babylonjs/core";

export default ({ antialias, engineOptions, adaptToDeviceRatio, sceneOptions, onRender, onSceneReady, ...rest }) => {
  const reactCanvas = useRef(null);

  // set up basic engine and scene
  useEffect(() => {
    const { current: canvas } = reactCanvas;

    if (!canvas) return;

    const engine = new Engine(canvas, antialias, engineOptions, adaptToDeviceRatio);
    const scene = new Scene(engine, sceneOptions);
    if (scene.isReady()) {
      onSceneReady(scene);
    } else {
      scene.onReadyObservable.addOnce((scene) => onSceneReady(scene));
    }

    engine.runRenderLoop(() => {
      if (typeof onRender === "function") onRender(scene);
      scene.render();
    });

    const resize = () => {
      scene.getEngine().resize();
    };

    if (window) {
      window.addEventListener("resize", resize);
    }

    return () => {
      scene.getEngine().dispose();

      if (window) {
        window.removeEventListener("resize", resize);
      }
    };
  }, [antialias, engineOptions, adaptToDeviceRatio, sceneOptions, onRender, onSceneReady]);

  return <canvas ref={reactCanvas} {...rest} />;
};

바빌론 공식 문서에 보면 나와있는 내용이다. 만들어준 씬 컴포넌트에 props 를 주어 3D 환경을 구축해야한다.

 

    <Secene antialias onSceneReady={onSceneReady} onRender={onRender} id="my-canvas" />

요렇게 쓰인다!

 

씬 컴포넌트가 사용될 나머지 설정들

FreeCamera, HemispericLinght, MeshBuilder 를 지정해주고 CreateGround 로 모델링 해줄 곳을 정의한다.

import { FreeCamera, Vector3, HemisphericLight, MeshBuilder } from "@babylonjs/core";
import Secene from "./Secene";

let box;

const onSceneReady = (scene) => {
  const camera = new FreeCamera("camera1", new Vector3(0, 5, -10), scene);
  camera.setTarget(Vector3.Zero());

  const canvas = scene.getEngine().getRenderingCanvas();
  camera.attachControl(canvas, true);

  const light = new HemisphericLight("light", new Vector3(0, 1, 0), scene);
  light.intensity = 0.7;
  box = MeshBuilder.CreateBox("box", { size: 2 }, scene);
  box.position.y = 1;
  MeshBuilder.CreateGround("ground", { width: 6, height: 6 }, scene);
};

const onRender = (scene) => {
  if (box !== undefined) {
    const deltaTimeInMillis = scene.getEngine().getDeltaTime();

    const rpm = 10;
    box.rotation.y += (rpm / 60) * Math.PI * 2 * (deltaTimeInMillis / 1000);
  }
};

export default () => (
  <>
    <Secene antialias onSceneReady={onSceneReady} onRender={onRender} id="my-canvas" />
  </>
);

onRender 로 씬이 그려지면 만들어줄 box 의 행동을 지정해줄 수 있다. 위처럼 rotation 을 지정해주면 빙글빙글 돈다.

빙글빙글

이정도가 공식 문서에 기재된 아주 기본이고, 자세히 파려면 https://github.com/brianzinn/react-babylonjs

 

GitHub - brianzinn/react-babylonjs: React for Babylon 3D engine

React for Babylon 3D engine. Contribute to brianzinn/react-babylonjs development by creating an account on GitHub.

github.com

여기를 봐야하는 것 같다. 

위 깃헙을 대충 살펴보면 엔진이나 씬 등 리액트 전용 컴포넌트를 위처럼 직접 정의해주는 게 아니라 컴포넌트처럼 사용할 수 있게 만들어진 라이브러리로 추정된다.