VUE3+ VITE 使用Three.js展示3D模型

您所在的位置:网站首页 手机做3d图 VUE3+ VITE 使用Three.js展示3D模型

VUE3+ VITE 使用Three.js展示3D模型

2024-07-10 19:01| 来源: 网络整理| 查看: 265

学习主要文献: 1. threejs文件包下载和目录简介 | Three.js中文网3D模型这里有下载网站:Sketchfab - The best 3D viewer on the web   (邮箱注册后有免费的模型下载)

3D模型编辑软件:Blender   windows环境微软应用市场可以直接获取安装最新版本。

里面有详细的安装环境介绍和各个功能组件的介绍,相对简单移动。还可以结合学习网站(bilibili)视频综合学习一下,感觉还不错~

这里主要记录一些比较容易出现的问题:

1.  画面不显示:展示要有渲染器(WebGLRenderer),渲染器里面有两个参数对象:         场景(Scene),场景里面可以添加光源(Light)、辅助线(AxesHelper)、模型(Group),模型加载3D模型OBJ文件加载器(OBJLoader和MTLLoader),GLTF和GLB文件加载器(GLTFLoader)。         相机(Camera),position.set设置坐标很重要,设置不对可能因为太小,或者位置不对造成看不到模型。

        跟着中文网内容走,可以画出一个基本的3D图形(角度看起来像平面,结合组件事件监听和11. 动画渲染循环 | Three.js中文网  和这章内容可以旋转起来看)。详细的下方代码是加载的3D模型 ,可以直接放入模型后使用。

2.  发布打包的时候本地资源引用异常:

       把3D的本地资源引用放入public文件夹中。load函数的路径在外面单独声明,就好了。

3. light的打光位置,这个因3D模型而异,我这边办法只能慢慢调,不知道咋引用Blender里面的灯光角度。

4. 3D模型的默认显示位置:

调整相机调整 

完整VUE代码:

import {onMounted, ref, reactive} from 'vue' import * as THREE from 'three'; //加载自定义3D模型 // 引入gltf模型加载库GLTFLoader.js import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js'; import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; //加载OBJ3D import {MTLLoader} from 'three/examples/jsm/loaders/MTLLoader' import {OBJLoader} from "three/examples/jsm/loaders/OBJLoader" const three9038 = "./59_9038.glb"; //创建场景载体 const scene = new THREE.Scene(); const loader = new GLTFLoader();//三维模型加载器 const model = new THREE.Group(); //声明一个组对象,用来添加加载成功的三维场景 const data = reactive({ index: 2, x: 5, y: 5, z: 5, isHelper: false,//是否开启了辅助线 isAutoRotate: false,//是否开启了自动旋转 }) const mtlLoader2 = new MTLLoader() const objLoader2 = new OBJLoader() //辅助观察的坐标系 const axesHelper = new THREE.AxesHelper(100); //光源设置 // const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // directionalLight.position.set(92, 100, 100); // scene.add(directionalLight); // const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5); // directionalLight2.position.set(-92, -100, -100); // scene.add(directionalLight2); const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight2.position.set(50, 100, -100); scene.add(directionalLight2); //渲染器和相机 const width = window.innerWidth; const height = width / 1.5 > 500 ? 500 : width / 1.5; const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000); camera.position.set(150, 300, 200); camera.lookAt(0, 0, 0); const renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0xffffff);//画布颜色 renderer.setSize(width, height); renderer.antialias = true; renderer.alpha = true; renderer.precision = 'mediump' renderer.setPixelRatio(window.devicePixelRatio); //解决加载gltf格式模型颜色偏差问题 renderer.outputEncoding = THREE.sRGBEncoding; // 设置相机控件轨道控制器OrbitControls const controls = new OrbitControls(camera, renderer.domElement); // controls.maxPolarAngle = 1.5 // 上下翻转的最大角度 // controls.minPolarAngle = -1.5 // 上下翻转的最小角度 // 渲染循环 function render() { renderer.render(scene, camera); if (data.isAutoRotate) { controls.autoRotate = true // 是否自动旋转 controls.update(); } else { controls.autoRotate = false // 是否自动旋转 } const id = requestAnimationFrame(render); // console.log("render--->" + id) } render(); // // 画布跟随窗口变化 // window.onresize = function () { // renderer.setSize(window.innerWidth, window.innerHeight); // camera.aspect = window.innerWidth / window.innerHeight; // camera.updateProjectionMatrix(); // }; defineProps({ msg: '上面传下来的', }) function addUI() { console.log("开始加载渲染-->") document.getElementById('webgl1').appendChild(renderer.domElement); document.getElementById('webgl1').addEventListener('click', function (e) { console.log("x------>" + camera.position.x) console.log("y------>" + camera.position.y) console.log("z------>" + camera.position.z) // data.x = camera.position.x + 1; // data.y = camera.position.y; // data.z = camera.position.z; // camera.position.set(data.x, data.y, data.z); //x轴方向观察 // camera.lookAt(0, 0, 0); //重新计算相机视线方向 }) } onMounted(() => { addUI(); helperControl(false); autoRotateControl(true); draw3D(); }) //辅助函数 function helperControl(isOpen) { if (data.isHelper === isOpen) return; data.isHelper = isOpen; if (data.isHelper) { scene.add(axesHelper); } else { scene.remove(axesHelper); } } function autoRotateControl(isOpen) { console.log("----->" + isOpen); if (data.isAutoRotate === isOpen) return; data.isAutoRotate = isOpen; } function draw3D() { data.index++; if (data.index === 1) { mtlLoader2.load('../../static/9038.mtl', material => { material.preload() //mtl文件中的材质设置到obj加载器 console.log(material.materials) objLoader2.setMaterials(material) objLoader2.load( '../../static/9038.obj', loadedMesh => { console.log(loadedMesh) //设置模型大小 loadedMesh.scale.set(1, 1, 1) //设置模型位置 loadedMesh.position.set(5, 5, 5); scene.add(loadedMesh) camera.position.set(400, 400, 400); } ) }) } else if (data.index === 2) { // 加载gltf/glb三维模型 loader.load('../../static/scene.gltf', function (gltf) { console.log('gltf load ---->', gltf.scene); model.add(gltf.scene); }) scene.add(model); // 模型对象添加到场景中 camera.position.set(data.x, data.y, data.z); } else if (data.index === 3) { // 加载gltf/glb三维模型 loader.load(three9038, function (gltf) { console.log('gltf load ---->', gltf.scene); model.add(gltf.scene); }) scene.add(model); // 模型对象添加到场景中 } } {{ msg }}----{{ data.index }} 开启坐标辅助线 关闭坐标辅助线 开启自动旋转 停止自动旋转 换一个3D模型 root { padding: 0px; } .divThree { width: auto; height: auto; align-items: center; margin: 0px auto; background-color: green; } button { margin-left: 1em; margin-top: 1em; }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3