目录
- 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也可以,不强求,但我想用!!!
- 在合适的文件夹目录 下去打开cmd(windows小黑窗口)窗口或者Terminal(Mac终端),这俩不知道的话,就别往下看了。在弹出的窗口中输入以下命令,回车即可。
vue create demo
复制
注: 啥啥啥?vue不是内部或外部命令?点我点我
- 选择VUE2,本讲解以VUE2来进行 ,所以选择VUE2。 上下键去选,选完以后回车。

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

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

- 在开发工具的Terminal中输入以下内容回车。
npm install three
复制

实际操作环节
文件目录创建
- 在src下创建js文件目录



- 并创建ThreeJs.js文件



初始化场景、相机
-
Three他是一个右手系的X、Y、Z,如下图所示:

-
引入Three文件,创建ThreeJs的通用组件方法,使用构造器构建组件。
| import * as THREE from 'three'; |
| export default class ThreeJs{ |
| |
| constructor(id){ |
| |
| this.id=id; |
| this.dom=document.getElementById(id); |
| } |
| |
| } |
复制
- 创建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); |
| } |
复制
注 :相机的相关解释,这个必须要详细的介绍一下,这个很关键。也可以点击链接看官方文档 官方
序号 | 相机 | 含义 |
---|
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(视差屏障)。 |
- 修改相机观看位置点位,默认让他看原点
复制
- 追加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); |
| |
| |
| |
| 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); |
| |
| 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); |
| } |
| }) |
| } |
复制
- 创建辅助对象方法
| |
| |
| |
| |
| |
| |
| |
| 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> |
| |
| </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轴的辅助对象。

- 此时用鼠标旋转,放大缩小,都是不管用的,是因为我们没有初始化控制器,现在我们进行初始化控制器。
| import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' |
| import {CSS3DRenderer} from "three/examples/jsm/renderers/CSS3DRenderer" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| this.labelRenderer=new CSS3DRenderer(); |
| this.labelRenderer.setSize(width,height); |
| |
| 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; |
| } |
复制
- 页面进行引用,然后在浏览器中进行测试。
