如何轻松上手 ThreeJS - 第一部分
大家好,希望你们一切都好!:)
最近我在推特上看到一个预告视频:是@prismicio发布的对@brunosimon的采访。在采访中,他讲解了如何使用ThreeJS为网站添加3D元素。
以下是那条推文的链接:
这次采访以及 Bruno 对 ThreeJS 概念的热情讲解给了我很大的启发,所以我决定开始深入研究这个新的虚拟世界。
我会尽量用最简单明了的方式进行总结和解释。
我保证,只需大约 30 行代码,你就能创建出你的第一个可用的 3D 元素(文章末尾有总结)。
项目设置
第一步是创建一个新的index.html文件,其内容应如下所示:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1"/>
<link rel="stylesheet" href="css/styles.css"/>
<title>My first ThreeJS demo app</title>
</head>
<body>
<script src="js/script.js" type="module"></script>
</body>
</html>
然后,我们应该在index.html文件中添加两个“链接”的外部文件:我们创建styles.css和script.js文件,并将它们分别放在css和js文件夹中。
现在是时候初始化我们的包管理器来配置我们的项目了,所以我们启动一个
npm init
我的默认包管理器是 NPM,但你当然也可以使用 Yarn。
Three.js 的安装和设置
要开始使用 Three.js,我们需要先安装它。我们可以通过打开终端并运行以下命令来完成安装:
npm install three
然后,在script.js文件中,我们可以使用以下代码导入 Three:
import * as THREE from "three";
现在我们已经导入完毕,可以开始使用了。
首先需要了解的是,Three 安装完成后,我们可以访问一个非常特殊的变量,即“THREE”。通过记录日志,我们可以看到我们已经可以访问该库支持的许多功能:
console.log(THREE);
如何添加场景、摄像机和宽高比
首先我们需要三样东西:第一样是场景,就像电影布景一样。在场景中添加物体(可以是角色)和一个摄像机。
首先,我们创建一个空白场景:
const scene = new THREE.Scene();
在场景中我们提到需要添加一个摄像机。
这里需要了解的是,Three.js 中有多种类型的摄像机(更多信息请参阅文档)。
我们将使用PerspectiveCamera,它模拟人眼的视觉方式,就像现实生活中的摄像机一样:距离越近,看到的物体就越大。
要创建相机,我们需要添加:
const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight);
相机需要一些参数选项:
-
第一个选项是视场角(FOV),单位为度。我们可以选择180度的开阔视角,也可以选择像摄影镜头那样30度的近景视角。
根据布鲁诺的经验,他建议选择40度到70度之间的视角,所以我们将使用55度的视角。 -
第二个必需选项是宽高比:由于我们希望页面背景完全被覆盖,因此需要指定视口的宽度和高度。在 JavaScript 中,我们可以使用`window.innerWidth`和`window.innerHeight`来获取这些尺寸。
简而言之:宽高比就是宽度除以高度。
使用 Three.js 需要理解的一点是,无论我们想要包含什么对象,都必须将其添加到场景中。目前,我们可以通过输入以下代码来添加摄像机:
scene.add(camera);
向场景中添加网格
在第一篇文章中(是的,这将是一个系列文章😉),我们将向场景中添加一个立方体。
立方体是一个我们可以看到的对象,在 Three.js 中,我们可以看到的对象被称为网格(mesh)。
网格由两部分组成:几何体(构成几何体的点,例如立方体的顶点数)和材质,即几何体在场景中渲染时的外观。
我们首先需要创建几何体,因为我们想要的是一个立方体,所以我们将使用它的相关类“BoxGeometry”:
const geometry = new THREE.BoxGeometry(1, 1, 1);
该类一旦收到所需的参数(即宽度、高度和深度) ,就会自动知道应该创建立方体的点(参见文档)。
现在该为立方体添加渲染时使用的材质了。在这个第一个实验中,我们希望立方体完全是红色的。所以我们添加以下内容:
const material = new THREE.MeshBasicMaterial({color: 0xff0000});
“MeshBasicMaterial”类以及所有可用的网格和几何体类都可以在文档中找到,并附有大量示例。我们传入的参数是颜色。
颜色参数可以通过多种方式指定:
- 作为字符串(“红色”);
- 以十六进制表示(#FF0000);
- 以十六进制表示(0xff0000)。
至此,我们已经有了几何体和材质,接下来可以将它们混合到一个网格中,并将其添加到场景中:
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
渲染场景
终于到了见见我们的立方体的时候了!
我们使用最常见的 WebGL 渲染器“WebGLRenderer”来声明渲染器:
const renderer = new THREE.WebGLRenderer();
我们的渲染器需要知道画面大小,正如我们之前所说,我们希望场景占据整个视口宽度。所以我们可以告诉渲染器:
renderer.setSize(window.innerWidth, window.innerHeight);
为了看到我们的场景,现在我们需要在画布🎨中绘制。
查看渲染器变量,我们可以注意到画布包含在domElement属性中。
如果我们将其输出到日志,就可以看到画布:
console.log(renderer.domElement);
此时,我们将让 ThreeJS 创建画布并将其添加到<body>页面的 <head> 元素中;我们可以通过添加以下代码行来实现:
document.body.appendChild(renderer.domElement);
检查我们的 DOM,现在应该可以看到我们的<canvas>元素已添加到其中<body>。
作为渲染器的最后一步,我们现在需要告诉它渲染页面内的画布。这需要场景(我们应该已经在其中添加了所有必要的元素)和摄像机。
renderer.render(scene, camera)
固定相机并旋转立方体
上一个问题的答案与相机位置有关。
我们仍然看不到立方体,因为我们身处立方体内部。
你现在可能在想:既然立方体是红色的,那我周围的一切不应该都是红色的吗?
答案是否定的:默认情况下,我们无法看到几何体的“内部”。我们可以看到它的正面,但看不到它的背面。
既然我们已经了解了以上内容,现在应该将相机位置移到立方体之外。向上移动到我们定义相机变量的位置,在该行下方添加以下代码:
camera.position.z = 3
为了将相机向后移动,我们需要调整Z轴方向。
完成后,我们就能看到立方体了:
我们还可以通过编辑x轴和y轴上的位置,将相机位置向左/向右或向上/向下移动(例如:在我们的最终演示中,我们将把对象稍微向右移动,以便在左侧为标题、段落和可能的 CTA 留出空间)。
由于在这种设置下,我们的物体是平面的,所以它看起来不像是一个真正的立方体。我们可以旋转这个立方体来观察一些角度。
要实现旋转,我们只需要对网格对象进行操作。
正如 Bruno 所说,为了水平移动它,我们需要在 y 轴上添加一个尖角,因此在网格声明行下方,我们将添加:
mesh.rotation.y = 0.5
请记住,测量单位是弧度,而不是角度。所以,数学在这里可以帮我们解决很多问题,比如圆周率(π),它代表半个圆。
如果你能想到圆周率,就可以想“八分之一圆”等等,只需将圆周率的值乘以或除以相应的数值即可。
概要
我把完整的script.js代码块放在这里,方便你更好地查看:
// script.js
import * as THREE from "three";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight);
camera.position.z = 3;
scene.add(camera);
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.y = 0.5;
scene.add(mesh);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render( scene, camera );
document.body.appendChild(renderer.domElement);
我们终于可以在页面上看到我们的 3D 立方体,并且可以调整它的位置、旋转和颜色。
在接下来的几篇文章中(敬请期待),我们将为立方体添加动画效果,学习如何改变它的几何形状和材质,以及如何使画布具有响应式设计。
我们还会加入一些流畅的动画效果,以及一些与物体互动的小技巧。
最终成果已可通过此演示链接查看:
👉🏼 https://th3wall-threejs.netlify.app
希望您已经有所收获,也希望您觉得这篇文章有趣。
请在Twitter、GitHub和Hashnode上关注我。
如果你喜欢这篇文章,请告诉我!
谢谢
。Th3Wall



