在 Three.js 中,载入和展示 3D 模型是创建交互式三维场景的关键步骤。无论是游戏、虚拟现实应用还是数据可视化,能够灵活地载入和操作 3D 模型都是至关重要的。本文将详细介绍如何使用 Three.js 载入 3D 模型,包括不同的格式、常用的加载器,以及一些高级用法和示例代码。
Three.js 支持多种 3D 模型格式,包括但不限于:
在本文中,我们将主要使用 GLTF 格式,因为它是 Three.js 推荐的格式。
确保你在项目中引入了 Three.js 和所需的加载器。以下是基本的 HTML 结构:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js 载入 3D 模型示例</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/loaders/GLTFLoader.js"></script>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
在 <script>
标签中,设置基本的 Three.js 场景、摄像机和渲染器:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 5;
要载入 GLTF 模型,我们需要使用 GLTFLoader
。以下是载入模型的步骤:
const loader = new THREE.GLTFLoader();
loader.load('path/to/model.glb', (gltf) => {
scene.add(gltf.scene);
}, undefined, (error) => {
console.error(error);
});
加载完成后,我们可以对模型进行各种操作,比如调整位置、缩放、旋转等。例如:
loader.load('path/to/model.glb', (gltf) => {
const model = gltf.scene;
model.position.set(0, 0, 0); // 设置位置
model.scale.set(1, 1, 1); // 设置缩放
model.rotation.set(0, Math.PI / 2, 0); // 设置旋转
scene.add(model);
}, undefined, (error) => {
console.error(error);
});
在动画循环中渲染场景:
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
确保在窗口大小变化时调整摄像机和渲染器的大小:
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
以下是一个完整的示例代码,展示了如何在 Three.js 中载入和渲染 GLTF 模型:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js 载入 3D 模型示例</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/loaders/GLTFLoader.js"></script>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 5;
const loader = new THREE.GLTFLoader();
loader.load('path/to/model.glb', (gltf) => {
const model = gltf.scene;
model.position.set(0, 0, 0);
model.scale.set(1, 1, 1);
model.rotation.set(0, Math.PI / 2, 0);
scene.add(model);
}, undefined, (error) => {
console.error(error);
});
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
为了使模型看起来更真实,建议添加光源:
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 环境光
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 平行光
directionalLight.position.set(5, 5, 5).normalize();
scene.add(directionalLight);
如果你的模型支持阴影,可以启用阴影效果:
renderer.shadowMap.enabled = true;
directionalLight.castShadow = true;
如果模型包含动画,GLTFLoader 也会加载这些动画。我们可以通过 AnimationMixer
来播放动画:
const mixer = new THREE.AnimationMixer(gltf.scene);
gltf.animations.forEach((clip) => {
mixer.clipAction(clip).play();
});
// 在动画循环中更新混合器
function animate() {
requestAnimationFrame(animate);
if (mixer) mixer.update(0.01); // 更新动画
renderer.render(scene, camera);
}
在本博客中,我们详细探讨了如何在 Three.js 中载入和渲染 3D 模型,包括使用 GLTFLoader 加载 GLTF 模型、添加灯光和阴影、处理动画等。通过这些示例,你可以在自己的项目中灵活地使用 3D 模型,提升用户体验。希望本博客能够帮助你更好地理解和使用 Three.js。如果有任何问题或建议,欢迎在评论区留言讨论!