首页 > 其他分享 ># 一篇文章了解 threejs 在 vue 项目中的基本使用(未完结)

# 一篇文章了解 threejs 在 vue 项目中的基本使用(未完结)

时间:2022-10-25 17:23:23浏览次数:73  
标签:threejs vue 渲染器 未完结 dom 设置 new 我们

一篇文章了解 threejs 在 vue 项目中的基本使用

Three.js 是一个跨浏览器的脚本,使用 JavaScript 函数库或 API 来在网页浏览器中创建和展示动画的三维计算机图形。为啥突然想写这么一篇文章的主要原因其实是前几天有个人需要我帮忙写一个简单的 demo,花了几个小时之后觉得基本上 threejs 基本的使用效果都实现了,之前就看过 threejs 的东西,但是一直没有时间静下心来整理汇总一下,所以说呢,今天时间比较充足,就稍微的记录一下。当然了,我也没有深入的学习使用,学习的时间很短,所以说也谈不上经验的分享,就算是一个简单的学习记录吧,浅看则以,切勿尽信。

threejs 相关资料

其实相对来说 threejs 的学习成本比较高的,需要掌握的知识相对来说会稍微杂一些,但是简单的入门倒是很简单,现在网上的资料还是很多的,无论是博客还是视频都是比较充足的,然后接下来的博文内容,就简单的介绍一些在 vue2 项目中 threejs 的基本使用。

threejs 介绍

threejs 是运行在浏览器中的 3D 引擎,是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。开发者可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。可以在它的主页上看到许多精彩的演示。不过,这款引擎还处在比较不成熟的开发阶段,其不够丰富的 API 以及匮乏的文档增加了初学者的学习难度(尤其是文档的匮乏)。

前言

在讲解 threejs 的时候,我们通过一个基本的简单的案例,来实现一个小的效果,然后把常用的 API、工具、功能稍微说一下哈!

这个案例我是使用 vue2 + 脚手架工具创建的项目,采用 javascript 开发。再次之前需要先准备一个 vue 的空项目,好在我们不需要使用网络请求,直接默认创建一个 vue2 的项目即可,不需要过多的配置。

安装 threejs

安装 threejs 的方式也很简单,直接使用 npm 工具就可以安装到项目里面使用:

npm install --save three

在终端输入命令然后回车等待执行完成就可以了!

在这里插入图片描述

安装完成之后,就可以看到 package.json 文件中已经包含了我们刚刚安装的 three 依赖。

在这里插入图片描述
同时,在 node_modules 文件夹下,也出现了 three 相关的包依赖。

在这里插入图片描述

这样,我们就成功将 threejs 相关的依赖添加到我们的项目,就可以继续进行后续 threejs 相关功能的开发了。

初始化项目

这个步骤就不多说了,直接使用 cli3 以上的版本创建一个 vue2 的项目,然年修改一下组件内容,创建一个 div 标签铺满整个浏览器页面就可以了。

<template>
  <div class="three-canvas" ref="threeTarget"></div>
</template>

<script>
export default {
  name: 'HelloWorld',
}
</script>

<style scoped>
  .three-canvas {
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #d6eaff;
  }
</style>

大体效果就是下面的样子,当然了这个无所谓了。

在这里插入图片描述

然后我们在这个组件中实现 threejs 效果,效果呢,挂载到我们创建的 <div class="three-canvas" ref="threeTarget"></div> 标签上面渲染。

为了保证项目代码稍微的有点规范性,我们创建一个 TEngine.js 文件,在当前组件引入,然后呢,所有与 threejs 初始化、操作等代码都是 TEngine.js 文件中实现。

在这里插入图片描述

创建渲染器 WebGLRenderer

接下来我们在 TEngine.js 文件中初始化一个 threejs ,首先第一步,我们需要有一个 dom 挂载我们创建的 threejs ,啥叫挂载呢,简单点说就是我创建的 3D 模型显示在哪里,我们之前初始化项目不是创建一个全屏的 div 吗?然后我们就把 3D 模型放在这个 div 上面显示。

