ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ Three.js์์ GLTFLoader๋ฅผ ํ์ฉํ์ฌ 3D ๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ
octo54 2025. 3. 28. 10:57๐ Three.js์์ GLTFLoader๋ฅผ ํ์ฉํ์ฌ 3D ๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ
์ด์ ๊ธ์์๋ Three.js + React ๊ฐ๋ฐ ํ๊ฒฝ์ ๊ตฌ์ถํ๊ณ , ๊ธฐ๋ณธ 3D ์ฌ์ ๋ ๋๋งํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ GLTFLoader๋ฅผ ์ฌ์ฉํ์ฌ 3D ๋ชจ๋ธ์ ๋ถ๋ฌ์ค๊ณ , Three.js ์ฌ์ ๋ฐฐ์นํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค.
๐ 1. GLTFLoader๋?
Three.js์์ .glb ๋ฐ .gltf ํ์์ 3D ๋ชจ๋ธ์ ๋ก๋ํ๋ ค๋ฉด GLTFLoader๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
โ GLTF vs GLB ์ฐจ์ด์
ํ์ผ ํ์ ์ค๋ช
.glb | ๋ฐ์ด๋๋ฆฌ ํฌ๋งท (์ฉ๋์ด ์๊ณ ์ต์ ํ๋จ) |
.gltf | JSON ํฌ๋งท (ํ ์คํธ ๊ธฐ๋ฐ, ์ฌ๋์ด ์ฝ๊ธฐ ์ฌ์) |
๐ Three.js์์๋ .glb ํ์ผ์ ๋ ์ถ์ฒํฉ๋๋ค.
- ์์ถ๋ฅ ์ด ๋๊ณ , ๋ก๋ฉ ์๋๊ฐ ๋น ๋ฅด๋ฉฐ, ๋คํธ์ํฌ ์ฌ์ฉ๋์ด ์ ์ต๋๋ค.
- WebGL์์ ์ต์ ํ๋์ด ๋น ๋ฅด๊ฒ ๋ ๋๋ง๋ฉ๋๋ค.
๐ 2. ํ๋ก์ ํธ์ 3D ๋ชจ๋ธ ์ถ๊ฐํ๊ธฐ
โ 1) @react-three/drei ์ค์น (GLTFLoader ํฌํจ)
GLTF ๋ชจ๋ธ์ ์ฝ๊ฒ ๋ถ๋ฌ์ค๊ธฐ ์ํด @react-three/drei ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
npm install @react-three/drei
๐น ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Three.js๋ฅผ React์์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋ค์ํ ์ ํธ๋ฆฌํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
โ 2) 3D ๋ชจ๋ธ ๋ค์ด๋ก๋ ๋ฐ ํ๋ก์ ํธ์ ์ถ๊ฐ
- ๋ฌด๋ฃ 3D ๋ชจ๋ธ ๋ค์ด๋ก๋ ์ฌ์ดํธ
- ๋ชจ๋ธ ํ์ผ ์ ์ฅ ๊ฒฝ๋ก
ํ๋ก์ ํธ ๋ด public/models ํด๋์ 3D ๋ชจ๋ธ์ ์ถ๊ฐํฉ๋๋ค.
๐ ์์ ํ์ผ ๊ตฌ์กฐ:
๐ public/models/
โฃ ๐ chair.glb
โฃ ๐ robot.glb
โ ๐ car.glb
๐ 3. GLTFLoader๋ฅผ ์ฌ์ฉํ์ฌ 3D ๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ
๐ src/components/ModelViewer.jsx
import { useRef } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, useGLTF } from "@react-three/drei";
const Model = ({ modelPath }) => {
const { scene } = useGLTF(modelPath);
return <primitive object={scene} scale={1.5} />;
};
const ModelViewer = () => {
return (
<Canvas camera={{ position: [0, 2, 5], fov: 50 }}>
{/* ์กฐ๋ช
์ค์ */}
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
{/* 3D ๋ชจ๋ธ ๋ก๋ */}
<Model modelPath="/models/chair.glb" />
{/* ์นด๋ฉ๋ผ ์ปจํธ๋กค */}
<OrbitControls />
</Canvas>
);
};
export default ModelViewer;
๐ฏ 4. App.jsx์์ ModelViewer ์ปดํฌ๋ํธ ์ถ๊ฐ
๐ src/App.jsx
import ModelViewer from "./components/ModelViewer";
function App() {
return (
<div>
<h1 style={{ textAlign: "center", marginTop: "20px" }}>3D ๋ชจ๋ธ ๋ทฐ์ด</h1>
<ModelViewer />
</div>
);
}
export default App;
โ ์ด์ npm run dev๋ก ์คํํ๋ฉด 3D ๋ชจ๋ธ์ด Three.js ์ฌ์ ๋ก๋๋ฉ๋๋ค!
๐ 5. 3D ๋ชจ๋ธ ๋ก๋ฉ ์ต์ ํํ๊ธฐ
โ 1) ๋ชจ๋ธ ํฌ๊ธฐ ์กฐ์
<primitive> ํ๊ทธ์์ scale ๊ฐ์ ์กฐ์ ํ์ฌ ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
<primitive object={scene} scale={2} />
โ 2) ์ฌ๋ฌ ๋ชจ๋ธ ์ ํ ๊ธฐ๋ฅ ์ถ๊ฐ
์ฌ์ฉ์๊ฐ ๋ค์ํ ๋ชจ๋ธ์ ์ ํํ์ฌ ๋ก๋ํ ์ ์๋๋ก UI๋ฅผ ๊ฐ์ ํด๋ด ๋๋ค.
๐ src/components/ModelGallery.jsx (๋ชจ๋ธ ์ ํ ๋ฒํผ ์ถ๊ฐ)
import { useState } from "react";
import ModelViewer from "./ModelViewer";
const models = [
{ name: "Chair", path: "/models/chair.glb" },
{ name: "Car", path: "/models/car.glb" },
{ name: "Robot", path: "/models/robot.glb" }
];
const ModelGallery = () => {
const [selectedModel, setSelectedModel] = useState(models[0].path);
return (
<div>
{/* ๋ชจ๋ธ ์ ํ ๋ฒํผ */}
<div style={{ textAlign: "center", marginBottom: "10px" }}>
{models.map((model) => (
<button
key={model.name}
onClick={() => setSelectedModel(model.path)}
style={{
margin: "5px",
padding: "10px",
border: "1px solid gray",
borderRadius: "5px",
cursor: "pointer"
}}
>
{model.name}
</button>
))}
</div>
{/* ์ ํ๋ ๋ชจ๋ธ์ ModelViewer์ ์ ๋ฌ */}
<ModelViewer modelPath={selectedModel} />
</div>
);
};
export default ModelGallery;
๐ src/components/ModelViewer.jsx (๋์ ์ผ๋ก ๋ชจ๋ธ ๋ณ๊ฒฝ)
import { useGLTF } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
const Model = ({ modelPath }) => {
const { scene } = useGLTF(modelPath);
return <primitive object={scene} scale={1.5} />;
};
const ModelViewer = ({ modelPath }) => {
return (
<Canvas camera={{ position: [0, 2, 5], fov: 50 }}>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
<Model modelPath={modelPath} />
<OrbitControls />
</Canvas>
);
};
export default ModelViewer;
๐ App.jsx์์ ModelGallery ์ฌ์ฉ
import ModelGallery from "./components/ModelGallery";
function App() {
return (
<div>
<h1 style={{ textAlign: "center", marginTop: "20px" }}>3D ๋ชจ๋ธ ๋ทฐ์ด</h1>
<ModelGallery />
</div>
);
}
export default App;
โ 6. ์์ฑ๋ ๊ธฐ๋ฅ
โ GLTFLoader๋ฅผ ํ์ฉํ์ฌ 3D ๋ชจ๋ธ ๋ถ๋ฌ์ค๊ธฐ
โ Canvas๋ฅผ ํ์ฉํ Three.js ์ฌ ๋ ๋๋ง
โ ์ฌ๋ฌ ๊ฐ์ 3D ๋ชจ๋ธ์ ์ ํํ์ฌ ํ์ ๊ฐ๋ฅ
โ OrbitControls๋ก ๋ง์ฐ์ค ์กฐ์ ๊ธฐ๋ฅ ์ถ๊ฐ
๐ฅ 7. ๋ค์ ๋จ๊ณ: 3D ๋ชจ๋ธ์ ์ ๋๋ฉ์ด์ ์ ์ฉํ๊ธฐ
์ง๊ธ๊น์ง ์ฐ๋ฆฌ๋ GLTFLoader๋ฅผ ํ์ฉํ์ฌ 3D ๋ชจ๋ธ์ ๋ก๋ํ๊ณ , Three.js ์ฌ์ ๋ฐฐ์นํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค.
๋ค์ ๊ธ์์๋ ์ ๋๋ฉ์ด์
์ด ํฌํจ๋ GLTF ๋ชจ๋ธ์ ๋ถ๋ฌ์์ ์ฌ์ํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
โ
๋ค์ ํธ ์๊ณ :
"Three.js์์ 3D ๋ชจ๋ธ ์ ๋๋ฉ์ด์
๋ถ๋ฌ์ค๊ธฐ & ์ ์ดํ๊ธฐ" ๐
'project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- AI์ฑ๋ด
- nodejs
- PostgreSQL
- AI ์๋ํ
- App Router
- ๊ด๋ฆฌ์
- ํ๋ก ํธ์๋
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- ์น๊ฐ๋ฐ
- Ktor
- SEO ์ต์ ํ
- rag
- REACT
- LangChain
- Next.js
- llm
- Prisma
- SEO์ต์ ํ
- ์ค๋งํธ ์ปจํธ๋ํธ
- gatsbyjs
- Docker
- Webpack
- kotlin
- NestJS
- seo ์ต์ ํ 10๊ฐ
- github
- fastapi
- nextJS
- CI/CD
- ๋ฐฑ์๋๊ฐ๋ฐ
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |