在Vue中搭建Three.js环境(超详细、保姆级),创建场景、相机、渲染器《一》

avatar
作者
筋斗云
阅读量:0

目录

Three.js简介

Three.js 是一款基于 WebGL的 JavaScript 3D 库,它封装了 WebGL API,为开发者提供了简单易用的 API 来在 Web 浏览器中展示 3D 图形。Three.js 提供了多种组件、方法和工具,用于创建和处理 3D 图形,使得开发者可以在 Web 浏览器中快速创建 3D 场景和动画,而不需要深入了解 WebGL 的底层实现。

简单来说:它就是一个绘制 3D 的 javaScript 轻量级框架;
能干什么:游戏,地图,智能工厂,智慧园区,360°模型 ,建筑家装,3d物联网 ,能干的东西太多了,不一一说了,自己想去吧。
官方网址:https://threejs.org

好了好了,介绍到这里就行了,已经够多了,官方的介绍很详细,来来来 步入正题…

创建vue项目

你不想用vue也可以,不强求,但我想用!!!

  1. 在合适的文件夹目录 1 下去打开cmd(windows小黑窗口)窗口或者Terminal(Mac终端),这俩不知道的话,就别往下看了。在弹出的窗口中输入以下命令,回车即可。
vue create demo 

注: 啥啥啥?vue不是内部或外部命令?点我点我

  1. 选择VUE2,本讲解以VUE2来进行2 ,所以选择VUE2。 上下键去选,选完以后回车。
    在这里插入图片描述
  2. 展示以下结果代表创建成果,没报错就是创建成功了。
    在这里插入图片描述

引入Three.js

  1. 使用WebStorm(你想用什么工具都可以,不强求)打开刚才创建的项目。
    在这里插入图片描述
  2. 在开发工具的Terminal中输入以下内容回车。
 npm install three 

在这里插入图片描述

实际操作环节

文件目录创建

  1. 在src下创建js文件目录
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 并创建ThreeJs.js文件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

初始化场景、相机

  1. Three他是一个右手系的X、Y、Z,如下图所示:
    在这里插入图片描述

  2. 引入Three文件,创建ThreeJs的通用组件方法,使用构造器构建组件。