第一步,我们现在 TEngine.js 中创建并交出一个 ThreeEngine 类,然后这个类,在组件中实例化就可以了,前面说了,需要一个 dom 节点挂载模型,那么我们首先得接收一个 dom 节点吧?所以说在构造器函数里面获取到传入的 dom 节点,然后挂载。

export class ThreeEngine {
  dom = null; // 挂载的 DOM
  // 构造器函数
  constructor(dom) {
    this.dom = dom
  }
}

然后我们就可以在组件中实例化这个类了。注意,需要在 mounted 生命周期钩子中实例化吧?不能在 created 生命周期钩子中,为啥,因为 mounted 才是 dom 都渲染完成吧,好:

<script>
  import { ThreeEngine } from './js/TEngine'
  export default {
    name: 'HelloWorld',
    data() {
      return {
        ThreeEngine: null,
      };
    },
    mounted() {
      this.ThreeEngine = new ThreeEngine(this.$refs.threeTarget)
    }
  }
</script>

OK,这样子第一步就完成了,但是呢页面没效果,因为我们刚刚开始,完全没有任何的 threejs 的操作。

接下来,就是 threejs 相关的操作了哈,都在 ThreeEngine 类的构造器函数中实现。

【引导】首先你想,我们想在一个 div 上面展示 3D 模型的东西,是不是首先得有一个东西把这个 3D 模型转换成我们浏览器可以展示的画面放在我们传递进来 div 上展示啊,这个帮助我们把 模型 展示到 div 上的东西就可以简单的理解成渲染器。举一个例子:老师说我们准备换一个新教室,老师想看一下新教室的布局,但是自己有事过不去,怎么办?找个同学小明帮忙过去看一下就可以了吧,怎么让老师亲眼看到?对,视频通话,小明拿手机拍摄,然后老师在手机上就可以看到这个新教室的布局了吧,那这个小明就是渲染器。所以第一步,找一个小明。

老师的渲染器是小明,而 threejs 的渲染器就是 WebGLRenderer。WebGLRenderer是 three 中提供的一个工具类,我们在使用之前需要先引入他,使用也很简单。

import { WebGLRenderer } from 'three'

首先创建一个渲染器:

let renderer = new WebGLRenderer()  // 创建渲染器

创建完成之后,我们需要把这个渲染器挂载到 dom 上面,这样,渲染器渲染的效果就可以展示在 div 上面,就是学生和老师打视频电话,才可以让老师在自己的手机看到新教室布局。

dom.appendChild(renderer.domElement)  // 将渲染器挂载到dom

问题来了,我们告诉渲染器说:你把 threejs 的效果展示在 div 上面。可以渲染器有点蒙蔽还,就是我要渲染多大啊?这个 div 有高宽,我是渲染在这个 div 的那个部分呢?所以说还需要设置一下渲染器的大小吧?我们一般设置的和 dom 节点一样大小就可以。

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

这样我们的渲染器初始化的全部代码就完成了!

import { WebGLRenderer } from 'three'

export class ThreeEngine {

  dom = null; // 挂载的 DOM
  
  constructor(dom) {

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

    this.dom = dom
  }

}

我们看一下页面效果。

在这里插入图片描述

非常好,和没有初始化之前一模一样,为啥。

【引导】还是老师想看新教室,渲染器小明有了,但是小明拿手机拍啥啊?新教室对吧?但是我们只是找到了小明,交代给小明说你去渲染给我看,但是并没有告诉小明去看啥,这里让小明看的东西叫做场景,我们需要告诉小明看什么场景才可以。所以说下一步,找一个场景。

创建场景 Scene

threejs 中的场景是 Scene,同样这个也是 threejs 提供的工具类,使用的话也需要引入,创建一样简单。

import { WebGLRenderer, Scene } from 'three'

创建场景直接 new 就可以。

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

就这两行代码初始完场景了,然后到此为止,所有的代码就是下面这样的。

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

我们看一下效果:

在这里插入图片描述

我勒个去!还是怎么东西没有,我之前一模一样。这又是为啥!

