Research/Web

20240708-overview-babylon.js

RIEM 2024. 10. 14. 13:12
728x90

What is Babylon.js?

  • Babylon.js is

What are the key elements of Babylon.js?

  • scene, camera, light, and object
  • scene for world model, camera to view, light to illuminate, and object made of meshes
  • Babylon engine works with webGL, audio, etc in low level and this enable 'scene' to create the world model

What kind of formats are in Babylon.js?

  • .babylon or .glb
  • .glb stands for GL Transmission Format Binary, which is open standard file format for 3D contents. This is designed to load and transfer 3d things such as model, scene, animation, etc. It's structure consists of JSON-based text or binary file.

What's the difference between glTF and glb?

  • file structure : glTF is made of JSON, binary, texture, etc. But glb is made of single binary file
  • data format : glTF is JSON but glb is binary.
  • volume : glTF is generally bigger than glb which is comressed
  • loading speed : glTF can be slower due to multiple types of files to load. But glb can be faster because there is only one file type
  • usage : glTF is flexible in develop process. But glb is efficient in deploy process.

How to import in web app?

// get CDN (this address is only for learning)
<script src="https://cdn.babylonjs.com/viewer/babylon.viewer.js"></script>

// place <babylon> element
<babylon model="Path to File"></babylon>

How it works?

  • apply material in order to add color and texture to our meshes

How to use babylon.js in React?

// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)
// src/BabylonScene.tsx
import React, { useEffect, useRef } from "react";
import * as BABYLON from "babylonjs";
import "babylonjs-loaders";

const BabylonScene = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    const engine = new BABYLON.Engine(canvasRef.current, true);

    const createScene = () => {
      // 세상 생성
      const scene = new BABYLON.Scene(engine);

      // 카메라 생성
      const camera = new BABYLON.ArcRotateCamera(
        "camera",
        -Math.PI / 2,
        Math.PI / 2.5,
        15,
        new BABYLON.Vector3(0, 0, 0),
        scene
      );
      camera.attachControl(canvasRef.current, true);

      // 조명 생성
      new BABYLON.HemisphericLight(
        "light",
        new BABYLON.Vector3(1, 1, 0),
        scene
      );

      // 박스 생성
      BABYLON.MeshBuilder.CreateBox("box", {}, scene);

      return scene;
    };

    const scene = createScene();

    engine.runRenderLoop(() => {
      scene.render();
    });

    const handleResize = () => {
      engine.resize();
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
      engine.dispose();
    };
  }, []);

  return (
    <canvas
      id="renderCanvas"
      ref={canvasRef}
      style={{ width: "100%", height: "100%" }}
    />
  );
};

export default BabylonScene;

함수 모듈화하기

import React, { useEffect, useRef } from "react";
import * as BABYLON from "babylonjs";
import "babylonjs-loaders";

const BabylonScene = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    const engine = new BABYLON.Engine(canvasRef.current, true);

    const createScene = () => {
      const scene = new BABYLON.Scene(engine);

      const camera = new BABYLON.ArcRotateCamera(
        "camera",
        -Math.PI / 2,
        Math.PI / 2.5,
        10,
        new BABYLON.Vector3(0, 0, 0)
      );
      const light = new BABYLON.HemisphericLight(
        "light",
        new BABYLON.Vector3(1, 1, 0)
      );

      const ground = buildGround();
      const box = buildBox();
      const roof = buildRoof();

      return scene;
    };

    // Build Functions
    const buildGround = () => {
      const groundMat = new BABYLON.StandardMaterial("groundMat");
      groundMat.diffuseColor = new BABYLON.Color3(0, 1, 0);

      const ground = BABYLON.MeshBuilder.CreateGround("ground", {
        width: 10,
        height: 10,
      });
      ground.material = groundMat;
    };

    const buildBox = () => {
      const boxMat = new BABYLON.StandardMaterial("boxMat");
      boxMat.diffuseTexture = new BABYLON.Texture(
        "https://assets.babylonjs.com/environments/cubehouse.png"
      );

      // options parameter for seeting different images on each side of house
      const faceUV = [];
      faceUV[0] = new BABYLON.Vector4(0.5, 0.0, 0.75, 1.0); // rear side
      faceUV[1] = new BABYLON.Vector4(0.0, 0.0, 0.25, 1.0); // front
      faceUV[2] = new BABYLON.Vector4(0.25, 0, 0.5, 1.0); // right
      faceUV[3] = new BABYLON.Vector4(0.75, 0, 1.0, 1.0);

      const box = BABYLON.MeshBuilder.CreateBox("box", {
        faceUV: faceUV,
        wrap: true,
      });
      box.material = boxMat;
      box.position.y = 0.5;

      return box;
    };

    const buildRoof = () => {
      // for texture
      const roofMat = new BABYLON.StandardMaterial("roofMat");
      roofMat.diffuseTexture = new BABYLON.Texture(
        "https://assets.babylonjs.com/environments/roof.jpg"
      );

      const roof = BABYLON.MeshBuilder.CreateCylinder("roof", {
        diameter: 1.3,
        height: 1.2,
        tessellation: 3,
      });
      roof.material = roofMat;
      roof.scaling.x = 0.75;
      roof.rotation.z = Math.PI / 2;
      roof.position.y = 1.22;

      return roof;
    };

    const scene = createScene();

    engine.runRenderLoop(() => {
      scene.render();
    });

    const handleResize = () => {
      engine.resize();
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
      engine.dispose();
    };
  }, []);

  return (
    <canvas
      id="renderCanvas"
      ref={canvasRef}
      style={{ width: "100%", height: "100%" }}
    />
  );
};

export default BabylonScene;

glb 파일 임포트해서 보여주기

    const createScene = () => {
      const scene = new BABYLON.Scene(engine);

      const camera = new BABYLON.ArcRotateCamera(
        "camera",
        -Math.PI / 2,
        Math.PI / 2.5,
        15,
        new BABYLON.Vector3(0, 0, 0)
      );
      camera.attachControl(engine, true);
      const light = new BABYLON.HemisphericLight(
        "light",
        new BABYLON.Vector3(1, 1, 0)
      );

      BABYLON.SceneLoader.ImportMeshAsync(
        "",
        "https://assets.babylonjs.com/meshes/",
        "village.glb"
      );

      return scene;
    };
728x90