BabylonJS × Blender 1회차 : 전체 파이프라인 개요 + 개발환경 세팅
목표: Blender→GLB→BabylonJS 흐름을 한 번에 이해
Blender: 기본 화면/오브젝트 조작(이동/회전/스케일), 저장
BabylonJS: 로컬 서버, 기본 Scene/Camera/Light
산출물: 빈 씬 + 기본 카메라/조명 템플릿
체크포인트: 브라우저 콘솔 에러 0, 리로드 즉시 표시
요약
이 시리즈의 핵심은 “모델을 만들고(Blender) → 파일로 내보내고(GLB) → 엔진에서 불러와서(BabylonJS) 화면에 안정적으로 보여주는 것”입니다. 초보자 단계에서 가장 많이 막히는 지점은 실력이 아니라 파이프라인과 개발환경입니다. 예를 들어 file://로 HTML을 열면 CORS나 리소스 로딩 제한 때문에 GLB/텍스처가 깨질 수 있고, Blender에서 단위/스케일이 정리되지 않으면 엔진에서 크기가 이상해 보일 수 있습니다. 1회차에서는 “정상적으로 실행되는 기본 템플릿”을 먼저 확보하고, 다음 회차부터 모델/텍스처/애니메이션을 얹어도 흔들리지 않는 기반을 만드는 데 집중합니다.
목차
- 1) 전체 파이프라인 한 장 요약
- 2) Blender 기본 화면과 오브젝트 조작(이동/회전/스케일)
- 3) 개발환경 세팅: 폴더 구조 + 로컬 서버
- 4) BabylonJS 기본 템플릿: Scene/Camera/Light
- 5) 체크포인트: 콘솔 에러 0, 리로드 즉시 표시
- 6) 자주 막히는 원인과 해결
- 7) 실행 단계(실습 순서)
- 8) 추가로 생각해볼 점
- 9) 블로그 최적화 정보
1) 전체 파이프라인 한 장 요약
Blender와 BabylonJS를 함께 쓸 때의 흐름은 아래 5단계로 정리하면 안정적으로 운영할 수 있습니다.
| 단계 | 도구 | 무엇을 한다 | 초보자 체크 |
|---|---|---|---|
| 1) 모델링/배치 | Blender | 오브젝트 생성, 위치/회전/스케일 조정, 저장 | 조작 단축키(G/R/S) 익숙해지기 |
| 2) 내보내기 | Blender | GLB로 export(모델/머티리얼/텍스처 포함) | 스케일/피벗/텍스처 경로가 깨지지 않게 |
| 3) 정적 호스팅 | 로컬 서버 | 브라우저에서 동일 출처로 리소스 제공 | file:// 금지, http로 실행 |
| 4) 엔진 로딩 | BabylonJS | Scene/Camera/Light 구성, GLB를 씬에 붙임 | 콘솔 에러 0, 네트워크 404 0 |
| 5) 검증/반복 | Blender + BabylonJS | 크기/피벗/재질 확인 → 다시 export | 리로드 즉시 반영되는 흐름 유지 |
1회차에서는 3)과 4)를 확실히 잡습니다. 여기서 기반이 흔들리면 이후 회차(모델 로딩/텍스처/애니메이션)에서 계속 같은 문제를 반복하게 됩니다.
2) Blender 기본 화면과 오브젝트 조작(이동/회전/스케일)
Blender를 “정교한 모델링 툴”로 보기 전에, 일단은 3D 오브젝트를 다루는 기본 조작기로 이해하시면 됩니다. BabylonJS에 들어갈 모델은 결국 “3D 공간에서 어떤 위치/회전/크기를 가졌는가”가 핵심이기 때문입니다.
2-1) 화면 구성(초보자 기준 핵심만)
- Viewport(3D 뷰): 오브젝트를 보고 움직이는 메인 영역입니다.
- Outliner: 씬의 오브젝트 목록(계층 구조)이 보입니다. 나중에 부모/자식 구조를 잡을 때 중요합니다.
- Properties: 오브젝트/재질/렌더 설정을 조정합니다.
2-2) 오브젝트 조작 3종 세트(G/R/S)
- 이동(Move):
G키 → 마우스 이동 → 확정 클릭(또는 Enter) - 회전(Rotate):
R키 → 회전 → 확정 - 스케일(Scale):
S키 → 크기 조절 → 확정
축으로 제한하면 조작이 훨씬 안정적입니다.
G후X또는Y또는Z: 해당 축으로만 이동R후Z: Z축 회전(바닥 기준 회전이 많아 가장 자주 씁니다)S후X: X축 방향으로만 스케일
2-3) 저장(가장 중요한 습관)
- Blender 파일(
.blend)은 “원본”입니다. 엔진에 넣는 GLB는 “산출물”입니다. - 원본과 산출물을 분리하면, 수정/재export가 빠르고 안전해집니다.
3) 개발환경 세팅: 폴더 구조 + 로컬 서버
BabylonJS는 브라우저에서 동작합니다. 브라우저는 보안 정책상 로컬 파일 접근이 제한될 수 있으므로, 반드시 로컬 서버로 실행하는 습관이 필요합니다. 이것이 “콘솔 에러 0”의 첫 번째 조건입니다.
3-1) 추천 폴더 구조(최소 템플릿)
1회차 산출물은 빈 씬 템플릿이지만, 이후 GLB가 들어올 것을 고려해 폴더를 미리 잡아두면 편합니다.
project-root/
index.html
assets/
models/
textures/
src/
main.js (선택: 분리하고 싶을 때)
이번 글의 예시는 단순성을 위해 index.html 하나로 진행하지만, 폴더는 위처럼 만들어두는 것을 권장합니다.
3-2) 로컬 서버 실행 옵션(가장 쉬운 것부터)
| 방법 | 명령 | 장점 | 주의 |
|---|---|---|---|
| Python 내장 서버 | python -m http.server 5500 |
설치 부담이 낮음 | 폴더에서 실행해야 함 |
| Node http-server | npx http-server -p 5500 |
간단, 널리 사용 | Node 필요 |
| VSCode Live Server | 확장 실행 | 리로드가 편함 | 확장 설치 필요 |
명령어를 바로 복사해 실행할 수 있도록 예시를 정리합니다.
# (1) Python
python -m http.server 5500
# (2) Node (설치형)
npm i -g http-server
http-server -p 5500
# (3) Node (설치 없이 npx)
npx http-server -p 5500
서버를 실행한 뒤 브라우저에서 http://localhost:5500로 접속하면 됩니다. 이때부터 “리로드 즉시 표시”가 가능한 개발 루프가 만들어집니다.
4) BabylonJS 기본 템플릿: Scene/Camera/Light
이 시리즈에서는 “항상 같은 템플릿에서 시작”하는 것을 권장합니다. 템플릿이 안정적이면 문제를 분리하기 쉬워집니다.
- 화면이 안 나오면: 카메라/조명/렌더 루프 문제일 확률이 큽니다.
- 모델만 안 나오면: 모델 경로/로딩/스케일 문제로 범위를 좁힐 수 있습니다.
4-1) 빈 씬 + 기본 카메라/조명 템플릿(산출물)
아래 index.html은 1회차 산출물입니다. 바닥(ground)과 기준 오브젝트(토러스/박스)를 넣어 “지금 정상적으로 렌더링 중”임을 확실히 보여주도록 구성했습니다. 콘솔 에러 0, 리로드 즉시 표시 체크에 적합합니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>BabylonJS × Blender Pipeline - Template (Empty Scene)</title>
<style>
html, body { width:100%; height:100%; margin:0; overflow:hidden; font-family:system-ui, -apple-system, Segoe UI, Roboto, sans-serif; }
#renderCanvas { width:100%; height:100%; display:block; touch-action:none; }
#hud {
position: fixed; left: 12px; top: 12px;
width: min(520px, 94vw);
padding: 12px 12px 10px;
border-radius: 14px;
background: rgba(0,0,0,0.55);
border: 1px solid rgba(255,255,255,0.18);
color: rgba(255,255,255,0.92);
z-index: 10;
}
#hudTitle { margin:0 0 8px 0; font-size:14px; font-weight:700; }
#stats { font-size:12px; line-height:1.55; }
.row { display:flex; justify-content:space-between; gap:10px; }
.k { color: rgba(255,255,255,0.75); }
.v { font-variant-numeric: tabular-nums; }
#hint { margin-top:8px; color: rgba(255,255,255,0.72); font-size:12px; line-height:1.45; }
#hint code { background: rgba(255,255,255,0.12); padding: 1px 6px; border-radius: 6px; }
</style>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
</head>
<body>
<div id="hud">
<p id="hudTitle">빈 씬 템플릿(카메라/조명/바닥) - 체크포인트용</p>
<div id="stats">
<div class="row"><span class="k">FPS</span><span class="v" id="fps">-</span></div>
<div class="row"><span class="k">Camera Radius</span><span class="v" id="rad">-</span></div>
<div class="row"><span class="k">Tip</span><span class="v">Wheels/Zoom로 카메라 이동 가능</span></div>
</div>
<div id="hint">
<div>체크: 브라우저 콘솔 에러 0, 새로고침 시 즉시 화면 표시</div>
<div>다음 회차에서 GLB 로딩 코드가 이 템플릿에 추가됩니다.</div>
</div>
</div>
<canvas id="renderCanvas"></canvas>
<script>
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const ui = {
fps: document.getElementById("fps"),
rad: document.getElementById("rad")
};
let scene, camera;
function createScene() {
const s = new BABYLON.Scene(engine);
s.clearColor = new BABYLON.Color4(0.06, 0.07, 0.09, 1.0);
// Camera: ArcRotate는 초보자에게 가장 안정적(드래그 회전/휠 줌/패닝 가능)
camera = new BABYLON.ArcRotateCamera(
"camera",
Math.PI / 2,
Math.PI / 2.6,
16,
new BABYLON.Vector3(0, 1.2, 0),
s
);
camera.attachControl(canvas, true);
camera.wheelDeltaPercentage = 0.01;
// Light: 가장 단순한 조명 조합(기본 확인용)
const hemi = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), s);
hemi.intensity = 1.0;
// Ground: 공간 감각용
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 40, height: 40 }, s);
const gmat = new BABYLON.StandardMaterial("gmat", s);
gmat.diffuseColor = new BABYLON.Color3(0.14, 0.15, 0.17);
gmat.alpha = 0.98;
ground.material = gmat;
// Reference Objects: "정상 렌더링 중" 확인용
const refMat = new BABYLON.StandardMaterial("refMat", s);
refMat.diffuseColor = new BABYLON.Color3(0.75, 0.78, 0.90);
const box = BABYLON.MeshBuilder.CreateBox("refBox", { size: 1.2 }, s);
box.position.set(0, 0.6, 0);
box.material = refMat;
const ring = BABYLON.MeshBuilder.CreateTorus("refRing", { diameter: 3.0, thickness: 0.18, tessellation: 72 }, s);
ring.position.set(-4.5, 1.4, -3.5);
ring.material = refMat;
// 약간의 방향감(축 느낌)
const poleMat = new BABYLON.StandardMaterial("poleMat", s);
poleMat.diffuseColor = new BABYLON.Color3(0.24, 0.26, 0.30);
for (let i = 0; i < 10; i++) {
const pole = BABYLON.MeshBuilder.CreateCylinder("pole" + i, { height: 3.5, diameter: 0.25, tessellation: 24 }, s);
pole.position.set((Math.random() - 0.5) * 28, 1.75, (Math.random() - 0.5) * 28);
pole.material = poleMat;
}
return s;
}
scene = createScene();
engine.runRenderLoop(() => {
scene.render();
ui.fps.textContent = engine.getFps().toFixed(1);
ui.rad.textContent = camera.radius.toFixed(2);
const ring = scene.getMeshByName("refRing");
if (ring) ring.rotation.y += 0.006;
});
window.addEventListener("resize", () => engine.resize());
</script>
</body>
</html>
이 템플릿이 “매번 정상 실행”되면, 이후 회차에서는 여기 위에 GLB 로딩(ImportMesh/SceneLoader)과 로딩 UI를 단계적으로 추가해도 흔들리지 않습니다.
5) 체크포인트: 콘솔 에러 0, 리로드 즉시 표시
초보자에게 가장 좋은 품질 기준은 “그럴듯해 보이는 것”이 아니라 반복 가능한 실행 안정성입니다. 이번 회차의 체크포인트는 아래 2개입니다.
| 체크포인트 | 확인 방법 | 정상 기준 | 실패 시 의심 |
|---|---|---|---|
| 브라우저 콘솔 에러 0 | DevTools Console 확인 | 오류/경고 최소, 빨간 에러 없음 | CDN 차단, 스크립트 경로, 문법 오류 |
| 리로드 즉시 표시 | F5/새로고침 | 화면이 즉시 렌더링되고 HUD가 표시 | 로컬 서버 미사용, 캐시/서버 경로 문제 |
6) 자주 막히는 원인과 해결
- 증상: 화면이 검은색만 보임
가능 원인: 카메라가 씬을 보지 못함, 렌더 루프 미실행, 스크립트 로딩 실패
대응: 콘솔에서 babylon.js 로딩(404 여부) 확인,engine.runRenderLoop존재 확인, 카메라 타깃/반경 값을 기본값으로 되돌리기 - 증상: 콘솔에 CORS/Blocked 관련 메시지
가능 원인:file://로 실행하거나, 리소스를 다른 출처로 잘못 요청
대응: 반드시 로컬 서버(http://localhost)로 실행 - 증상: 화면은 나오는데 조작이 안 됨
가능 원인:camera.attachControl이 빠졌거나 캔버스 이벤트가 막힘
대응:attachControl(canvas, true)확인, CSS에서 캔버스가 100%인지 확인 - 증상: 새로고침할 때마다 가끔 깨짐
가능 원인: 브라우저 캐시/서비스워커/불안정한 개발 루프
대응: 캐시 비활성(DevTools Network), 간단한 서버로 통일, 파일 위치/경로 고정
7) 실행 단계(실습 순서)
- 프로젝트 폴더를 만들고
index.html을 생성합니다. - 위의 “빈 씬 템플릿” 코드를 그대로 붙여넣습니다.
- 로컬 서버를 실행합니다(권장:
python -m http.server 5500또는npx http-server -p 5500). - 브라우저에서
http://localhost:5500로 접속합니다. - DevTools를 열고 Console 에러가 0인지 확인합니다.
- 새로고침(F5) 후 즉시 HUD/바닥/기준 오브젝트가 보이는지 확인합니다.
- Blender를 열고 기본 큐브를 선택한 뒤
G/R/S로 이동/회전/스케일을 짧게 연습하고 저장합니다(원본 저장 습관). - 오늘의 산출물 기준을 통과하면, 다음 회차부터
assets/models에 GLB를 추가하고 BabylonJS에서 로딩하는 단계로 진행합니다.
8) 추가로 생각해볼 점
- “템플릿이 곧 생산성”입니다: 매번 새로 세팅하면 작은 실수로 시간이 많이 소모됩니다. 1회차 템플릿을 레포의 시작점으로 고정해두면 이후 속도가 크게 올라갑니다.
- 모델 문제가 생겨도 엔진 템플릿은 정상이어야 합니다: GLB를 얹기 전에도 항상 화면이 나오는 상태를 유지하면, 문제 범위를 빠르게 좁힐 수 있습니다.
- 단위/스케일은 앞으로 계속 등장합니다: 지금은 조작만 익히지만, 다음 회차에서 “왜 모델이 너무 크거나 작은가”가 본격적으로 나오므로, Blender에서 “현실적인 크기” 감각을 조금씩 맞춰두는 것이 좋습니다.
- 체크포인트는 습관입니다: 콘솔 에러 0, 리로드 즉시 표시를 매 회차 반복하면 “원인 추적”이 쉬워지고, 파이프라인이 단단해집니다.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.




0 댓글