import * as THREE from 'three'; export default class ThreeJs{          constructor(id){         //根据传入的id,去获取他的dom节点,用来加载三维模型         this.id=id;         this.dom=document.getElementById(id);     }     } 
  1. 创建initThree方法,用来初始化场景,动画的宽高,和相机。
 initThree(){         //创建场景scene         this.scene=new THREE.Scene();         //获取dom的宽和高         this.width=this.dom.offsetWidth         this.height=this.dom.offsetHeight;         //创建相机,fov:视角 aspect:宽高比 near:近裁剪面 far:远裁剪面         this.camera=new THREE.PerspectiveCamera(45,this.width/this.height,1,1000);        	//设置相机位置         this.camera.position.set(0,0,0);     } 

:相机的相关解释,这个必须要详细的介绍一下,这个很关键。也可以点击链接看官方文档 官方

序号相机含义
1ArrayCamera(摄像机阵列)ArrayCamera 用于更加高效地使用一组已经预定义的摄像机来渲染一个场景。这将能够更好地提升VR场景的渲染性能。一个 ArrayCamera 的实例中总是包含着一组子摄像机,应当为每一个子摄像机定义viewport(视口)这个属性,这一属性决定了由该子摄像机所渲染的视口区域的大小。
2Camera(摄像机)摄像机的抽象基类。在构建新摄像机时,应始终继承此类。
3CubeCamera(立方相机)创建6个渲染到WebGLCubeRenderTarget的摄像机。
4OrthographicCamera(正交相机)这一摄像机使用orthographic projection(正交投影)来进行投影。在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。这对于渲染2D场景或者UI元素是非常有用的。。
5PerspectiveCamera(透视相机)这一摄像机使用perspective projection(透视投影)来进行投影。这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。
6StereoCamera(立体相机)双透视摄像机(立体相机)常被用于创建3D Anaglyph(3D立体影像) 或者Parallax Barrier(视差屏障)。
  1. 修改相机观看位置点位,默认让他看原点
this.camera.looAt(0,0,0) 
  1. 追加webGL的渲染器,他是用来调用浏览器的GPU,去进行实时渲染(前提浏览器已经支持GPU)
 this.renderer=new THREE.WebGLRenderer({antialias:true,alpha:true,logarithmicDepthBuffer:true}) 

注: antialias:是否开启锯齿,alpha:是否开启透明,logarithmicDepthBuffer:是否开启对数深度缓存。

  1. 设置渲染器的像素比,设置渲染器的输出颜色,设置渲染器的大小。
   // 设置渲染器的像素比    this.renderer.setPixelRatio(window.devicePixelRatio);    //渲染器的输出颜色    this.renderer.outputEncoding=THREE.sRGBEncoding;    //设置渲染器的大小    this.renderer.setSize(this.width,this.height); 
  1. 将渲染器的dom元素,添加至我们div的dom元素中
    this.dom.append(this.renderer.domElement); 
  1. 监听浏览器大小,去更新相机的矩阵
    // 监听浏览器大小,去更新相机的矩阵     window.addEventListener('resize',()=>{         // 更新相机的宽高比         this.camera.aspect=this.dom.offsetWidth/this.dom.offsetHeight;         this.camera.updateProjectionMatrix();         //更新渲染器的大小         this.renderer.setSize(this.dom.offsetWidth,this.dom.offsetHeight);         if(this.cssRenderer){             this.cssRenderer.setSize(this.dom.offsetWidth,this.dom.offsetHeight);         }     }) 
  1. initThree()方法完整版如下
    initThree(){         //这个初始化的是场景         this.scene= new THREE.Scene();         this.width=this.dom.offsetWidth;         this.height=this.dom.offsetHeight;         this.camera= new THREE.PerspectiveCamera(45,this.width/this.height,1,1000);          this.camera.position.set(0,0,0);         this.camera.lookAt(0,0,0);          //追加webGL的渲染器,他是用来调用浏览器的GPU,去进行实时渲染(前提浏览器已经支持GPU)         //antialias:是否开启锯齿,alpha:是否开启透明,logarithmicDepthBuffer:是否开启对数深度缓存         this.renderer=new THREE.WebGLRenderer({antialias:true,alpha:true,logarithmicDepthBuffer:true})         // 设置渲染器的像素比         this.renderer.setPixelRatio(window.devicePixelRatio);         //渲染器的输出颜色         this.renderer.outputEncoding=THREE.sRGBEncoding;         //设置渲染器的大小         this.renderer.setSize(this.width,this.height);         //将渲染器的dom元素,添加至我们div的dom元素中         this.dom.append(this.renderer.domElement);          // 监听浏览器大小,去更新相机的矩阵         window.addEventListener('resize',()=>{             // 更新相机的宽高比             this.camera.aspect=this.dom.offsetWidth/this.dom.offsetHeight;             this.camera.updateProjectionMatrix();             //更新渲染器的大小             this.renderer.setSize(this.dom.offsetWidth,this.dom.offsetHeight);             if(this.cssRenderer){                 this.cssRenderer.setSize(this.dom.offsetWidth,this.dom.offsetHeight);             }         })     } 
  1. 创建辅助对象方法
    /**     * @name      * @author shaoqunchao     * @date 2024/3/5 10:21     * @description 初始化X,Y,Z轴的扶助对象     * @update 2024/3/5 10:21     **/     initHelper(helperSize=1000){         this.scene.add(new THREE.AxesHelper(helperSize));     } 
  1. 重写render方法,调用requestAnimationFrame去更新相机和场景。
   render(callback){         callback();         requestAnimationFrame(()=>this.render(callback));     } 
  1. 在项目中任意的vue下去引用该组件。
<template>       <div style="width: 100%;height: 100%" id="threejs"></div>  </template>  <script> import ThreeJs from "@/js/ThreeJs";     let app,scene,camera,renderer;  export default {   name: 'App',   components: {    },     methods:{       async init(){           app=new ThreeJs("threejs");           app.initThree();           app.initHelper();           renderer=app.renderer;           scene=app.scene;           camera=app.camera;           app.render(()=>{               renderer.render(scene,camera)           })       }     },     mounted() {       this.init();     } } </script>  <style>     html, body {         width: 100%;         height: 100%;         margin: 0;         padding: 0;         overflow: hidden; /* 防止出现滚动条 */     } </style>  
  1. 去运行项目,查看当前效果,可以看到现在是一个空白的页面,什么也没有。
    在这里插入图片描述
  2. 是因为我们将相机的位置放在了0,0,0的位置,所以目前是什么也展示不了的,需要调整相机的位置。
    在这里插入图片描述
  3. 再次运行项目,可以看到我们的X,Y,Z轴的辅助对象。
    在这里插入图片描述
  4. 此时用鼠标旋转,放大缩小,都是不管用的,是因为我们没有初始化控制器,现在我们进行初始化控制器。
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' import {CSS3DRenderer} from "three/examples/jsm/renderers/CSS3DRenderer"      /**      * @name 初始化控制器      * @author shaoqunchao      * @date 2024/1/18 13:05      * @description 轨道控制器,可以使得相机围绕目标进行轨道运动      * @param enableZoom 设置控制器是否可以缩放,默认为true。      * @param autoRotate 设置是否自动旋转,默认为false。      * @param enableDamping 设置控制器阻尼,让控制器更有真实效果,默认为false。      * @param dampingFactor 设置控制器阻尼系数,让控制器更有真实效果,默认为0。      * @param minDistance 设置控制器最小距离,默认为1。      * @param maxDistance 设置控制器最大距离,默认为300。      * @param minAzimuthAngle 设置控制器最小旋转角度,默认为0。      * @update 2024/1/18 13:05      **/     initController(enableZoom=true,autoRotate=false,enableDamping=false,dampingFactor=0,minDistance=1,maxDistance=1000,minAzimuthAngle=0){         let width=this.dom.offsetWidth;         let height=this.dom.offsetHeight;         //这个Renderer是用来运行3维指标,相当于一个html页面去嵌入至模型中。         this.labelRenderer=new CSS3DRenderer();         this.labelRenderer.setSize(width,height);         //用来调整html页面的样式,让他围绕模型点位时,不会有偏移。         this.labelRenderer.domElement.style.position='absolute';         this.labelRenderer.domElement.style.top=0;         this.labelRenderer.domElement.style.pointerEvents="none";         this.dom.appendChild(this.labelRenderer.domElement);           this.controller=new OrbitControls(this.camera,this.renderer.domElement);         //设置控制器是否可以缩放         this.controller.enableZoom=enableZoom;         //设置是否可以旋转         this.controller.autoRotate=autoRotate;         //设置控制器阻尼效果,让控制器有真实的效果,         this.controller.enableDamping=enableDamping;         //设置阻尼控制器的系数         this.controller.dampingFactor=dampingFactor;         //设置控制器放大的最小距离         this.controller.minDistance=minDistance;         //设置控制器缩小的最大距离         this.controller.maxDistance=maxDistance;         //设置控制器最小旋转角度         this.controller.minAzimuthAngle=minAzimuthAngle;     } 
  1. 页面进行引用,然后在浏览器中进行测试。
    在这里插入图片描述

  1. 你觉得那个文件夹合适,那它就合适,大犟种,还真点开看啊 ↩︎

  2. 多余的解释 点我↩︎

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!