记录学习Vue3 + Three.js 加载 OBJ 模型⑬

一、效果展示



二、项目准备

确保你已经安装了 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)进行动画控制
✅ 响应式布局支持窗口缩放适配

四、模型文件放置结构

  public/
└── models/
    ├── 1.obj
    └── 1.mtl
mtl是材质皮肤
 

 五、注意事项

风车 - 3d模型 免费下载 - 爱给网

上面是下载.blend文件风车模型

Download — blender.org

上面这个网站下载blender需要把blender模型转换为.obj模型

three.js manual

这是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 加载器)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值