【引导】还是老师让小明看新教室,渲染器小明有了,场景也有了。但是小明拿着手机懵了,为啥懵了,小明到了新教室,他不知道怎么给老师看新教室,我们想法是啥,小明拿手机打视频给老师看,但是小明不知道啊!我们得给小明一个有摄像机的手机才可以。继续,小明有相机了,但是小明比较笨,他不知道从那个角度拍给老师看(尽管小明笨,但不许换掉小明),所以说我们还得告诉小明拍摄的位置,也就是说从哪个角度拍摄吧。

创建相机并设置位置 PerspectiveCamera

threejs 中的相机是 PerspectiveCamera,他同样是 three 提供的工具类,我们需要引入,然后在实例化。

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

怎么创建相机有几个步骤,首先实例化一个相机;然后需要设置相机的位置,就是从哪里拍;再然后设置相机拍摄的位置,就是拍具体哪里;最后可以设置相机角度,就是歪着拍还是竖着拍;

首先是初始化相机

// 实例化相机
let camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)  

这里传了几个参数,分别是啥意思稍微说一下。

  • 第一个参数 45 是 摄像机视锥体垂直视野角度,人眼看东西就差不多60度左右嘛,不可能看到头后面的东西,这里也是这个意思,一般就设置 45。
  • 第二个参数 dom.offsetWidth / dom.offsetHeight 是摄像机视锥体长宽比,我们就设置是我们 div 容器的长宽比就可以,如果不这样设置,可能会变形。因为我们看到的要和相机看到的一样大小,不然会被拉伸。
  • 第三个参数 1 是摄像机视锥体近端面
  • 第四个参数 1000 摄像机视锥体远端面

然后是设置相机位置,就是相机都放在哪里。

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

我们把相机放在 three 坐标 50 50 50 的位置。

然后是设置相机看向哪里,这里我们让相机看向原点。

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

我们还可以设置相机自身的方向。

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

这里我们稍微补充一点知识点,因为没有图形学基础的话可能不好理解,首先说一点,threejs 坐标系是向右为 x 轴正方向,垂直屏幕向外为 z 轴的正方向,向上为 y 轴正方向。

在这里插入图片描述
所以说设置相机的位置和看向原点就理解了哈,然后渲染器默认加载完成后他的中心就是(0,0,0)原点,分别对应 (x,y,z)。
camera.up 是用来设置相机自身的方向设置 y = 1 表示 y 轴的正方向为相机向上的方向,可能没说明白,就是相机向上移动就是向 three 坐标系 y 轴的正方向移动。

到这里,我们初始化相机的部分就完成了,然后我们到此位置所有代码:

import { WebGLRenderer, Scene, PerspectiveCamera, Vector3 } from 'three'
export class ThreeEngine {
  dom = null; // 挂载的 DOM
  scene = null; // 场景
  constructor(dom) {
    // 创建渲染器
    let renderer = new WebGLRenderer({
      antialias: true,  // 开启抗锯齿
    })
    dom.appendChild(renderer.domElement)  // 将渲染器挂载到dom
    renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)
    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)  // 设置相机自身方向
    this.dom = dom
    this.scene = scene
  }
}

然后我们保存代码,看一下页面效果。

在这里插入图片描述

非常好,还是那个样子,啥都没有。

为啥呢?再来引导一波!

【引导】我们初始化了渲染器,找到小明了;初始化了场景,让小明去了新教室;相机准备好了,小明掏出手机对准了目标。但是没有视频啊!老师啥也看不到。所以我们接下来需要把这个相机和场景绑定到渲染器里面。

绑定很简单,只需要在初始化相机之后呢,把场景和相机绑进渲染器,让渲染器渲染就可以了:

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

OK,现在在看一下效果。

在这里插入图片描述
全部变黑了是吧?这就是成功了,为啥是黑的呢,因为现在这个场景没有东西,如果有东西的话就可以展示出来了吧。

添加模型 Mesh

现在我们创建一个立方体放进场景里面去,我们就可以看到一个模型了吧?好的,现在开始!

