Vue中用Three.js创建一个3D会议室(一)初步创建

本文介绍了使用Three.js构建3D会议室的过程,包括场景、相机、灯光的初始化,以及 OrbitControls 轨道控制器的使用。作者分享了在Vue项目中引入Three.js的注意事项,如性能优化和插件应用,同时展示了实时性能监控和3D交互功能。文章适合Three.js初学者阅读,旨在提供一个基础的3D开发实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一章

前言

最近在研究Three.js 3D开发,正好迎合项目需求做了一个简易的3D会议室,因为完全是第一次开发,也没什么经验,所以虽然经过各种资料搜集以及实践最后完成了一些功能,但是代码逻辑吗嘿嘿,懂得都懂。

效果展示

在这里插入图片描述
在这里插入图片描述
看起来是比较空旷,没有往里面加入过多的元素,除了3D效果展示之外,会议室中所有设备都支持移动和角度旋转,并且会执行一定的物理规则校验,如重力以及与墙壁之间的碰撞效果等

初步实现

引入Three.js

对于Vue项目,首先当然是要引入相关依赖,可以采用npm安装或者用sprict标签引入外部资源,这里我就从我采用的方式npm安装来往下进行:
npm i three 安装three.js

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as Stats from "three/examples/js/libs/stats.min.js";

对于一个Vue项目中,Three.js我们只是会在部门模块中引用,所以我们最好不要再main.js中全局引用它,而是选择在相关模块的代码中去引用,除了需要引用THREE对象之外,我们可能还需要用到许多three.js的插件,这里我用的方法比较笨,从node_modules中去找相关的插件并引用它,至于如何找到相关插件的位置,可以参考官网中下载来的three.js的目录结构

创建3D场景

在这里有一点需要注意,虽然我们是Vue项目,但是不要将three.js封装的scenecamera等对象保存在data中,这样十分消耗性能,推荐在生命周期mounted中注册,在beforeDestory中注销,代码如下图所示

mounted() {
    this.scene = null; // 场景
    this.camera = null; // 相机
    this.renderer = null; // 渲染器
    this.stats = null; // 性能检测器
    this.animateAbled = true; // 是否开启帧数动画检测
    this.selectObject = null; // 鼠标点击选中的物体
    this.dragControls = null; // 拖拽对象
    this.cube = null; // 碰撞的对象
    this.selectGroup = null; // 选中的组
    this.init();
    this.loader = new OBJLoader();
    this.mat = new MTLLoader();
    this.createFloor();
    this.animate();
  },
  beforeDestroy() {
    // 清空设置,注销事件
    this.scene = null;
    this.camera = null;
    this.renderer = null;
    this.stats = null;
    this.animateAbled = false;
    this.cube = null;
    this.dragControls = null;
    document.removeEventListener("click", this.mouseClick, false);
    document.removeEventListener("resize", this.setResize, false);
  },

接下来就是初始化3D场景,相机,灯光等等3D因素,具体的大家可以去three.js官网学习,我在下面给一个简单的例子

  // 初始化
  init() {
    this.floorCanvas = document.getElementById("floorCanvas"); // 注册容纳3D内容的画布
    this.initScene();
    this.initCamera();
    this.initLight();
    this.initRenderer();
  },
   // 初始化场景
  initScene() {
    this.scene = new THREE.Scene();
    this.scene.fog = new THREE.Fog(this.scene.background, 3000, 5000);
  },
  // 初始化相机
  initCamera() {
    this.camera = new THREE.PerspectiveCamera(
      70,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    this.camera.position.set(0, 200, 280);
    this.camera.lookAt(new THREE.Vector3(0, 0, 0));
    // let helper = new THREE.CameraHelper(this.camera);
    // this.scene.add(helper);
  },
  // 初始化灯光
  initLight() {
    let directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); //模拟远处类似太阳的光源
    directionalLight.color.setHSL(0.5, 0.5, 0.8);
    directionalLight.position.set(0, 200, 0).normalize();
    this.scene.add(directionalLight);

    let ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源
    ambient.position.set(0, 0, 0);
    this.scene.add(ambient);
  },
  // 初始化渲染器
  initRenderer() {
    this.renderer = new THREE.WebGLRenderer({ antialias: true });
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setClearColor(0x4682b4, 1.0); // 渲染场景的颜色
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.floorCanvas.appendChild(this.renderer.domElement);
  },

init函数中调用几个场景元素的初始化函数,init函数在上个代码块中对应,在一开始的mounted中调用,需要注意的是,3D场景相当于是画布的3D渲染,所以我们需要注册一个“画布”去承载3D渲染

可能需要的一些额外插件

如果在开发中需要一些额外插件,一定不要忘了引用

性能

// 初始化性能插件
    initStats() {
      let stats = new Stats();
      stats.domElement.style.position = "absolute";
      stats.domElement.style.left = "0px";
      stats.domElement.style.top = "0px";
      this.floorCanvas.appendChild(stats.domElement);
      this.stats = stats;
    },

主要用到了Stats插件,这个可以显示当前3D渲染所消耗的性能、以及其帧数等,可以自定义其样式,也就是下面图的效果
在这里插入图片描述

轨道控制器

轨道控制器简单来说就是鼠标操纵屏幕的观察视角,可以通过鼠标达到放大缩小以及转换角度的效果,具体请去官网中学习,下面是示例代码

// 初始化轨道控制器
    initControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.dampingFactor = 0.2;
      // 视角最小距离
      this.controls.minDistance = 100;
      // 视角最远距离
      this.controls.maxDistance = 5000;
      // 最大角度
      this.controls.maxPolarAngle = Math.PI / 1.9;
      // this.controls.maxPolarAngle = 0;
    },

这里面也用到了插件OrbitControls,可以配置视角的最大以及最小距离和角度等等,这段代码中的角度设置主要是为了让视角的最大角度缩小,只能观察到物体的顶部与四周,而不会像默认视角一样360度无死角的来回翻转,效果如下
在这里插入图片描述

结束语

这是3D会议室创建的第一步,也是我第一次尝试写一个完整的Demo总结。
如果对大家能有帮助那自然是最好,如果有不足也希望大家指点出来,第一章内容不多比较基础,也是3D渲染最基础的部分,我会在下面篇章更新具体的新内容。
大家一起加油!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值