02-项目引入threejs

three学习

  • 一、创建项目
    • 1、如果已经建好项目了,可以略过创建这一步
    • 2、初始化项目
      • ①新建一个vue2项目
      • ②打开项目的命令窗口,可直接在项目目录的路径栏输入cmd,然后回车
      • ③使用npm安装three,在命令窗口中输入npm install three --force,其中--force是强制安装,避免node版本过高或者过低无法安装的问题
      • ④安装完成以后如何确定自己的项目中是否安装成功呢,打开项目的package.json文件,看到dependencies对象下是否有three,能看到就说明安装成功了,可以直接使用
  • 二、项目引入
    • 1、我这里是使用了一个组件ThreeJs,在APP中引用了这个组件,在组件中首先定义一个盒子,用来挂载3D盒子
    • 2、避免页面代码太多,我们将编写3D的代码与组件分离开,这里我是专门建立了一个JS文件夹,用来编写代码
        • 1、首先我们需要一个dom用来挂载我们的three,
        • 2、然后再我们的组件ThreeJS中,将类引入,然后传入dom节点挂载
  • 三、创建渲染器
    • 1、在Base.js文件中,引入渲染器的工作类
    • 2、创建渲染器
    • 3、将渲染器挂载到dom
    • 4、设置渲染器大小
  • 四、创建场景 Scene
    • 1、在Base.js文件中,引入场景工具类
    • 2、创建场景
  • 五、创建相机
    • 1、引入相机工具类
    • 2、实例化一个相机
    • 3、设置相机的位置--从哪里拍
    • 4、设置相机拍摄的位置--拍具体哪里
    • 5、设置相机角度--歪着拍还是竖着拍
    • 6、渲染器渲染场景和相机
  • 六、添加模型 Mesh
    • 1、引入所需要的类
    • 2、创建一个模型数组
    • 3、创建立方体模型
    • 4、Base.js 文件中创建一个方法,用来向场景中添加模型。
  • 七、添加模型到场景中
    • 1、引入
    • 2、调用
  • 八、光线添加
    • 1、引入
    • 2、创建光线数组
    • 3、添加环境光(自然光)
  • 九、添加光线到场景中
    • 1、引入
    • 2、添加光线
  • 十、逐帧渲染页面
  • 十一、轨道控制器
    • 1、引入
    • 2、实例化
  • 十二、点光源
    • 1、引入点光源
    • 2、创建点光源
  • 十三、效果

一、创建项目

1、如果已经建好项目了,可以略过创建这一步

2、初始化项目

①新建一个vue2项目

vue create my-project  // my-project是项目名称

②打开项目的命令窗口,可直接在项目目录的路径栏输入cmd,然后回车

02-项目引入threejs_第1张图片

③使用npm安装three,在命令窗口中输入npm install three --force,其中–force是强制安装,避免node版本过高或者过低无法安装的问题

npm install three --force

④安装完成以后如何确定自己的项目中是否安装成功呢,打开项目的package.json文件,看到dependencies对象下是否有three,能看到就说明安装成功了,可以直接使用

02-项目引入threejs_第2张图片

二、项目引入

1、我这里是使用了一个组件ThreeJs,在APP中引用了这个组件,在组件中首先定义一个盒子,用来挂载3D盒子

我是先给盒子一个固定的宽高和边框,看的时候比较方便,

<template>
  <div ref="container" id="container"></div>
</template>

<script>
export default {
  name: 'ThreeJs',
  data() {
    return {};
  },
};
</script>

<style scoped>
#container {
  width: 400px;
  height: 400px;
  border: 1px solid red;
}
</style>

效果如下:什么都没有,只有一个空白的边框盒子
02-项目引入threejs_第3张图片

2、避免页面代码太多,我们将编写3D的代码与组件分离开,这里我是专门建立了一个JS文件夹,用来编写代码

02-项目引入threejs_第4张图片

1、首先我们需要一个dom用来挂载我们的three,

在Base.js中创建一个类,并且在构造器中获取传入的dom,然后挂载到Vue上,这段代码写在Base.js中