为了保证我们项目代码的结构,我们创建一个 TBaseObject.js 文件,用来存放基础的模型,然后这个文件中我们创建一个立方体模型,并返回出来。

我们就简单点,先声明一个数组抛出,然后数组里面是创建的模型,这样外面使用这个文件的时候,导入就可以获取模型的列表了。

export const allBaseObject = []  // 返回所有基础模型

然后创建一个立方体模型,当然也可以抛出去,也可以往数组里面添加一下,这样的话我们既可以单独使用这个立方体,也可以获取全部模型。

创建一个简单的立方体很简单,Mesh 是 three 提供的基于以三角形为polygon mesh(多边形网格)的物体的类,我们可以通过他创建一个立方体。

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

allBaseObject.push(stage)  // 添加到模型数组

小地方说一下哈,设置模型大小肯定需要的,这个模型多宽、多高、多长。那材质是啥意思,就是我们这个立方体的样式,比如颜色,光泽等属性,当然如果是实际模型可能还有贴图之类的。简单理解就是什么样子的。

当然,中间使用的类也需要引入一下。

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

好,创建完成做一个事情,就是我们需要在 three 中把这个立方体添加进三维场景中,我们在 TEngine.js 文件中创建一个方法,用来向场景中添加模型。

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

然后我们在组件中把获取模型列表,然后呢,把模型添加到场景中。

import { allBaseObject } from './js/TBaseObject'

再 threejs 初始化完成后,调用我们写的方法,把模型列表添加到场景。

this.ThreeEngine.addObject(...allBaseObject)  // 添加基础模型

代码我最后会全部提交到 gitee,到时候如果需要可以看一下。

这样我们在看一下效果:

在这里插入图片描述
哇偶,还是黑色的。为啥呢,在引导一波!

【引导】小明开视频了,但是老师眼前一黑,为啥?没开灯呗!其实 threejs 还是很真实的,他里面集成了光线的设置,如果没有光线,就和实际生活一样,完全就是漆黑的一篇,真棒!那么接下来,我们给场景添加一个“自然光”。

光线添加

嗯,现实生活中光线有很多了,比如说房间一盏灯,点亮之后就是一个点光源向四周发散光,在比如聚光,各大晚会的聚光灯照在一个人身上这种。threejs 中也存在这种光源,我们先编写一个最简单的光线,叫 “自然光”。

注意一点,我们创建的很多东西如果想展示出来都需要添加到场景才可以,比如我们创建的立方体、现在要创建的自然光,以及后边说的光线辅助啥的都需要添加进场景才可以看到,那么我们写这个光线的时候和立方体一样,创建一个 TLights.js 文件,把光源创建出来,然后引入到组件然后添加进场景进行展示。

创建光线其实很简单:

import { AmbientLight } from "three"


/**
 * 光线
 */
export const allLights = []

// 添加环境光(自然光),设置自然光的颜色,设置自然光的强度(0 最暗, 1 最强)
export const ambientLight = new AmbientLight('rgb(255,255,255)', 0.8)

allLights.push(ambientLight)

threejs 中的自然光是 AmbientLight ,使用之前需要引入,引入完成实例化的时候需要传递两个参数:

  • 第一个参数是光线的颜色。
  • 第二个参数是光线的强度。0最暗,1最亮。

然后我们同样也是在 组件 中引入光线,然后将光线添加到场景。

this.ThreeEngine.addObject(...allLights)  // 添加光线

这样,光线就被我们添加到场景了,我们再来看一下效果。

在这里插入图片描述
啊? 还是黑色的!这又是怎么回事啊!!!!!

【说明】我们知道,页面是有刷新率的,比如 60hz 表示屏幕一秒钟渲染60个页面,我们的眼睛有延时,页面切换的太快,所以说我们看到的就是一个视频效果,但是 threejs 的渲染器,在初始化渲染器完成之后就只渲染了一次就不管了,所以说后边我们再修改场景修改模型的时候,并没有给我们渲染,所以说我们需要自己写代码然他渲染,怎么写呢,官网其实说的也很明白,一段代码加上就 OK 了。

