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일 투자한 보람이 있습니다.