一、效果展示
二、项目准备
确保你已经安装了 Three.js:
npm i three
并正确引用了相关加载器:
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'; import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
三、Vue 组件完整代码
<template> <div ref="threeCanvas" style="width: 100%; height: 100%"></div> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import * as THREE from 'three'; //加载.obj文件加载器 import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'; //加载.mtl文件加载器 import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'; //鼠标控制器 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; const threeCanvas = ref(null); let bladeMesh = null; let renderer, scene, camera, controls; //渲染器,场景,相机,控制器 //初始化场景、相机、灯光、控制器等 const initScene = () => { scene = new THREE.Scene();//创建场景 scene.background = new THREE.Color(0xeeeeee);//设置场景背景颜色 camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);//创建透视相机 camera.position.set(0, 1.5, 5);//设置相机位置前面上面 renderer = new THREE.WebGLRenderer({ antialias: true });//创建渲染器//开启抗锯齿效果 renderer.setSize(window.innerWidth, window.innerHeight); // 将渲染器的 canvas 添加到 DOM 中 threeCanvas.value.appendChild(renderer.domElement); // 设置鼠标控制器 controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; //启用阻尼(惯性) controls.dampingFactor = 0.05;//阻尼系数 controls.minDistance = 2;// 最小缩放距离 controls.maxDistance = 20; // 最大缩放距离 controls.maxPolarAngle = Math.PI / 2;//限制垂直旋转角度(最大为 90°) const lights = [ new THREE.AmbientLight(0xffffff, 0.6),// 环境光 new THREE.DirectionalLight(0xffffff, 0.8),// 主方向光 new THREE.DirectionalLight(0xffffff, 0.4),// 辅助方向光 new THREE.PointLight(0xffffff, 0.5)// 点光源 ]; lights[1].position.set(5, 10, 7);// 设置主方向光位置 lights[2].position.set(-5, 5, -5);// 设置辅助方向光位置 lights[3].position.set(0, 3, 3);// 设置点光源位置 lights.forEach(light => scene.add(light)); // 统一添加到场景中 }; //加载模型文件和材质 const loadModel = () => { const mtlLoader = new MTLLoader();// 创建材质加载器 mtlLoader.setPath('/models/');// 设置材质文件路径 // 加载材质文件 mtlLoader.load('1.mtl', (materials) => { materials.preload();// 预加载材质 // 创建 OBJ 模型加载器 const objLoader = new OBJLoader(); // 应用预加载好的材质 objLoader.setMaterials(materials); // 设置模型文件路径 objLoader.setPath('/models/'); // 加载模型文件 objLoader.load('1.obj', (object) => { object.traverse((child) => { // 遍历模型所有子对象 if (child.isMesh && child.name.toLowerCase().includes('blade')) { // 如果是叶片网格对象,保存引用以便后续动画使用 bladeMesh = child; } }); object.scale.set(0.5, 0.5, 0.5);// 缩放模型 scene.add(object);// 添加到场景中 }); }); }; const animate = () => { requestAnimationFrame(animate);// 每帧请求动画回调 if (bladeMesh) bladeMesh.rotation.z += 0.02; // 如果已获取到 blade 网格,执行旋转动画 controls.update();// 更新控制器状态(处理惯性) renderer.render(scene, camera); //执行渲染 }; // 窗口尺寸变化回调,保持自适应 const handleResize = () => { const width = window.innerWidth; const height = window.innerHeight; renderer.setSize(width, height);// 更新渲染器大小 camera.aspect = width / height;//更新相机大小 camera.updateProjectionMatrix();//更新投影矩阵 }; onMounted(() => { initScene(); loadModel(); animate(); window.addEventListener('resize', handleResize);// 监听窗口大小变化 }); onBeforeUnmount(() => { window.removeEventListener('resize', handleResize);// 移除监听 renderer.dispose();// 销毁渲染器资源 controls.dispose(); // 销毁控制器 }); </script> <style scoped> /* 可根据实际需要添加样式 */ </style>
功能点 说明 ✅ 支持 .obj + .mtl
材质绑定使用 MTLLoader
搭配OBJLoader
加载模型✅ 鼠标控制器 支持平移、缩放、旋转等交互 ✅ 多光源照明 环境光 + 多方向光 + 点光源,提升光照效果 ✅ 动态旋转动画 支持对特定 mesh(如 blade)进行动画控制 ✅ 响应式布局 支持窗口缩放适配
四、模型文件放置结构
mtl是材质皮肤public/ └── models/ ├── 1.obj └── 1.mtl
五、注意事项
上面是下载.blend文件风车模型
上面这个网站下载blender需要把blender模型转换为.obj模型
这是three.js的官网
六、.obj
格式的几个重要优势跨平台兼容性强
.obj
是一种被广泛支持的通用模型格式,可以在 Blender、3ds Max、Maya、Cinema4D、Unity、Three.js 等多种工具中使用。相比
.blend
(仅限 Blender 自己用),.obj
更适合导出/分享/在 WebGL 中加载。
.obj
是纯文本格式,记录的是:
顶点位置(v)
法线(vn)
UV 坐标(vt)
面(f)
搭配
.mtl
材质文件可以定义基本颜色和贴图路径,Three.js、Babylon.js 等都支持直接加载。
原因 描述 ❌ Three.js 不支持 .blend
无法在前端直接加载 .blend
❌ 私有格式 .blend
是 Blender 专属格式,结构复杂❌ 不适合网页使用 需要 Blender 打开才能解析,不适合浏览器环境
七、总结
将
.blend
文件导出成.obj
文件,是为了在 Web 项目中加载和显示模型。.obj
是最基本、兼容性最强的格式之一,非常适合 Three.js 等前端 3D 框架使用。
如果你追求更好的性能和更小的文件体积,也可以考虑将
.blend
导出为.glb
/.gltf
格式 —— Three.js 同样原生支持,性能更佳(需要用GLTFLoader
加载器)。