Three.js - 커스텀 모델 불러오기

·2023년 3월 6일
1

Three.js

목록 보기
6/8

glTF

glTF란 3차원 장면과 모델을 표현하는 파일 포맷으로 JSON 표준에 기반하고 있다.
이를 바이너리 형식으로 표현한 것을 glb라고 한다.

무료로 glTF를 다운받아보자. 주로 구글에 free glTF download를 치면 무언가가 나온다.
glb의 경우 텍스쳐 크기에 따라 용량이 다르다.

물론 Three.js에서는 glTF, glb외에 다른 파일 형식의 로더도 지원하고 있으나, glb가 표준이고, 정보도 제일 많다.

glb 불러오기


본 예제에서는 일부니 모델을 이용한다.

webpack을 이용하고 있다면?

본 강의에서는 webpack을 이용해 프로그래밍을 하고 있었는데,
모델 또한 번들링해야하기 때문에 webpack.config.js에서 따로 모델들의 정보도 입력해줘야 한다.

new CopyWebpackPlugin({
			patterns: [
				{ from: "./src/main.css", to: "./main.css" },
				{ from: "./src/models", to: "./models" },
				// { from: "./src/sounds", to: "./sounds" } 처럼 다른 에셋을 넣게 되면 CopyWebpackPlugin에 그 정보를 입력해야한다.
			],
		})

외부 모듈 설치

앞서 우리는 계속 3D모델을 THREE 모듈의 내장 객체를 이용해 메쉬를 생성했다.
하지만 외부에서 커스텀한 모델을 불러오긴 위해서는 외부 모듈이 필요하다!

import {GLTFLoader} from 'three/examples/jsm/loaders/ GLTFLoader';

외부 모델 불러오기

const gltfLoader = new GLTFLoader();
gltfLoader.load(
  '/models/ilbuni.glb',
  gltf=>{
  	const ilbuniMesh = gltf.scene.children[0];
  	scene.add(ilbuniMesh);
  }
);

gltfLoader객체를 만들어준 후,load메서드로 모델을 불러온다.


일부니가 불러와졌다. 반짝이는 머리가 인상적이다.

애니메이션 생성

애니메이션을 생성하기 위해선 믹서가 필요하다.

const gltfLoader = new GLTFLoader();
let mixer;

gltfLoader.load(
  '/models/ilbuni.glb',
  gltf=>{
  	const ilbuniMesh = gltf.scene.children[0];
  	scene.add(ilbuniMesh);
    
    const mixer = new THREE.AnimationMixer(ilbuniMesh);
    const actions=[];
    actions[0] = mixer.clipAction(gltf.animations[0]); //디폴트 애니
    actions[1] = mixer.clipAction(gltf.animations[1]);
    actions[0].play();
  }
);

또한 애니메이션인 만큼 매 프레임마다 메쉬 상태를 업데이트 해야한다.
draw함수도 수정해주자!

function draw(){
	const delta = clock.getDelta();
    mixer.update(delta); //오류가 생길 수 있다!
    renderer.render(scene,camera);
    renderer.setAnimationLoop(draw);
}

대신 문제가 있다!

gltfLoader에서 모델을 load하는 과정에서 mixer가 생성되는데,
생성과정에 시간이 어느정도 소요되므로, 코드를 실행하자마자 draw를 호출하게 되면 mixer가 존재하기도 전 호출이 되기 때문에 오류가 생긴다.

따라서 다음과 같이 수정이 필요하다.

function draw(){
	const delta = clock.getDelta();
    if (mixer) mixer.update(delta); //오류 해결!
    renderer.render(scene,camera);
    renderer.setAnimationLoop(draw);
}


업로드가 잘 된 것을 볼 수 있다.

profile
백엔드 호소인

0개의 댓글