03.Basic scene 基本场景
介绍
在我们的第一课中,我们将使 Three.js
以最直接的方式工作:没有捆绑器、没有依赖、没有模块,只有一个 HTML
文件和一些 JavaScript
。
基本文件
首先,创建一个普通index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03 - Basic Scene</title>
</head>
<body>
<script src="./script.js"></script>
</body>
</html>
和一个简单的script.js
文件:
console.log('Hello Three.js')
现在打开开发者工具。
然后导航到Developer Tools
顶部的Console
选项卡。
您应该始终保持控制台打开,以查看潜在的错误和警告。
如何加载Three.js
现在我们需要加载 Three.js
库。有很多方法可以做到这一点。现在,我们将简单地下载库并使用.
转到https://threejs.org/单击下载按钮下载 zip 文件并解压缩。文件很大,不过不用担心,我们只需要其中的一个文件。
你应该得到一个如下所示的文件夹:
转到build/
文件夹并将three.min.js
文件复制到您的项目。
你应该得到这样的结果:
我们现在可以在末尾加载 Three.js
库:
<script src="./three.min.js"></script>
<script src="./script.js"></script>
确保three.min.js
在script.js
之前加载;否则,script.js
中脚本先执行了,将不知道three.min.js
文件中的内容。
如何使用 Three.js
在我们的script.js
文件中,我们可以访问到一个名为THREE
的变量。 注意必须使用大写字母书写。
如果你console.log()
这个变量,你会发现里面有许多属性:
console.log(THREE)
该THREE
变量包含开发 Three.js
项目中可能需要的大部分类和属性。不幸的是,并不是所有的类都在这个变量中,但我们稍后会教学如何访问使用它们。
要使用其中一个类,您需要实例化它。例如,如果你想创建一个场景,你会写const scene = new THREE.Scene()
. 如果你想创建一个球体几何体,你需要写const sphereGeometry = new THREE.SphereGeometry(1.5, 32, 32)
——我们稍后会更深入地研究这些。
第一幕
是时候创建我们的场景并在屏幕上制作一些东西了。
我们需要准备 4 个要素才能开始:
- 包含对象的场景
- 一些模型对象
- 相机
- 渲染器
场景Scene
场景就像一个容器。您将对象、模型、粒子、灯光等放入其中,并在某个时候要求 Three.js
渲染该场景。
要创建场景,请使用Scene类:
// Scene
const scene = new THREE.Scene()
对象Mesh
对象可以是很多东西。包括原始几何体、导入的模型、粒子、灯光等。
我们将从一个简单的红色立方体开始设计。
要创建红色立方体,我们需要创建一种名为Mesh的对象。网格是几何体(形状)和材质(外观)的组合。
有许多种几何体和材料的类型,但我们现在先简单的创建一个BoxGeometry和一个MeshBasicMaterial。
要创建几何图形,我们使用BoxGeometry类,其前 3 个参数对应于框的大小。
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)
为了创建材质,我们需要使用带有一个参数的MeshBasicMaterial类:一个{}*
包含所有选项的对象。我们可以先指定它的color
属性。
在 Three.js
中有多种指定颜色的方法。您可以将其作为 JS hexadecimal 输入0xff0000
,也可以将其作为 string hexadecimal 输入 '#ff0000'
,也可以使用颜色名称,如输入Color’red’——我们稍后会详细介绍。
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
为了创建最终的网格,我们使用Mesh类并写入**geometry**
和**material**
参数。
// Object
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const mesh = new THREE.Mesh(geometry, material)
现在可以使用以下add(...)
方法将网格添加到场景中:
scene.add(mesh)
如果不向scene场景添加mesh对象,那么这个对象就无法渲染了。
相机Camera
相机不可见。这更像是一种理论观点。当我们对场景进行渲染时,将从该摄像机的视觉角度进行渲染。
你可以抽象为电影场景中的摄像机,所以three.js
中一样拥有多个摄像机,并且可以根据需要,在这些摄像机之间切换。通常,我们只使用一台相机。
有不同视角类型的相机,我们将在以后的课程中讨论这些。现在,我们只需要一个处理透视的相机(使近距离物体看起来比远距离物体更突出)。
要创建相机,我们使用PerspectiveCamera类。
我们需要为这个类提供两个基本参数。
参数一:视野
视野就是你的视角有多大。如果您使用非常大的角度,您将能够同时看到各个方向,但会造成画质失真,因为结果将绘制在一个小矩形上。如果您使用小角度,事物看起来会放大。视野(或fov)以度数表示,对应于垂直视角。在本练习中,我们将使用75角度。
参数二:纵横比
在大多数情况下,纵横比是画布的宽度除以它的高度。我们现在还没有指定任何宽度或高度,但稍后我们需要指定。同时,我们将创建一个具有可以重复使用的临时值的对象。
不要忘记将相机添加到场景中。如果将相机忘记添加到场景的情况下,它可能会在以后导致错误产生:
// Sizes
const sizes = {
width: 800,
height: 600
}
// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
scene.add(camera)
渲染器WebGLRenderer
渲染器的工作是进行渲染。
我们将简单地要求渲染器从相机的角度渲染我们的场景,结果将被绘制到画布中。您可以自己创建画布,也可以让渲染器生成它,然后将其添加到您的页面中。对于本练习,我们会将画布添加到 html
并通过JavaScript
获得元素节点将其绑定给渲染器。
在加载脚本之前创建<canvas>
元素并给它一个class
:
<canvas class="webgl"></canvas>
要创建渲染器,我们使用带有一个参数的WebGLRenderer类:一个{}
包含所有选项的对象。我们需要指定canvas
变量对应于我们<canvas>
标签。
创建一个变量canvas
,然后获取document.querySelector(...)
在 HTML
中使用创建的<canvas>
标签并将其存储在其中。
最好将画布分配给一个变量,因为我们将在下一课中使用这个变量操作DOM
元素。
setSize(...)
方法:我们还需要使用之前创建的对象的方法更新渲染器sizes
的大小。该setSize(...)
方法将相应地自动调整我们<canvas>
的大小:
// Canvas
const canvas = document.querySelector('canvas.webgl')
// ...
// Renderer
const renderer = new THREE.WebGLRenderer({
canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
现在,我们还是看不到任何东西,但是画布就在那里,并且已经相应地调整了大小。可以使用开发人员工具来检查<canvas>
的大小。
首先渲染
是时候开始我们的第一次渲染了。render(...)
在渲染器上调用该方法并将其发送scene
和camera
参数:
renderer.render(scene, camera)
依然没有?问题是:我们没有指定对象的位置,也没有指定相机的位置。两者都处于默认位置,即场景的中心,我们无法从实心的对象内部看到对象整体外貌(默认情况下)。
我们需要移动对象。
为此,我们可以访问每个对象的多个属性,例如position
、rotation
和scale
。现在,使用position
属性向后移动相机。
该position
属性是一个具有三个相关属性的对象:x
,y
和z
。默认情况下,Three.js 认为向前/向后轴是z
.
要向后移动相机,我们需要为该属性提供一个正值。一旦你创建了camera
变量,你就可以在任何地方使用,但它必须在你进行渲染之前使用:
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
scene.add(camera)
恭喜,我们看到了的第一个渲染出来的作品。它看起来像一个正方形,那是因为相机与立方体完美对齐,你只能看到它的一侧。
不要担心渲染的大小;稍后我们将学习如何使画布适合视口。
在接下来的课程中,您将了解有关position
、rotation
和scale
属性的更多信息,以及如何更改它们以及为场景制作动画。