Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

Next.js/three.js

three.js gltf 오브젝트 여러 개 로딩하기

방피터 2022. 6. 27. 19:55

gltf 오브젝트를 여러 개 로딩해볼려구. 화면 하나에 object 하나만 로딩하라는 법은 없잖아? 음 혹시나 서로 다른 형식의 object를 한 Scene에 로드할 수도 있고. 암튼 그래서 일단 똑같은 gltf 두개 로딩해볼거야.

특별한 건 없고 load() 대신 loadasync()를 Promiss.All에서 사용하면 간단하게 끝나. 아래 코드처럼.

import React, { useEffect, useRef } from "react";
import * as THREE from "three";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

const ThreeJSMultipleObject = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  useEffect(() => {
    if (canvasRef.current) {
      const scene = new THREE.Scene();
      const renderer = new THREE.WebGLRenderer({
        canvas: canvasRef.current,
        antialias: true,
      });
      renderer.outputEncoding = THREE.sRGBEncoding;
      const camera = new THREE.PerspectiveCamera();
      camera.position.set(0, 0, 5);
      const loader = new GLTFLoader();
      scene.background = new THREE.Color("green");
      const light = new THREE.DirectionalLight(0xffffff, 10);
      scene.add(light);
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.update();
      Promise.all([
        loader.loadAsync("/scene.gltf"),
        loader.loadAsync("/scene.gltf"),
      ]).then((results) => {
        const [objectA, objectB] = results;
        scene.add(objectA.scene);
        scene.add(objectB.scene);
        objectA.scene.position.set(1, 0, 0);
        objectB.scene.position.set(-1, 0, 0);
        const animate = () => {
          requestAnimationFrame(animate);
          objectA.scene.rotation.y += 0.01;
          objectB.scene.rotation.y -= 0.01;
          renderer.render(scene, camera);
          controls.update();
        };
        animate();
      });
    }
  }, [canvasRef]);

  return (
    <div>
      <canvas ref={canvasRef} id="canvas" width="300" height="300"></canvas>
      <h1>Multiple objects</h1>
    </div>
  );
};

export default ThreeJSMultipleObject;

아니면 위의 Promiss.All 부분을 아래처럼 async, await으로 변경해도 똑같이 동작해.

const mainLoader = async () => {
    const [objectA, objectB] = await Promise.all([
        loader.loadAsync("/scene.gltf"),
        loader.loadAsync("/scene.gltf"),
    ]);
        scene.add(objectA.scene);
        scene.add(objectB.scene);
        objectA.scene.position.set(1, 0, 0);
        objectB.scene.position.set(-1, 0, 0);
        const animate = () => {
        requestAnimationFrame(animate);
        objectA.scene.rotation.y += 0.01;
        objectB.scene.rotation.y -= 0.01;
        renderer.render(scene, camera);
        controls.update();
    };
    animate();
};
mainLoader();

이렇게 만든 컴포넌트를 index.tsx에 추가한 후 테스트를 해보면 아래처럼 gltf 오브젝트가 여러개 추가된 걸 확인할 수 있어.

gltf 여러개 로딩

지금은 코드가 너저분한데 계속 하다보면 요령이 생기겠지 ㅎㅎㅎ 너무 조바심내지 말자구 친구들!(나님에게도 하는 말 ㅋ)

👇👇👇 아래는 github repository 주소!

https://github.com/peter-bang/nextjs-3djs/blob/main/components/threejs_multiple_object.tsx

 

GitHub - peter-bang/nextjs-3djs: three.js on next.js

three.js on next.js. Contribute to peter-bang/nextjs-3djs development by creating an account on GitHub.

github.com

 

반응형