前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Threejs进阶之一:基于vite+vue3+threejs构建三维场景

Threejs进阶之一:基于vite+vue3+threejs构建三维场景

作者头像
九仞山
修改2023-05-19 09:32:43
修改2023-05-19 09:32:43
7.5K10
代码可运行
举报
文章被收录于专栏:前端漫步前端漫步
运行总次数:0
代码可运行

前面的章节我们都是通过HTML+JS的方式创建三维场景,从这一章节开始,我们后面将使用vite+vue3+threejs来构建三维场景。

搭建项目环境

打开vscode的终端管理器,输入如下命令

代码语言:javascript
代码运行次数:0
复制
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中代码如下

代码语言:javascript
代码运行次数:0
复制
<template>
  <div id="scene">    
  </div>
</template>
<script setup> 
</script>
<style scoped> 
</style>

清空style.css中的样式,清空外边距和内边距

代码语言:javascript
代码运行次数:0
复制
* {
  margin: 0;
  padding: 0;
}

新建3dModules文件夹

在public文件夹下,新建3dModules文件夹,用于存放三维模型文件,将要展现在页面上的motor03.gltf文件拷贝到该文件夹

新建utils文件夹

在src文件夹下下新建utils文件夹,用于存放工具类js代码,在该文件夹下新建motor3d.js文件,该文件用于通过threejs创建三维场景,并挂载到div上进行展示

引入Threejs库文件、轨道控制器和GLTF加载器

在motor3d.js中引入Threejs库文件,并引入轨道控制器和GLTFLoader文件

代码语言:javascript
代码运行次数:0
复制
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方法将其导出

代码语言:javascript
代码运行次数:0
复制
class motor3d {
}
export default motor3d

创建构造函数

为了更好的使用motor3d模块,我们在motor3d类中创建一个构造函数,用于初始化motor3d对象;

代码语言:javascript
代码运行次数:0
复制
class motor3d {
constructor(selector) {    
    this.container = document.querySelector(selector)//获取容器
    this.scene
    this.camera 
    this.renderer
    this.controls
    this.init() //初始化
    this.animate()//循环函数
  }
} 

创建init()函数

创建好构造函数后,我们来创建init()函数,该函数用于初始化场景、相机、灯光、渲染器等

代码语言:javascript
代码运行次数:0
复制
init() {
    // 初始化场景
    this.initScene()    
    // 初始化辅助轴
    this.initAxesHelper()
    // 初始化灯光
    this.initLight() 
    // 初始化相机
    this.initCamera()
    // 初始化渲染器
    this.initRender()
    // 初始化轨道控制器
    this.initControls()
    // 监听场景大小改变,重新渲染尺寸
    window.addEventListener('resize',this.onWindowResize.bind(this))
  }
创建initScene() 函数

initScene() 函数用于实例化Threejs的场景,

代码语言:javascript
代码运行次数:0
复制
initScene() {
    this.scene = new THREE.Scene()
    this.scene.background = new THREE.Color(0xa0a0a0)
}
创建initAxesHelper() 函数

initAxesHelper()函数用于在场景中添加辅助轴线,帮助我们更好的理解场景信息

代码语言:javascript
代码运行次数:0
复制
 initAxesHelper() {
    const axesHelper = new THREE.AxesHelper(5)
    this.scene.add(axesHelper)
  }
创建initLight() 函数

initLight() 函数用于初始化灯光,并添加到场景中

代码语言:javascript
代码运行次数:0
复制
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()函数用于初始化相机

代码语言:javascript
代码运行次数:0
复制
 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()函数,初始化渲染器

代码语言:javascript
代码运行次数:0
复制
  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() 函数
代码语言:javascript
代码运行次数:0
复制
 render() {    
    this.renderer.render(this.scene,this.camera)
  }
创建animate() 函数
代码语言:javascript
代码运行次数:0
复制
  animate() { 
    this.renderer.setAnimationLoop(this.render.bind(this))
  }
创建initControls() 函数
代码语言:javascript
代码运行次数:0
复制
  initControls() {
    this.controls = new OrbitControls(this.camera,this.renderer.domElement)
  }
创建onWindowResize() 函数
代码语言:javascript
代码运行次数:0
复制
  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中代码如下

代码语言:javascript
代码运行次数:0
复制
<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) 方法
代码语言:javascript
代码运行次数:0
复制
// 加载模型
  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文件的名称

代码语言:javascript
代码运行次数:0
复制
initMesh() {
    this.addGLTFModel('motor03.gltf')
  }
在init() 方法中调用initMesh()方法
代码语言:javascript
代码运行次数:0
复制
  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模型颜色色差的问题,将如下代码添加到渲染器初始化函数中

代码语言:javascript
代码运行次数:0
复制
    //解决加载gltf格式模型纹理贴图和原图不一样问题
    this.renderer.outputEncoding = THREE.sRGBEncoding;

重新刷新浏览器,问题解决

好的,基于vite+vue3+threejs方式构建Threejs三维场景的方法就说道这里,喜欢的朋友点赞关注收藏哦!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 搭建项目环境
  • 目录结构
  • 安装threejs
  • 清楚App.vue页面默认内容及格式
  • 新建3dModules文件夹
  • 新建utils文件夹
    • 引入Threejs库文件、轨道控制器和GLTF加载器
    • 创建motor3d类,并导出
    • 创建构造函数
    • 创建init()函数
      • 创建initScene() 函数
      • 创建initAxesHelper() 函数
      • 创建initLight() 函数
      • 创建initCamera() 函数
      • 创建initRender() 函数
      • 创建render() 函数
      • 创建animate() 函数
      • 创建initControls() 函数
      • 创建onWindowResize() 函数
    • 初始化物体
      • 添加addGLTFModel(modelName) 方法
      • 创建initMesh() 方法
      • 在init() 方法中调用initMesh()方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档