接下来,我们在 构造器函数 最后加上这段代码,threejs 就会一直帮我们逐帧渲染页面效果。

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

我们现在再来看效果:

在这里插入图片描述

终于,我们的立方体加载出来了。如果我们不设置正方体的位置,默认模型初始化加载在原点位置。

我们看到渲染器背景是黑色的,这是因为我们没有设置,他默认就是黑色的,我们可以给渲染器设置其他的颜色,在渲染器绑定完相机和场景之后:

renderer.setClearColor('rgb(239, 70, 1)')  // 设置渲染器的颜色

他就可以被设置成我们想设置的任意颜色。

在这里插入图片描述
好了,这就是最基本的使用。

轨道控制器 OrbitControls

上面我们说完了基本的初始化渲染器、相机、场景、添加模型、设置光线之后,我们发现一个问题啊,就是这个页面是静态的,我们之前看百度地图或者是其他 cesium 创建场景之后,鼠标可以拖动,放大缩小,但是现在我们编写的案例还不可以,接下来我们实现这个功能。

要想实现鼠标操控,需要使用 threejs 的另一个工具类,那就是 OrbitControls,它叫做轨道控制器。

怎么使用呢?首先需要引入进项目,主要,这个工具类不是 three 中提供的,而是在它提供的案例里面,我们需要单独引入。

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

引入完成,需要初始化轨道控制器。

let orbitControls = new OrbitControls(camera, renderer.domElement)

OK,初始化完成再去看效果,我们的案例就可以鼠标旋转缩放了。

在这里插入图片描述
这就是 轨道控制器 的基本使用。使用方式也很简单:

  • 鼠标左键按下拖拽:围绕视图中心点旋转。
  • 鼠标中键滚动:缩小放大,实际是相机靠近和远离。
  • 鼠标右键按下拖拽:移动场景。

【拓展】

再稍微拓展一个轨道控制器的地方,就是我们的轨道控制器鼠标按键功能,是可以设置的,因为我们后面可能介绍鼠标点击事件,所以说鼠标左键按下事件可能有冲突,所以说我们重新设置一下,中键功能不变,旋转改为右键操作,左键什么功能都没有。

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

里面使用了 MOUSE,这是 three 提供的,我们得引入一下:

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

这样设置之后,我们鼠标按键的功能就发生了变化,可以试一下。

在这里插入图片描述
OK,发现鼠标功能确实实现了。但是有没有发现一个很大的问题啊?就是根本看不出立方体的感觉来,你说他是立方体,我还就说他是一个多边形不停的变换呢!

确实是这样哈!正经的立方体他是有轮廓显示的,类似于下面:

在这里插入图片描述

但是现在没有为啥。稍微解释一下,为了看见这个立方体,我们使用了环境光,环境光有一个特点,啥特点呢,就是说,他在模型的每一个面上光照强度都是一样的,不会衰减,所以说我们看到的模型,他每个面放光是一样的,根本看不出立体感。如果想要立体感怎么办?很简单哈,换一种光线,不使用环境光了,我们使用一个点光源,从一个点射出一束光向四周扩散,这样的话,照在模型上,因为距离不一样,光照强度就不一样,立体感就出来了。

添加点光源 PointLight

我们之前在 TLights.js 文件创建了一个环境光,现在我们再创建一个点光源 PointLight,添加到场景中去。因为之前封装好了,我们只需要创建完点光源,然后把点光源放进光源数组就可以了吧。

创建点光源使用的是 PointLight,这个工具类同样是 three 中提供的,我们需要引入一下子。

import { AmbientLight, PointLight } from "three"

然后就是创建点光源,创建点光源和创建环境光有点不一样,因为他就像一个灯泡,需要有颜色、强度、能照射多远、光照衰减值,最后还有位置:

// 点光源
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(pointLight)  // 将点光源添加到光源列表抛出

PointLight 有四个参数:

  • color - (可选参数)) 十六进制光照颜色。默认 0xffffff (白色)。
  • intensity - (可选参数) 光照强度。 缺省值 1。
  • distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失,默认0。
  • decay - 沿着光照距离的衰退量。默认 1。