export class ThreeBox {
  dom = null; // 挂载的 DOM
  // 构造器函数
  constructor(dom) {
    // 挂载
    this.dom = dom
  }
}
2、然后再我们的组件ThreeJS中,将类引入,然后传入dom节点挂载
<script>
import { ThreeBox } from './js/Base';
export default {
  name: 'ThreeJs',
  data() {
    return {
      ThreeBox: null,
    };
  },
  mounted() {
    this.ThreeBox = new ThreeBox(this.$refs.container);
  },
};
</script>```

三、创建渲染器

1、在Base.js文件中,引入渲染器的工作类

import { WebGLRenderer } from 'three'

2、创建渲染器

在构造函数里面创建

import { WebGLRenderer } from 'three'

3、将渲染器挂载到dom

 dom.appendChild(renderer.domElement) 

4、设置渲染器大小

设置的和 dom 节点一样大小一样就可以

   renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)

四、创建场景 Scene

1、在Base.js文件中,引入场景工具类

因为之前已经引入了渲染器的工具类,直接在后面加场景工具类就可以

import { WebGLRenderer,Scene  } from 'three'

2、创建场景

let scene = new Scene()  // 实例化场景
this.scene = scene

到目前为止,Base.js里面的全部代码如下:

import { WebGLRenderer,Scene  } from 'three'
export class ThreeBox {
  dom = null; // 挂载的 DOM
  // 构造器函数
  constructor(dom) {
    // 挂载
    // 创建渲染器
    let renderer = new WebGLRenderer({
      antialias: true,  // 开启抗锯齿
    })
    renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)
    dom.appendChild(renderer.domElement)  // 将渲染器挂载到dom
    let scene = new Scene()  // 实例化场景
this.scene = scene
    this.dom = dom
  }
}

五、创建相机

1、引入相机工具类

import { WebGLRenderer,Scene,PerspectiveCamera,Vector3   } from 'three'

2、实例化一个相机

let camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)

简单介绍一些四个参数是什么意思

 1、视野角度(FOV-视野角度是无论在什么时候,在显示器上所能看到的场景    的范围,单位是角度(与弧度区分开)
  2、长宽比(aspect ratio)-用一个物体的宽除以它的高所得来的值
  3、近截面(near)-当物体某些部分比摄像机的远截面远或者比近截面近的时候,该这些部分将不会被渲染到场景中
  4、远截面(far)-当物体某些部分比摄像机的远截面远或者比近截面近的时候,该这些部分将不会被渲染到场景中

3、设置相机的位置–从哪里拍

camera.position.set(50, 50, 50) // 设置相机位置

4、设置相机拍摄的位置–拍具体哪里

camera.lookAt(new Vector3(0, 0, 0))  // 设置相机看先中心点

5、设置相机角度–歪着拍还是竖着拍

camera.up = new Vector3(0, 1, 0)  // 设置相机自身的方向

补充个小知识:

three.js里面的坐标系方向是向右-x轴正方向,垂直屏幕-Z轴正方向,垂直水平面-Y轴正方向
02-项目引入threejs_第5张图片

6、渲染器渲染场景和相机

renderer.render(scene, camera)  // 渲染器渲染场景和相机

到此刻,场景是黑色的,因为场景没有东西

六、添加模型 Mesh

避免Base.js文件中代码可读性强,所以我们新建一个js文件,用来存放基础模型,我这里创建的是Modal.js
02-项目引入threejs_第6张图片

1、引入所需要的类

BoxGeometry:几何体,
Mesh:网格
MeshStandardMaterial :材质

import { BoxGeometry, Mesh, MeshStandardMaterial } from "three"

2、创建一个模型数组

创建模型数组的目的是,后期使用的时候,可以获取到全部的模型,比如立方体球体等,后期添加的模型添加到这个数组中去的时候,组件中可以一次性获取到所有的模型

export const allModal = []  //抛出所有基础模型

3、创建立方体模型

可以使用抛出的方式,也可以添加到模型数组中去,单独抛出的话组件可以单独使用这一个立方体模型

// 创建立方体
export const box = new Mesh(
  new BoxGeometry(20, 20, 20),  // 设置立方体的大小 (x 长度, y 高度 ,z 长度)
  new MeshStandardMaterial({   // 设置材质
    color: 'rgb(36, 172, 242)',  // 设置材质的颜色
  })
)

allModal.push(box)  // 添加到模型数组

4、Base.js 文件中创建一个方法,用来向场景中添加模型。

注意:写在构造函数外面

/**
   * 向场景中添加模型
   * @param  {...any} moadl 模型列表
   */
  addModal(...moadl) {
    moadl.forEach(elem => {
      this.scene.add(elem)  // 场景添加模型
    })
  }

七、添加模型到场景中

在组件ThreeJs中,引入和调用

1、引入

import { allModal } from './js/Modal';

2、调用

  this.ThreeBox.addModal(...allModal);

八、光线添加

因为光线也有多种,方便Base.js代码的可读性,将添加光线的代码单独使用一个JS编写,我这里新建了一个Light.js文件来编写

1、引入

import { AmbientLight } from "three"

2、创建光线数组

这里和模型数组一样,光线有多种,其他组件引用的时候可以引用全部光线

export const allLights = []

3、添加环境光(自然光)

设置自然光的颜色,强度等

export const ambientLight = new AmbientLight('rgb(255,255,255)', 0.8)
// 同时添加到光线数组中去
allLights.push(ambientLight)
// 两个参数第一个为光线的颜色,第二个为光线的强度

九、添加光线到场景中

在ThreeJs组件中,引入并添加光线

1、引入

import {allLights} from './js/Light'

2、添加光线

    this.ThreeBox.addModal(...allLights);

十、逐帧渲染页面

threejs 的渲染器,初始化渲染器完成之后就只渲染了一次就不管了,所以后边我们再修改场景修改模型的时候,并没有给我们渲染,需要添加一段渲染代码,threejs 就会一直帮我们逐帧渲染页面效果,这段代码加在构造器的最后面

  let animate = () => {
      renderer.render(scene, camera)  // 渲染器渲染场景和相机
      requestAnimationFrame(animate);
    }
    animate()

这里发一下构造器,避免写露或者写错地方

 constructor(dom) {
    // 挂载
    // 创建渲染器
    let renderer = new WebGLRenderer({
      antialias: true,  // 开启抗锯齿
    })
    renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)
    dom.appendChild(renderer.domElement)  // 将渲染器挂载到dom
    let scene = new Scene()  // 实例化场景

    // 实例化相机
let camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)
camera.position.set(50, 50, 50) // 设置相机位置
camera.lookAt(new Vector3(0, 0, 0))  // 设置相机看先中心点
camera.up = new Vector3(0, 1, 0)  // 设置相机自身的方向
renderer.render(scene, camera)  // 渲染器渲染场景和相机
this.scene = scene
    this.dom = dom

    let animate = () => {
      renderer.render(scene, camera)  // 渲染器渲染场景和相机
      requestAnimationFrame(animate);
    }
    animate()
  }

写到这里效果可以就可以看到了,能看到背景为黑色,因为没有设置,默认就是黑色的,
02-项目引入threejs_第7张图片
我们可以给他设置其他的颜色

renderer.setClearColor('rgb(253, 218, 1)') 

02-项目引入threejs_第8张图片

十一、轨道控制器

这个时候可以看到页面是静止的,鼠标无法进行操作,如果想要鼠标可以进行操作,我们需要添加一个工具类(OrbitControls,它叫做轨道控制器),

1、引入

在base.js中引入和实例化

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

2、实例化

轨道控制器鼠标按键功能,是可以设置的,需要先添加鼠标工具类

import { WebGLRenderer,Scene,PerspectiveCamera,Vector3,MOUSE   } from 'three'

一般情况下,鼠标左键是有其他功能的,所以一般不添加功能,这里为了操作方便,所以给鼠标左键也添加了旋转的功能

let orbitControls = new OrbitControls(camera, renderer.domElement)
    orbitControls.mouseButtons = {  // 设置鼠标功能键(轨道控制器)
      LEFT: MOUSE.ROTATE,  // 左键旋转
      MIDDLE: MOUSE.DOLLY,  // 中键缩放
      RIGHT: MOUSE.ROTATE   // 右键旋转
    }

十二、点光源

写到这里,我们会发现一个问题,就是这个立方体的每一面的光都是一样,因为我们使用了环境光,环境光的特点就是它在模型的每一个面上光照强度都是一样的,不会衰减,所以说我们看到的模型,他每个面放光是一样的,根本看不出立体感,所以我们需要添加点光源,从一个点射出一束光向四周扩散,光强度不一样的话,立体感就能看的很清楚了。

1、引入点光源

在Light.js文件中引入并创建点光源

import { AmbientLight,PointLight  } from "three"

2、创建点光源

export const pointLight = new PointLight(
  'rgb(255,255,255)',
  0.5,
  600,
  0.2
)
pointLight.position.set(0, 100, 200)  // 设置点光源位置 (x,y,z)
// 添加到光源数组中
allLights.push(ambientLight,pointLight)
四个参数分别是:
 1、color(可选参数)-十六进制光照颜色,默认白色
 2、intensity(可选参数)-光照强度
 3、distance-表示光源到光照强度为0的位置,当设置为0时,光照永远不会消失
 4、decay-沿着光照距离的衰退量

十三、效果

写到这里,立方体的效果也出来了,鼠标也能操作了,我这个背景色比较深,看的可能不是很清楚,你们使用的时候可以适当调节立方体的颜色和背景的颜色,看的就比较明显了
02-项目引入threejs_第9张图片

你可能感兴趣的:(Thressjs开发,vue.js,前端,javascript,开发语言)