下面是针对"Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析"的完整攻略,包括两个示例的说明。
Vue集成three.js并加载模型的场景分析
前言
Three.js是一个基于webgl开发的JavaScript 3D库,它能够让开发人员通过JS创建各种3D场景。同时,Vue则是一个较为流行的JavaScript开发框架,可以轻松地搭建Web应用。
在本篇文章中,我们将结合这两种技术,介绍如何在Vue中集成three.js,并成功加载gltf、glb、fbx和json模型。
准备工作
首先,我们需要创建一个Vue项目。可以使用如下命令:
vue create vue-threejs-model
运行上述命令后,在相应的目录下面,一个与项目名相同的文件夹便会被创建。
接下来,我们需要安装three.js。在终端中,运行如下命令:
cd vue-threejs-model
npm install three
在我们能够使用three.js之前,需要在项目中引入它。在main.js文件中,添加如下代码:
import * as THREE from 'three'
window.THREE = THREE // 特别注意:必须将three.js绑定在window对象上,否则在后面的GLTFLoader、FBXLoader和OrbitControls等模块中会找不到THREE
这样,我们就可以在Vue中使用three.js了。
加载模型
在本节中,我们将介绍如何加载gltf、glb、fbx和json模型。
GLTF/GLB
GLTF和GLB是行业标准的3D模型格式,在三维渲染领域中应用非常广泛。three.js中提供了GLTFLoader模块用于加载gltf/glb格式的3D模型。
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const loader = new GLTFLoader()
loader.load('model.gltf', (gltf) => {
scene.add(gltf.scene)
})
以上代码会将model.gltf文件加载到场景scene中。
GLTFLoader还提供了许多可选的属性,例如在此处增加使用代码:
const loader = new GLTFLoader()
loader.load('model.gltf', (gltf) => {
gltf.scene.traverse((node) => {
if (node instanceof THREE.Mesh) {
// 设置材质
node.material.side = THREE.DoubleSide // 可以看到内置表面
node.material.transparent = true
node.material.opacity = 0.8
}
})
scene.add(gltf.scene)
}, undefined, (error) => {
console.error(error)
})
这个示例演示了如何在模型加载完成后,遍历模型的所有子元素,以设置材质效果。同时,我们对于模型本身的信息,如 loading 、progress 和 error 等,三个回调函数都在对象内提供。不过,只有前两个回调函数是必须要的,否则如果在加载时出现错误,我们将无法收到错误信息。
FBX
FBX是另一个流行的3D模型格式,它由Autodesk开发并且广泛用于游戏和影视制作中。与GLTF一样,three.js中也提供了FBXLoader模块(需要单独安装)用于加载fbx格式的3D模型。
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
const loader = new FBXLoader()
loader.load('model.fbx', (fbx) => {
scene.add(fbx)
})
JSON
除GLTF、GLB和FBX外,three.js还支持JSON格式。JSON格式之所以老行业不推荐使用,是因为它需要多余的字符串量(甚至比二进制文件还要多),因此其体积相对较大。但是,在某些场景下,还是可以考虑使用JSON格式。
顾名思义,JSONLoader模块可以用于加载JSON格式的3D模型。
import { JSONLoader } from 'three'
const loader = new JSONLoader();
loader.load('model.json', (geometry, materials) => {
const material = new THREE.MultiMaterial(materials)
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
})
总结
在本篇文章中,我们介绍了在Vue中集成three.js,以及如何成功加载不同格式的3D模型文件。不过,值得注意的是,当模型文件过大时,加载时可能会产生明显的延迟。因此,对于较大的模型,我们建议在loading过程中增加合适的预加载界面,从而增加用户体验。
示例代码
下面是一个基于Vue和three.js的简单示例代码:
<template>
<div class="three-container">
<div ref="dom" class="three-dom"></div>
</div>
</template>
<style scoped>
.three-container {
width: 100%;
height: 100%;
overflow: hidden;
}
.three-dom {
width: 100%;
height: 100%;
}
</style>
<script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
name: 'ThreeContainer',
data() {
return {
scene: null,
renderer: null,
camera: null,
controls: null,
group: null
}
},
mounted() {
this.initScene()
this.animate()
},
methods: {
initScene() {
this.scene = new THREE.Scene()
// 环境光
const ambientLight = new THREE.AmbientLight(0x666666)
this.scene.add(ambientLight)
// 添加照相机
this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
this.camera.position.set(0, 4, 10)
this.scene.add(this.camera)
// 添加渲染器
this.renderer = new THREE.WebGLRenderer({
antialias: true
})
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.setSize(window.innerWidth, window.innerHeight)
this.renderer.setClearColor(0x132c3e)
this.$refs.dom.appendChild(this.renderer.domElement)
// OrbitControls
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.enableDamping = true
this.controls.dampingFactor = 0.2
this.controls.screenSpacePanning = false
this.controls.minDistance = 1
this.controls.maxDistance = 10
this.controls.maxPolarAngle = Math.PI / 2
// 添加group
this.group = new THREE.Group()
this.scene.add(this.group)
// 加载模型
const loader = new GLTFLoader()
loader.load('model.gltf', (gltf) => {
gltf.scene.traverse((node) => {
if (node instanceof THREE.Mesh) {
node.material.side = THREE.DoubleSide
}
})
this.group.add(gltf.scene)
}, undefined, (error) => {
console.error(error)
})
// 监听窗口大小变化
window.addEventListener('resize', this.handleResize)
},
animate() {
window.requestAnimationFrame(() => {
this.animate()
})
this.controls.update()
this.renderer.render(this.scene, this.camera)
},
handleResize() {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
}
}
}
</script>
<template>
<div>
<ThreeContainer />
</div>
</template>
<script>
import ThreeContainer from '@/components/ThreeContainer'
export default {
name: 'App',
components: {
ThreeContainer
}
}
</script>
在index.html中加入CSS样式,全局设置height为100%:
<style>
html, body {
height: 100%;
margin: 0;
}
</style>
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析 - Python技术站