1、安装所需的依赖:在Vue项目的根目录下打开终端,并执行以下命令来安装Three.js和GLTFLoader库。
npm install three gltf-loader
npm install three fbx-loader
2、在需要展示模型的组件中导入所需的库。
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
3、创建模型公共名
const gltf_loader = new GLTFLoader()
const fbx_loader = new FBXLoader()
4、在组件的生命周期钩子函数中编写加载和展示gltf模型的代码。例如,在mounted钩子函数中加载并展示模型。
mounted() {
this.$nextTick(() => {
this.init()
})
},
5、
初始化场景
init() {
// 创建场景和相机
this.scene = new THREE.Scene()
this.createLight() // 创建光源
this.createLight() // 创建光源
this.createCamera() // 创建相机
this.createRender() // 创建渲染器
this.createControls() //创建控制器
this.render() // 渲染
// 添加 resize 监听事件
window.addEventListener('resize', this.onWindowResize, {
passive: false
})
// 将 renderer.domElement 的 tabIndex 属性设置为 1
this.renderer.domElement.tabIndex = 1
},
6、
// 创建光源
createLight() {
// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
this.scene.add(ambientLight) // 将环境光添加到场景
},
// 创建相机
createCamera() {
const width = window.innerWidth // 窗口宽度
const height = window.innerHeight // 窗口高度
const k = width / height // 窗口宽高比
// PerspectiveCamera( fov, aspect, near, far )
this.camera = new THREE.PerspectiveCamera(20, k, 0.1, 1000)
this.camera.position.set(-330, 10, 0) // 设置相机位置
this.camera.lookAt(new THREE.Vector3(0, 30, 10)) // 设置相机方向
this.scene.add(this.camera)
},
// 创建渲染器
createRender() {
const element = document.getElementById('container_uwb_Bim')
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染区域尺寸
this.renderer.shadowMap.enabled = true // 显示阴影
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
this.renderer.setClearColor(0xffffff, 0.1) // 设置背景颜色
this.renderer.autoClear = false // 关闭自动清除
this.renderer.sortObjects = false // 禁用对象排序
this.renderer.state.setBlending(THREE.NormalBlending)
element.appendChild(this.renderer.domElement)
},
render() {
// if (this.mesh) {
// this.mesh.rotation.z += 0.006
// }
// 添加点击事件
this.renderer.domElement.addEventListener('click', this.onMouseClick, {
passive: false
})
this.renderer.render(this.scene, this.camera)
},
// 创建控件对象
createControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.enableDamping = true // 启用阻尼效果,控制器会根据速度缓慢停止运动
this.controls.dampingFactor = 0.25 // 阻尼系数,控制阻尼效果的强度
this.controls.screenSpacePanning = false // 控制平移是否基于屏幕坐标而非场景坐标
this.controls.minDistance = 1 // 最小缩放距离
this.controls.maxDistance = 20000 // 最大缩放距离
},
animate() {
// 更新 OrbitControls 控制器
this.controls.update()
// 渲染场景
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this.animate)
},
onWindowResize() {
// 更新渲染器大小
// 这部分代码用于更新相机的宽高比(aspect)和投影矩阵(projectionMatrix)。在 Three.js 中,相机使用投影矩阵来将三维场景中的坐标映射到二维屏幕上,而投影矩阵的计算需要使用相机的宽高比。因此在窗口尺寸发生变化时,需要更新相机的宽高比和投影矩阵。
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
// 这部分代码用于更新渲染器的尺寸。Three.js 渲染器需要知道渲染区域的大小才能正确地渲染场景,因此在窗口尺寸发生变化时,需要更新渲染器的大小。
this.renderer.setSize(window.innerWidth, window.innerHeight)
// 这部分代码则是通过改变渲染器 DOM 元素的 CSS 样式来使其与窗口大小保持一致。由于渲染器默认使用 CSS position: absolute 定位,因此需要设置其左上角的坐标(left 和 top)为 0,以充满整个窗口。同时需要将渲染器 DOM 元素的宽高设置为与窗口一致,以使渲染器的尺寸保持不变。
this.renderer.domElement.style.width = `${window.innerWidth}px`
this.renderer.domElement.style.height = `${window.innerHeight}px`
this.renderer.domElement.style.left = 0
this.renderer.domElement.style.top = 0
}
7、
现在可以来加载模型了 案例以gltf为例 其他格式同理
// 加载模型的函数
loadModelInit(url, callback) {
// 检查模型是否已被缓存
if (this.cache.models[url]) {
callback(this.cache.models[url])
return
}
// 如果模型未被缓存,则进行加载
gltf_loader.load(
url,
(gltf) => {
gltf.scene.traverse((child) => {
if (child.isMesh) {
// console.log(child.material)
child.material.emissive = child.material.color
child.material.emissiveMap = child.material.map
child.material.transparent = true // 启用透明度
child.material.opacity = 0.5 // 设置透明度为0.5(半透明)
}
})
// 将模型存入缓存
this.cache.models[url] = gltf.scene
callback(gltf.scene)
},
undefined,
(error) => {
console.log('加载出错', error)
}
)
},
// 使用 GLTFLoader 加载 gltf 模型
loadModel() {
this.loadModelInit(this.uwbBim_url, (model) => {
// 在回调函数中处理已加载的模型
this.mesh = model
this.scene.add(this.mesh)
this.animate()
})
},