前面的章节我们都是通过HTML+JS的方式创建三维场景,从这一章节开始,我们后面将使用vite+vue3+threejs来构建三维场景。
搭建项目环境
打开vscode的终端管理器,输入如下命令
npm create vite@latest vue3-threejs-app --template vue
在弹出的选择框架提醒中,按上下键盘键,选择Vue,然后回车
选择JavaScript,回车
提示项目创建完成,
输入cd vue3-threejs-app,进入该文件夹,输入npm install 安装项目需要的依赖
输入npm run dev 运行查看效果
目录结构
项目创建完成后,目录结构如下图所示
public 目录用于存放静态文件
src 目录用于存放源代码
assets 目录用于存放静态资源,例如图片、字体等
components 目录用于存放组件
App.vue 是应用程序的根组件
main.js 是应用程序的入口文件
vite.config.ts vite配置文件
安装threejs
终端中输入npm install three
安装threejs
清楚App.vue页面默认内容及格式
清楚App.vue中的HelloWorld组件及原因内容,新建一个Id为scene的div作为三维场景的容器,App.vue中代码如下
<template>
<div id="scene">
</div>
</template>
<script setup>
</script>
<style scoped>
</style>
清空style.css中的样式,清空外边距和内边距
* {
margin: 0;
padding: 0;
}
新建3dModules文件夹
在public文件夹下,新建3dModules文件夹,用于存放三维模型文件,将要展现在页面上的motor03.gltf文件拷贝到该文件夹
新建utils文件夹
在src文件夹下下新建utils文件夹,用于存放工具类js代码,在该文件夹下新建motor3d.js文件,该文件用于通过threejs创建三维场景,并挂载到div上进行展示
引入Threejs库文件、轨道控制器和GLTF加载器
在motor3d.js中引入Threejs库文件,并引入轨道控制器和GLTFLoader文件
import * as THREE from 'three'//导入three.js核心库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //导入轨道控制器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'//导入GLTF模型加载器
创建motor3d类,并导出
在motor3d.js中新建一个motor3d类,并使用export default方法将其导出
class motor3d {
}
export default motor3d
创建构造函数
为了更好的使用motor3d模块,我们在motor3d类中创建一个构造函数,用于初始化motor3d对象;
class motor3d {
constructor(selector) {
this.container = document.querySelector(selector)//获取容器
this.scene
this.camera
this.renderer
this.controls
this.init() //初始化
this.animate()//循环函数
}
}
创建init()函数
创建好构造函数后,我们来创建init()函数,该函数用于初始化场景、相机、灯光、渲染器等
init() {
// 初始化场景
this.initScene()
// 初始化辅助轴
this.initAxesHelper()
// 初始化灯光
this.initLight()
// 初始化相机
this.initCamera()
// 初始化渲染器
this.initRender()
// 初始化轨道控制器
this.initControls()
// 监听场景大小改变,重新渲染尺寸
window.addEventListener('resize',this.onWindowResize.bind(this))
}
创建initScene() 函数
initScene() 函数用于实例化Threejs的场景,
initScene() {
this.scene = new THREE.Scene()
this.scene.background = new THREE.Color(0xa0a0a0)
}
创建initAxesHelper() 函数
initAxesHelper()函数用于在场景中添加辅助轴线,帮助我们更好的理解场景信息
initAxesHelper() {
const axesHelper = new THREE.AxesHelper(5)
this.scene.add(axesHelper)
}
创建initLight() 函数
initLight() 函数用于初始化灯光,并添加到场景中
initLight() {
const hesLight = new THREE.HemisphereLight(0xffffff,0x444444)
hesLight.intensity = 0.6
this.scene.add(hesLight)
const dirLight = new THREE.DirectionalLight()
dirLight.position.set(5,5,5)
this.scene.add(dirLight)
}
创建initCamera() 函数
initCamera()函数用于初始化相机
initCamera() {
this.camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,100)
this.camera.position.set(1.5,1.5,1.5)
}
创建initRender() 函数
创建initRender()函数,初始化渲染器
initRender() {
this.renderer = new THREE.WebGLRenderer({antialias:true})//设置抗锯齿
//设置屏幕像素比
this.renderer.setPixelRatio(window.devicePixelRatio)
//渲染的尺寸大小
this.renderer.setSize(window.innerWidth,window.innerHeight)
// 添加到容器
this.container.appendChild(this.renderer.domElement)
}
创建render() 函数
render() {
this.renderer.render(this.scene,this.camera)
}
创建animate() 函数
animate() {
this.renderer.setAnimationLoop(this.render.bind(this))
}
创建initControls() 函数
initControls() {
this.controls = new OrbitControls(this.camera,this.renderer.domElement)
}
创建onWindowResize() 函数
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()//更新矩阵,将3d内容投射到2d画面上转换
this.renderer.setSize(window.innerWidth,window.innerHeight)
}
至此,我们已经基本将三维场景搭建完成了,在App.vue中引入motor3d.js文件,并在onMounted()中实例化该对象
App.vue中代码如下
<template>
<div id="scene">
</div>
</template>
<script setup>
import motor3d from './utils/motor3d';
import { onMounted } from 'vue';
onMounted(()=>{
new motor3d('#scene')
})
</script>
<style scoped>
</style>
刷新浏览器,我们看到三维场景已经搭建完成了
初始化物体
接下来我们将模型添加到三维场景中,首先我们创建一个添加GLTF文件的方法
添加addGLTFModel(modelName) 方法
// 加载模型
addGLTFModel(modelName) {
return new Promise((resolve,reject) => {
const loader = new GLTFLoader().setPath('3dModels/')
loader.load(modelName,(gltf) =>{
console.log(gltf);
this.scene.add(gltf.scene)
resolve(this.modelName + '模型添加成功')
})
})
}
创建initMesh() 方法
创建initMesh() 方法,在该方法中调用上面的addGLTFModel()方法,并传入3dModels文件夹下GLTF文件的名称
initMesh() {
this.addGLTFModel('motor03.gltf')
}
在init() 方法中调用initMesh()方法
init() {
// 初始化场景
this.initScene()
// 初始化辅助轴
this.initAxesHelper()
// 初始化灯光
this.initLight()
// 初始化Mesh
this.initMesh()
// 初始化相机
this.initCamera()
// 初始化渲染器
this.initRender()
// 初始化轨道控制器
this.initControls()
// 监听场景大小改变,重新渲染尺寸
window.addEventListener('resize',this.onWindowResize.bind(this))
}
刷新浏览器,看效果
这里我们遇到了和前面将到的threejs和gltf模型颜色色差的问题,将如下代码添加到渲染器初始化函数中文章来源:https://www.toymoban.com/news/detail-659943.html
//解决加载gltf格式模型纹理贴图和原图不一样问题
this.renderer.outputEncoding = THREE.sRGBEncoding;
重新刷新浏览器,问题解决
好的,基于vite+vue3+threejs方式构建Threejs三维场景的方法就说道这里,喜欢的朋友点赞关注收藏哦!文章来源地址https://www.toymoban.com/news/detail-659943.html
到了这里,关于Threejs进阶之一:基于vite+vue3+threejs构建三维场景的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!