一、创建vue项目工程

二、导入three.js依赖

三、第一个【vue + three.js】项目

1、核心代码 

2、效果展示

四、源码解析

1、基础知识

2、引入three.js(必须)

3、创建场景(必须)

4、创建相机(必须)

5、创建渲染器(必须)

6、创建几何体(可选)

7、渲染函数(必须)

8、添加坐标轴辅助对象(可选)

9、官网实例

五、可能出现的问题(注意点)

1、相机相关

2、渲染器相关

3、模型相关 

六、项目拓展

1、自适应窗口

2、鼠标操控

3、完整代码


点击下方链接可在three.js官网查看例子与文档;

Threejs 官网

一、创建vue项目工程


选择一个存放项目的文件夹【E:\demo】,“cmd”打开命令行工具;

输入下列代码,创建vue项目,起一个自己的项目名称,例如:“ threejs_demo ”;

vue create threejs_demo

回车,选择vue2项目

回车,等待创建完成;

可以在我们的项目文件夹下看到我们新建的项目【threejs_demo】;

在【vs code】中打开,可以看下如下图所示的项目列表;

点击菜单栏中的【终端】,选择【新建终端】,或者使用快捷键【Ctrl + Shift + `】;

打开后,在【vs code】的下方,会出现如下图所示的窗口;一定要核对路径是否在自己项目的文件夹下,【E:\demo\threejs_demo> 】,如果不是,可以输入“cd xxx”相关命令切换盘符;

继续输入【npm run serve】命令,启动项目;

可以看到我们的项目已成功运行,可在浏览器窗口打开并查看;

​​​​​​​

搭建vue项目(第一个vue项目)

(详细介绍请从上方链接查看)

二、导入three.js依赖

1、下载three.js包

在终端输入下方代码,下载three.js包;

npm i three

 完成后,在<script></script>标签中,输入代码:

// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE");

如下图: 

保存,运行后 可在浏览器的控制台查看打印输出结果:

看到如上输出结果,表示three.js引入成功;

三、第一个【vue + three.js】项目

1、核心代码 

在【components】下新建一个vue文件,例如:threejs.vue,其余保持不变;

在【threejs.vue】文件中编写相关代码;

threejs.vue

<template>
  <div class="box" ref="box"></div>
</template>
<script>
// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;
export default {
  name: "ThreeJs",
  methods: {
    getThreeJs() {
      // 创建场景
      const scene = new THREE.Scene();

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        100
      );
      camera.position.set(10, 10, 10); // 设置相机位置
      camera.lookAt(0, 0, 0); // 设置相机看向原点

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      const box = this.$refs.box; // 获取元素
      box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素

      // 添加辅助坐标
      const axesHelper = new THREE.AxesHelper(20);
      scene.add(axesHelper);

      // 创建几何体
      const geometry = new THREE.BoxGeometry(5, 5, 5);
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      // 声明渲染函数
      function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
      }
      animate();
    },
  },
  mounted() {
    this.getThreeJs(); // 执行three的相关代码
  },
};
</script>
<style scoped>
.box {
  width: 100%;
  height: 100%;
}
</style>

在【App.vue】中引入【threejs.vue】,并展示;

App.vue

<template>
  <div>
    <!-- 使用ThreeJs组件 -->
    <ThreeJs />
  </div>
</template>

<script>
// 引入ThreeJs组件
import ThreeJs from "./components/threejs.vue";
export default {
  name: "App",
  components: {
    ThreeJs, // 注册ThreeJs组件
  },
};
</script>

<style>
* {
  padding: 0;
  margin: 0;
}
</style>

2、效果展示

将上述代码完全copy到自己的项目中, 运行成功后,你会看到如下图所示的展示效果;

四、源码解析

1、基础知识

在梳理代码之前,有必要了解three.js中的一些基本概念:

A.场景

官方给出这样的说明:【场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方】;

我们可以简单理解,场景就是一个容器,是我们用来放东西的地方;我们想要在项目中看到什么东西,便在场景中放什么进去即可;

B.相机

顾名思义,是用来给场景中的物体做投影的;相机就好比是我们的眼睛,它是将场景中的内容呈现给我们的工具;

要注意的相机中有一些必要的参数进行设置,比如,相机自身的位置,相机看向的位置,都会影响我们对整个场景的观测;

C.渲染器

如果有了场景,也有了相机,但是我们在页面中还是看不到想要的效果;

这是因为,虽然场景已经存在,相机也拍到了场景中的内容,但他们都是虚拟存在的,并不能真实呈现;这时候就需要一个工具,把相机看到的内容展示给我们,就是【渲染器】;

它的实质是将【相机】中看到的【场景】内容以Canvas的形式呈现在页面上;

D.渲染函数

渲染函数的作用就是,使渲染器能够在每次屏幕刷新时对场景进行绘制的循环;

2、引入three.js(必须)

在组件的<script></script>标签中,导入three.js包,习惯上命名为【THREE】;

可在控制台进行打印输入,确保three.js成功引入;

// 引入three.js
import * as THREE from "three";
console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;

3、创建场景(必须)

使用【场景(Scene)】创建场景实例对象,它将是所有内容的容器;

// 创建场景
const scene = new THREE.Scene();

4、创建相机(必须)

使用【透视相机(PerspectiveCamera)】创建相机实例对象,其中四个参数分别表示: 视野角度、长宽比、近截面、远截面;

A. 视野角度

是指你在显示器上能看到场景的范围;类似我们人眼视野一样;该值越大,看到的范围越大;

B. 长宽比

是指物体宽(width)除以高(height)的比值;一般设置为窗口的宽高比;比例设置不当,会使得物体被压缩,或者拉伸;

C.近截面

是指在场景中能看到最近的地方,比近截面更近的地方不会被渲染(看不见);

D. 远截面

是指在场景中能看到最远的地方,比远截面更远的地方不会被渲染(看不见);

// 创建相机
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    100
);
camera.position.set(10, 10, 10); // 设置相机位置
camera.lookAt(0, 0, 0); // 设置相机看向原点

5、创建渲染器(必须)

  • 使用【 WebGLRenderer】构造器创建渲染器对象;其中,
  • 【 setSize(width, height)方法 】,将输出canvas的大小调整为整个窗口的宽高比例;
  • 【 renderer.domElement 】即为渲染器绘制输出的Canvas,将其添加到我们的页面容器中即可;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const box = this.$refs.box; // 获取元素
box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素

6、创建几何体(可选)

  • 使用【立方缓冲几何体(BoxGeometry)】创建立方体,可传入 “width”、“height”、“depth” 参数设置立方体的长宽高属性;
  • 使用【基础网格材质(MeshBasicMaterial)】,来创建几何体的材质;
  • 使用【网格(Mesh)】,来创建立方体实例,需要传入几何体的【形状和材质】两个参数;
  • 使用【scene.add()】,再将创建好的【cube】实例对象添加到【场景对象scene】中;
// 创建几何体
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

7、声明并调用渲染函数(必须)

至此,我们已经创建好了场景、相机、渲染器;不难发现,我们的页面中依旧是什么也看不见,这是因为场景中的内容还未进行【真正渲染】;

我们需要定义一个渲染函数,让它做【渲染循环 || 动画循环】;

【requestAnimationFrame(animate)】指定浏览器在下一次循环之前执行指定函数(animate);

【renderer.render(scene, camera)】用我们创建的渲染器实例对象renderer,将场景实例对象scene中内容,在相机实例对象camera中的投影,渲染在Canvas上;

// 声明渲染函数
function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

8、添加坐标轴辅助对象(可选)

使用【AxesHelper】 创建坐标轴对象实例,会在我们的场景中添加一个坐标轴,辅助观测;

红色代表X轴,绿色代表Y轴,蓝色代表Z轴;

// 添加辅助坐标
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);

9、官网实例

three.js 实例——创建场景

五、可能出现的问题(注意点)

1、相机相关

  • 创建相机的时候,需要注意参数的设置,考虑后续创建的模型物体的大小尺寸;避免模型过大或过小,导致不在相机的观测范围内(就像现实中离得太远或者太近的问题);
  • 【相机的位置】和【相机看向的位置】要有大致的概念,避免相机观测的位置不是模型所在的位置(就像现实中有个东西在我们身后,看不见一样);

2、渲染器相关

  • 一定要将渲染器输出的结果Canvas,也就是【renderer.domElement】添加到我们的页面元素中;
  • 一定要声明和执行渲染函数;

3、模型相关 

  •  考虑模型的大小尺寸,要跟相机参数相匹配(不然就得进一步调整相机参数);
  • 一开始我们先选用【基础网格材质(MeshBasicMaterial)】,“这种材质不受光照的影响”,如果选用其他材质,那可能就得设置光源等因素才能使物体呈现在我们的视野中(就像现实中,我们在没有光的时候看不见东西是一样的);
  • 创建好几何体后,要注意【scene.add()】将物体添加到我们的场景中;

以上就是我个人在整个demo的开发过程中,遇到过的问题,或者是觉得需要注意的地方;简单整理,希望有用;

在整个过程中可能还会出现很多其他的问题,但是只要大家耐心,慢慢调试,成功往往就是下一个瞬间!

六、项目拓展

1、自适应窗口

不难发现,我们的项目中,如果改变窗口的大小,页面内容并不能实现自适应,

想要页面内容实现窗口自适应,我们需要添加对window的resize的监听;

一旦浏览器窗口发生大小变化,我们就去更新【渲染器绘制的宽高比】和【相机投影的宽高比】,代码如下:

// 监听窗口变化
window.addEventListener("resize", () => {
    renderer.setSize(window.innerWidth, window.innerHeight);     // 重置渲染器宽高比
    camera.aspect = window.innerWidth / window.innerHeight;      // 重置相机宽高比
    camera.updateProjectionMatrix();                             // 更新相机的投影矩阵
});

2、鼠标操控

此外,我们的页面内容并不能动,不像真正的3D项目,是静态的,是平面的;

我们想操控它动起来,最简单的方式就是添加【轨道控制器】,可以使得相机围绕目标进行轨道运动;

首先,需要引入

// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

然后添加,代码如下:

// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;        // 设置带阻尼的惯性
controls.dampingFactor = 0.05;        // 设置阻尼的系数
controls.autoRotate = true;           // 设置自动旋转

 最后,需要在【渲染函数】animate()中更新控制器,添加下述代码(一定要添加!一定要添加!一定要添加!)

controls.update()       // 更新控制器

 完成后,我们就可以观测到页面中的内容动起来了;

我们也可以使用鼠标控制,按住【鼠标右键 || 鼠标左键】滑动一下,看看效果吧~~~

3、完整代码

只需修改【threejs.vue】即可;

<template>
  <div class="box" ref="box"></div>
</template>
<script>
// 引入three.js
import * as THREE from "three";
// console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功;
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default {
  name: "ThreeJs",
  methods: {
    getThreeJs() {
      // 创建场景
      const scene = new THREE.Scene();

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        100
      );
      camera.position.set(10, 10, 10); // 设置相机位置
      camera.lookAt(0, 0, 0); // 设置相机看向原点

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      const box = this.$refs.box; // 获取元素
      box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素

      // 添加辅助坐标
      const axesHelper = new THREE.AxesHelper(20);
      scene.add(axesHelper);

      // 添加轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      // 设置带阻尼的惯性
      controls.enableDamping = true;
      // 设置阻尼的系数
      controls.dampingFactor = 0.05;
      // 设置自动旋转
      controls.autoRotate = true;

      // 创建几何体
      const geometry = new THREE.BoxGeometry(5, 5, 5);
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      const cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      // 声明渲染函数
      function animate() {
        controls.update()       // 更新控制器
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
      }
      animate();

      // 监听窗口变化
      window.addEventListener("resize", () => {
        // 重置渲染器宽高比
        renderer.setSize(window.innerWidth, window.innerHeight);
        // 重置相机宽高比
        camera.aspect = window.innerWidth / window.innerHeight;
        // 更新相机的投影矩阵
        camera.updateProjectionMatrix();
      });
    },
  },
  mounted() {
    this.getThreeJs(); // 执行three的相关代码
  },
};
</script>
<style scoped>
.box {
  width: 100%;
  height: 100%;
}
</style>

==================================================================================================================================================

现在,不出意外的话,我们已经做好了第一个vue+three.js开发的项目了!

希望通过这个入门案例,使我们对three.js开发有初步了解!

期待后续的完善和创作吧!!!

更多推荐