Skip to main content
민트라

Blender에서 Three.js로 - 3일간의 워크플로우 구축기

유니티나 언리얼이라면 에셋을 임포트하면 끝입니다. 하지만 Three.js는 달랐습니다. Blender에서 정성껏 만든 모델이 웹에서 제대로 보이기까지 3일이 걸렸습니다.

첫 번째 시도: 그냥 내보내기 #

Blender에서 File → Export → glTF 2.0을 선택했습니다. 기본 설정으로 내보내고 Three.js에서 불러왔습니다.

const loader = new GLTFLoader();
loader.load('model.glb', (gltf) => {
  scene.add(gltf.scene);
});

결과: 모델이 안 보였습니다.

콘솔에 에러는 없었습니다. 뭐가 문제일까요?

// 디버깅
loader.load('model.glb', (gltf) => {
  console.log(gltf.scene.position);  // (0, 0, 0)
  console.log(gltf.scene.scale);      // (1, 1, 1)
  scene.add(gltf.scene);
});

알고 보니 모델이 너무 작았습니다. Blender에서 1미터로 만들었는데, Three.js 씬에서는 점처럼 보였습니다. 카메라가 100 단위 떨어져 있었거든요.

gltf.scene.scale.set(100, 100, 100);

모델이 보였습니다. 하지만 새로운 문제가 생겼습니다.

두 번째 문제: 재질이 이상하다 #

Blender에서는 금속 재질이었는데, Three.js에서는 플라스틱처럼 보였습니다.

원인을 찾는 데 반나절이 걸렸습니다. Blender의 렌더러(Eevee/Cycles)와 glTF 스펙의 차이였습니다.

Blender 머티리얼 설정:
- Principled BSDF 사용
- Metallic: 1.0
- Roughness: 0.2
- Base Color: 연결된 텍스처

glTF 내보내기 후:
- Metallic: 0 (기본값으로 초기화됨)
- Roughness 텍스처: 없음

Blender에서 머티리얼을 glTF 호환 방식으로 설정해야 했습니다.

glTF 호환 머티리얼 설정:
1. Principled BSDF만 사용 (다른 셰이더 X)
2. 텍스처 연결 방식 확인
3. 색상 공간 확인 (Base Color: sRGB, 나머지: Non-Color)

세 번째 문제: 파일이 너무 크다 #

최적화 전 모델 크기: 45MB

웹에서 45MB를 로드하면 사용자가 떠납니다.

시도 1: Draco 압축 #

// Blender 내보내기 설정에서 Draco 압축 활성화
// 또는 gltf-pipeline 사용
npx gltf-pipeline -i model.glb -o model-draco.glb -d

결과: 45MB → 8MB

좋아졌지만 아직 부족합니다.

시도 2: 텍스처 최적화 #

텍스처가 4K(4096x4096)였습니다. 웹에서는 과합니다.

# ImageMagick으로 리사이즈
convert texture.png -resize 1024x1024 texture-web.png

# WebP로 변환
cwebp texture-web.png -o texture-web.webp -q 80

결과: 8MB → 2MB

시도 3: 지오메트리 단순화 #

Blender의 Decimate Modifier를 사용했습니다.

원본: 150,000 삼각형
Decimate (Ratio: 0.3): 45,000 삼각형
품질 저하: 육안으로 구분 어려움

최종 결과: 2MB → 800KB

네 번째 문제: 애니메이션이 안 된다 #

Blender에서 만든 애니메이션이 재생되지 않았습니다.

loader.load('animated-model.glb', (gltf) => {
  scene.add(gltf.scene);

  // 애니메이션 확인
  console.log(gltf.animations);  // [] 빈 배열!
});

내보내기 설정에서 애니메이션 옵션을 체크해야 했습니다.

Blender Export 설정:
☑ Include > Animation
☑ Animation > Skinning
☑ Animation > Sampling Rate: 24 (또는 원하는 fps)

다시 내보내니 애니메이션이 포함되었습니다.

loader.load('animated-model.glb', (gltf) => {
  scene.add(gltf.scene);

  const mixer = new THREE.AnimationMixer(gltf.scene);
  const action = mixer.clipAction(gltf.animations[0]);
  action.play();

  function animate() {
    mixer.update(clock.getDelta());
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
  }
});

다섯 번째 문제: 원점이 이상하다 #

모델을 회전시키니 이상한 축을 중심으로 돌았습니다.

mesh.rotation.y += 0.01;  // 모델이 엉뚱한 곳을 기준으로 회전

Blender에서 원점(Origin)을 제대로 설정하지 않았습니다.

Blender에서:
1. 객체 선택
2. Object → Set Origin → Origin to Center of Mass
3. Apply → All Transforms (Ctrl + A)

Transform을 적용하지 않으면 Blender 내부의 변환 정보가 남아서 Three.js에서 이상하게 동작합니다.

최종 워크플로우 #

3일간의 삽질 끝에 정리한 체크리스트입니다.

Blender 작업 시 #

1. 단위 설정: Scene Properties → Units → Metric, Scale: 0.01
2. 원점 설정: Origin to Center of Mass
3. Transform 적용: Ctrl + A → All Transforms
4. 머티리얼: Principled BSDF만 사용
5. 텍스처: 2K 이하, PNG 또는 JPG
6. 폴리곤: 모바일 대상이면 50,000 이하

내보내기 설정 #

Format: glTF Binary (.glb)

Include:
☑ Selected Objects (필요한 것만)
☑ Custom Properties
☑ Cameras (필요시)
☑ Punctual Lights (필요시)

Transform:
☑ +Y Up

Geometry:
☑ Apply Modifiers
☑ UVs
☑ Normals
☑ Tangents (노멀맵 사용시)
☐ Vertex Colors (필요시만)
☑ Compression (Draco)

Animation:
☑ Animation
☑ Shape Keys
☑ Skinning

Three.js 로드 시 #

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');

const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);

loader.load(
  'model.glb',
  (gltf) => {
    // 성공
    const model = gltf.scene;
    scene.add(model);

    // 애니메이션 있으면
    if (gltf.animations.length > 0) {
      const mixer = new THREE.AnimationMixer(model);
      gltf.animations.forEach((clip) => {
        mixer.clipAction(clip).play();
      });
    }
  },
  (progress) => {
    // 로딩 진행
    console.log((progress.loaded / progress.total * 100) + '%');
  },
  (error) => {
    // 에러
    console.error(error);
  }
);

유용한 도구들 #

1. gltf-transform

glTF 파일을 CLI에서 최적화합니다.

npx @gltf-transform/cli optimize input.glb output.glb --compress draco --texture-compress webp

2. gltf.report

온라인에서 glTF 파일을 분석해줍니다. 문제점과 최적화 제안을 보여줍니다.

3. Blender glTF 검증 애드온

내보내기 전에 호환성 문제를 미리 확인할 수 있습니다.

이제 Blender에서 Three.js까지 30분이면 됩니다. 처음 3일 투자한 보람이 있습니다.