ThreeJS之旅 02

介绍

现在让我们编码创造我们第一个Three.js场景。

如果你熟悉现在前端工具,像Node.js和Vite,那么你可以跳过本节的大部分内容。

本地服务器和构建工具

为了运行我们之后的Three.js网站,需要运行一个本地服务器。

我们可以创建一个HTML文件在电脑上,双击打开它,但是浏览器会因为安全原因限制网站的功能。做为结果,我们将不能加载Three.js,模型,纹理一系列东西。

最简单的解决方法就是使用构建工具或打包工具。

现在的构建工具

有很多的构建工具可供选择,你可能听说过一些像WePack、Vite、Gulp、Parcel。

他们有各自的的优点和缺点,但是我们接下来会使用指定的构建工具。

如今,最流行的构建工具是WebPack。它被广泛地使用,拥有一个很大的社区,你可以用它来做很多事情。但是尽管WebPack是最流行的,它不是最好用的。

事实上,现在最好用的构建工具是Vite。它安装起来很快,运行也很快,并且更少出现bug。开发者的体验会更好。

Vite

在这里,简单介绍一些关于Vite的内容。

正如之前提到的,Vite是一个构建工具。我们将会编写像 HTML/CSS/JS 的网站代码,Vite会帮我们构建最终的网站。Vite也可以用来做优化,解决缓存实效的问题,源码映射,作为一个本地服务器运行。

Vite除了这些基本功能,我们还可以增加插件来增加更多特性。我们之后会增加插件,支持GLSL文件来构建我们自己的着色器,并且让它运行在React上。

终端

我们会运行一些命令在终端上。我们将会使用Termial(MacOS)或者Command Prompt(Windows),实际上更推荐使用VSCode的内置终端。打开VSCode,键入CMD + J (MacOS)或者CTRL+J(Windows)去打开内置终端。

Node.js

为了运行Vite,你需要在你的计算机上安装Node.js。

Node.js可以让你在浏览器外运行JavaScript。这便于运行各种各样的工具,比如Vite。

为了安装Node.js,前往 nodejs.org/en/,下载"LTS"版本,然后以默认设置安装即可。

重新打开你的撞断,然后运行node -v命令查看版本。

创建一个Node.js项目

现在我们拥有了Node.js,并且知道如何使用终端,让我们创建第一个Node.js项目。

创建一个将要包含你网站的文件夹。

接下来用VSCode打开文件夹。打开VSCode内置终端运行npm init -y命令。

当我们安装Node.js的时候,我们自动安装了NPM。NPM是一个Node的包依赖管理器,可以用来获取三方库,比如Three.js,Vite。另外,NPM拥有一个命令行接口npm可以在终端中使用。

通过运行npm init -y命令,NPM将会创造一个package.json文件,这个文件包含运行Node.js项目的最少信息。

添加依赖

在本节中,我们将会添加两个依赖。Vite和Three.js。

现在,我们将注意力集中在Vite。为了给Node.js项目添加依赖,在终端中运行npm install vite

需要注意三件事情。

  • node_modules/文件夹被创建了。这个文件夹包含了项目的依赖,不要轻易修改这个文件夹里面的内容。除了包含vite依赖在vite/文件夹下,同样也包含其他被vite用的依赖。
  • package.json文件被更新了,现在包含一个依赖数组写在"dependencies"属性。
  • pacakge-lock.json文件被创建,并且包含依赖的具体信息和具体版本,这会让让你的项目准确安装依赖版本。

这两个文件使得项目可以被分享。如果你想分享Three.js项目给其他开发者,你将要移除node_modules文件夹,然后分享剩余的项目。其他开发者会获取你项目,运行命令npm install,根据package.json自动创建node_modules

基础网站

现在,让我们创建一个基础的网站。

在项目文件夹下,创建index.html文件。

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>03 - First Three.js Project</title>
</head>
<body>
    <h1>Soon to be a Three.js website</h1>
</body>
</html>

不要直接打开这个文件。这样做会违背我们使用Vite的初心。

package.json中,用下面的内容替换"scripts":

json 复制代码
{
  // ...
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  // ...
}

这样我们拥有了两个"scripts",现在可以在终端运行devbuild命令,这些命令会分别触发vitevite build,通过使用在node_modules/文件下的vite/依赖。

为了运行dev脚本,在终端中,运行npm run dev

Vite将会展示一个类似http://localhost:5173的URL。复制它并在浏览器中打开,你会看到如下网站。

恭喜🎉,你已经让自己的Vite网站运行起来了。

添加JavaScript

现在我们需要执行一些JavaScript在网站上。

在项目文件夹下,创建script.js文件:

arduino 复制代码
console.log('JavaScript is working')

index.html,在<body>的最后添加<Script>:

xml 复制代码
<!-- ... -->
<body>
    <h1>Soon to be a Three.js website</h1>
    <script type="module" src="./script.js"></script>
</body>
</html>

不要忘记了 type="module"

打开浏览器中的开发者工具,你将会在控制台中看见JavaScript is working

Three.js

就像我们之前添加Vite到项目中,我们需要添加Three.js。

添加依赖

这个依赖的名称在NPM上是three

我们需要运行npm install three,但我们的终端目前正在运行Vite服务器。

我们有两个选项:

  • 打开一个新的终端,运行命令。
  • 关闭服务器,运行命令,随后重启服务器。

我们将会关闭服务器。

按下CTRL + C来停止服务器。

现在运行npm install three:

引入Three.js

回到scirpt.js,我们按照下面的方式导入three依赖:

javascript 复制代码
import * as THREE from 'three'