OK,现在我们再来看一下添加完点光源之后,模型效果:

在这里插入图片描述
非常好,模型的立体感已经出来了。

模型部分拓展

我们既然说完了光线,其实还有很多中光线,可以去官网查看相关使用。

接下来我们稍微拓展一点儿东西哈,就是我们之前创建模型是使用的下面的代码:

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

我们可以向这个模型添加数据的,比如我们设置个 name,我这个立方体叫做 “box” 可以吧。只需要这样写就可以配置他的 name 属性。

export const box = new Mesh(
  new BoxGeometry(20, 20, 20),  // 设置立方体的大小
  new MeshStandardMaterial({   // 设置材质
    color: 'rgb(36, 172, 242)',  // 设置材质的颜色
  })
)
box.name = 'box'

除了 name 之外还可以设置他的位置。

box.position.set(5, 5, 5)  // 设置模型位置 (x,y,z)

当然,位置信息也可以单独设置。

box.position.x = 5
box.position.y = 5
box.position.z = 5

单独设置每个坐标轴的位置也是可以的。

在实际开发的时候,比如我们有一个模型,我们需要给这个模型绑定一些数据,点击弹窗显示或者是鼠标悬浮显示的时候获取到这些数据,怎么绑定数据呢?其实我们可以直接设置,比如:

box.sheshimoxingshuju = {
  name: 'box',
  user: '我是ed.'
}

当然,threejs 提供了一个参数 userData 用来存放用户数据,建议放到那里面,默认我们都放到 uerData 里面,这样是为了以后多人开发,不至于每个人创建一个属性最后乱套了都。

export const box = new Mesh(
  new BoxGeometry(20, 20, 20),  // 设置立方体的大小
  new MeshStandardMaterial({   // 设置材质
    color: 'rgb(36, 172, 242)',  // 设置材质的颜色
  })
)
box.name = 'box'  // 设置模型 name
box.position.set(5, 5, 5)  // 设置模型位置
box.position.x = 5
box.position.y = 5
box.position.z = 5


box.sheshimoxingshuju = {
  name: 'box',
  user: '我是ed.'
}

box.userData = {
  name: '我是ed.'
}

怎么确定我们都设置成功了?我们打印一下就可以了。

在这里插入图片描述

我们直接打印一下 box 就可以看到我们配置的都是生效了的,都存进去了的。为啥突然想说这个,主要是想说一下 name 设置的,因为后边可能要根据模型的 name 从场景中获取模型,所以说一下模型的 name 怎么设置。我们去掉测试多余的代码哈。

然后再说一下模型的材质问题

还是这段代码:

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

关于材质,我们只设置了一个颜色对吧!页面效果也显示出来了,然后是蓝色的很精致的小盒子,他除了颜色还可以设置其他的属性,比如:粗糙度 roughness

roughness 粗糙度是啥意思,就比如说我们生活里面,木头的粗糙度就很高,玻璃的粗糙度就很低。

roughness 上怎么提现粗糙度呢,roughness 的取值范围是 0 到 1。当 roughness 为 0 时,表示粗糙度最低,就越光滑;当 roughness 为 1 时,表示粗糙度最高,越粗糙。

比如我们给这个正方体设置一个粗糙度为 0 ,也就是最光滑。

export const box = new Mesh(
  new BoxGeometry(20, 20, 20),  // 设置立方体的大小
  new MeshStandardMaterial({   // 设置材质
    color: 'rgb(36, 172, 242)',  // 设置材质的颜色\
    roughness: 0   // 粗糙度(0 最光滑,1 最粗糙)
  })
)

我们怎么看效果,这也是为啥我在这里说粗糙度而不是在添加模型说的原因,我们在场景添加了一个点光源,可以理解成就是一个灯吧!如果一个物体,他表面光滑到一个程度之后他会反光的!我就把正方体的粗糙度调到最低,也就是最光滑的时候,他肯定会反光吧,那我们调节模型,看他有没有反光的时候。看效果:

在这里插入图片描述
找到反光的点了,是吧!但是如果我们粗糙度调到最高,是绝对不可能反光的,这里我们就不看了,有兴趣的可以自己看一下。

除了粗糙度,在说一个吧,就是 金属度 metalness

我们在生活中见过铁吧!见过不锈钢吧!见过铝合金吧!那种金属质感很酷吧?就算是相同的颜色,塑料和金属你一眼就分个大概吧!

metalness 就是用来设置模型金属质感的,他的取值也是从 0 到 1,当 metalness 为 0 表示金属质感最少,最不像金属;metalness 为 1 表示金属质感最强,最像金属。

我们在给模型添加一个金属质感。

export const box = new Mesh(
  new BoxGeometry(20, 20, 20),  // 设置立方体的大小
  new MeshStandardMaterial({   // 设置材质
    color: 'rgb(36, 172, 242)',  // 设置材质的颜色
    metalness: 0.5,   // 金属度 (1 最像金属,0 最不想金属)
    roughness: 0   // 粗糙度(0 最光滑,1 最粗糙)
  })
)

我这里金属质感设置的 0.5,为啥,现实生活中有没有一个感觉,就是一个金属块,表面越光滑,金属感越强,他的颜色就越暗,暗的发黑。

在这里插入图片描述

看,我设置完金属度之后,模型不如之前亮了,但是没有看出金属质感啊?别急,我移动一下,照样让他返回看一下,金属质感立马就出来了。

在这里插入图片描述
怎么样!厉害吧!啊哈哈哈哈!

好了,关于这个小的拓展部分就到这里吧!完成!

标签:threejs,vue,渲染器,未完结,dom,设置,new,我们
From: https://www.cnblogs.com/wjw1014/p/16825565.html

相关文章

  • vue中加载three.js的gltf模型
    一、开始引入three.js相关插件。首先利用淘宝镜像,操作命令为:cnpminstallthree//npminstallthree也行二、three.js中所有的控件插件,都可以在node_modules下......
  • vue和浏览器返回操作一致
    methods:{goBack(){//返回上一页this.$router.go(-1);//关闭当前页面;this.$store.dispatch("tagsView/delView",this.$route);}},moun......
  • Vue实现全选全不选功能
                       注意:script里面的vue.js的引用文件最好自己找个线上的<!doctypehtml><html><head><title>......
  • VUE - Cesium 测量
    VUE-Cesium测量 增加测量类:cesiumUtilMeasure.js/**测距*/letCesiumUtilMeasure={};lethandler=null;letMEA={Entitys:[],};//测量空间直线......
  • Vuex3的状态管理
    一.Vuex是什么Vue全局事件总线Vuex状态管理何时使用Vuex二.纯vue组件案例计算总数案例添加人员案例三.Vuex工作原理和流程第一种工作流程第二种工作流程生活化的Vuex工......
  • Vue要做权限管理该怎么做?控制到按钮级别的权限怎么做
    一、是什么权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源而前端权限归根结底是请求的发起权,请求的发起可能有下面两种形式触发页面加......
  • vue路由导航守卫
    简单来说路由导航守卫就是.可以让我们对用户要跳转的路由做一次检查,符合条件的就放行,不符合条件则强制用户跳转至登录页面,说白了就时路由导航守卫是为了路由跳转之前做的......
  • vue开发整理
    1.先检查项目是否有,接下来输入命令行:npminstall加载依赖包node_modulesnpminstall//下载依赖包命令2.如果安装失败请删除node_modulese文件夹,并清除缓存npm......
  • 01_初识Vue
    1.基础代码<!--html代码--><divid="root"><h1>hello,{{name.toUpperCase()}},{{address}}!</h1></div><!--js代码--><script>Vue.config.produ......
  • 网友心得—运行jeecgboot-vue3项目可能出现的问题
    运行jeecgboot-vue3项目可能出现的问题1.执行pnpminstall的时候报错ERR_PNPM_INVALID_OVERRIDE_SELECTOR Cannotparsethe"//"selectorintheoverrides​ 翻......