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

邵群超 2024-08-04 17:35:01 阅读 79

目录

Three.js简介创建vue项目引入Three.js实际操作环节文件目录创建初始化场景、相机

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 下去打开cmd(windows小黑窗口)窗口或者Terminal(Mac终端),这俩不知道的话,就别往下看了。在弹出的窗口中输入以下命令,回车即可。

<code>vue create demo

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

选择VUE2,本讲解以VUE2来进行 2 ,所以选择VUE2。 上下键去选,选完以后回车。

在这里插入图片描述

展示以下结果代表创建成果,没报错就是创建成功了。

在这里插入图片描述

引入Three.js

使用WebStorm(你想用什么工具都可以,不强求)打开刚才创建的项目。

在这里插入图片描述

在开发工具的Terminal中输入以下内容回车。

<code> npm install three

在这里插入图片描述

实际操作环节

文件目录创建

在src下创建js文件目录

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

并创建ThreeJs.js文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

初始化场景、相机

Three他是一个右手系的X、Y、Z,如下图所示:

在这里插入图片描述

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

<code>import * as THREE from 'three';

export default class ThreeJs{

constructor(id){

//根据传入的id,去获取他的dom节点,用来加载三维模型

this.id=id;

this.dom=document.getElementById(id);

}

}

创建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);

}

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

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

修改相机观看位置点位,默认让他看原点

<code>this.camera.looAt(0,0,0)

追加webGL的渲染器,他是用来调用浏览器的GPU,去进行实时渲染(前提浏览器已经支持GPU)

this.renderer=new THREE.WebGLRenderer({ antialias:true,alpha:true,logarithmicDepthBuffer:true})

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

设置渲染器的像素比,设置渲染器的输出颜色,设置渲染器的大小。

// 设置渲染器的像素比

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);

}

})

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);

}

})

}

创建辅助对象方法

/**

* @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));

}

重写render方法,调用requestAnimationFrame去更新相机和场景。

render(callback){

callback();

requestAnimationFrame(()=>this.render(callback));

}

在项目中任意的vue下去引用该组件。

<template>

<div style="width: 100%;height: 100%" id="threejs"></div>code>

</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>

去运行项目,查看当前效果,可以看到现在是一个空白的页面,什么也没有。

在这里插入图片描述

是因为我们将相机的位置放在了0,0,0的位置,所以目前是什么也展示不了的,需要调整相机的位置。

在这里插入图片描述

再次运行项目,可以看到我们的X,Y,Z轴的辅助对象。

在这里插入图片描述

此时用鼠标旋转,放大缩小,都是不管用的,是因为我们没有初始化控制器,现在我们进行初始化控制器。

<code>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';code>

this.labelRenderer.domElement.style.top=0;

this.labelRenderer.domElement.style.pointerEvents="none";code>

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;

}

页面进行引用,然后在浏览器中进行测试。

在这里插入图片描述


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

多余的解释 点我 ↩︎



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。