这样将会从three依赖导入所有Three.js的核心类在THREE变量中。

这样导入依赖的方式称之为"ES modules"。

使用Three.js

在我们的script.js文件,现在可以获取一个变量名城THREE

如果你console.log()这个变量,你会看到里面的很多内容:

javascript 复制代码
import * as THREE from 'three'
​
console.log(THREE)

THREE变量包含大量的类和属性,这些内容会在Three.js项目中被使用。为了使用这些类,你需要实例化它。举个例子,如果你需要创建一个窗景,你需要写下const scene = new THREE.Scene()。如果你想创建一个球形几何体,你需要写下const sphereGeometry = new THREE.SphereGeometry(1.5, 32, 32)

第一个场景

现在来创建我们的场景并创造一些东西在屏幕上。

我们需要四个元素:

  • 一个场景用来包含物体
  • 一些物体
  • 一个相机
  • 一个渲染器

场景

场景像一个容器。我们可以在里面放置物体,模型,粒子,光源。然后使用Three.js渲染场景。

为了创建场景,使用Scene类:

arduino 复制代码
// Scene
const scene = new THREE.Scene()

物体

物体有很多类别,可以是原生的结合体,导入的模型,粒子,光源等其他东西。

我们将会从一个红色的立方体开始。

为了创建红色立方体,需要先创建一个类型为Mesh的物体。一个Mesh是几何体和材质的聚合体。

为了创建这个几何体,我们使用BoxGeometry类,带有三个参数对应着盒子的大小。

arduino 复制代码
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)

为了创建材质,我们需要使用MeshBasicMaterial类,它带有一个参数:一个对象{}包含所有选项。我们需要指定它的color属性。

在Three.js中,有很多方式指定颜色。你可以传入JS十六进制格式 0xff0000 ,也可以传入字符串格式的十六进制'#ff0000',也可以使用像'red'这样的颜色名称,或者传入一个Color类的实例。

php 复制代码
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })

为了创建最后的mesh,我们使用Mesh类,并且传入geometry和material作为参数。

php 复制代码
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const mesh = new THREE.Mesh(geometry, material)

最后再往场景中添加mesh:

csharp 复制代码
scene.add(mesh)

相机

相机是不可见的。它更像是理论上的一个观察点。当我们为场景做渲染的时候,会从相机的视角出发。

你可以拥有很多相机,并且在它们之间切换。但是通常情况下,我们只会用一个相机。

有几种不同的相机,我们会在之后的内容详细讨论。但现在,我们使用透视相机。

为了创建这个相机,需要使用PerspectiveCamera类。

view字段

view字段代表着视角的角度。如果你使用一个非常大的角度,你能立马看到各个方向的内容,但是有着很大的失真,因为这些内容会被绘制在很小的长方形内。如果你使用小角度,物体看起来就像被放大了。view字段(fov)表示我们在垂直方向上的可视角度。

aspect ratio

在很多情况下,aspect ratio是画布的宽度除以他的高度。

arduino 复制代码
// Sizes
const sizes = {
    width: 800,
    height: 600
}
​
// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
scene.add(camera)

渲染器

渲染器的工作是渲染。

我们将会让渲染器将我们的场景从相机的视角渲染,并且渲染结果会绘制在画布上。你可以自己创建画图,或者让渲染器生成一个,然后把它加入到页面中。

在index.html中,替换掉<h1>,在加载脚本之前创建一个<canvas>元素:

ini 复制代码
<canvas class="webgl"></canvas>

为了得到canvas变量,我们需要使用document.querySelector(...)。还需要用setSize(...)修改渲染器尺寸。

arduino 复制代码
// Canvas
const canvas = document.querySelector('canvas.webgl')
​
// ...
​
// Renderer
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)

第一次渲染

在渲染器上调用render(...),并将scene和camera作为参数:

scss 复制代码
renderer.render(scene, camera)

一个黑色的场景?我们物体在哪里?

原因在这里:我们没有指定物体的位置,也没有指定相机的位置。它们都在默认的位置上,这个场景的中心,所以我们看不到物体。

我们需要移动物体。

为了移动物体,我们需要访问每个物体的多个属性,比如position,rotation,scale。现在,我们使用postion属性向后移动我们的相机。

postion属性有三个相关的属性:x,y和z。默认情况下,Three.js默认 前/后 方向轴为z。

为了向后移动相机,我们需要提供一个相对值给position属性。你可以在任何地方设置position,只要在渲染前设置好就行。

arduino 复制代码
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
scene.add(camera)

现在就可以看到我们渲染的第一个场景。

相关推荐
Mintopia21 小时前
深入理解 Three.js 中的 WebGLRenderer
前端·javascript·three.js
Mintopia2 天前
Three.js 进阶:复杂模型与动画处理技巧
前端·javascript·three.js
糖墨夕3 天前
【1】Three.js入门心得记-开发环境及准备工作
前端·three.js
伶俜monster3 天前
破解旋转死锁:Threejs 四元数魔法对抗欧拉角困局
前端·webgl·three.js
阿白的白日梦3 天前
TSL文档译本留存学习
javascript·three.js
Mintopia4 天前
深入理解 Three.js 中的 Mesh 对象
前端·javascript·three.js
不浪brown4 天前
炸裂的开源!基于Three+Vue3的三维低代码编辑器,还支持BIM+CAD,绝了!
three.js·trae
谢小飞5 天前
Threejs全球坐标分布效果
前端·three.js
Mintopia5 天前
Three.js 相机(Camera)的使用详解
前端·javascript·three.js