动手学Three.js(一) 起步
本文是专栏文章的第一篇,本专栏,将带你带你从零开始学习关于Three.js的一切。包括简单场景,简单动画,Gui,材质,灯光,交互,物理, shader。最后完成一个超酷的网页。
阅读本系列文章需要一丢丢 html 和 js 知识。
在本节我们会简单对Three.js进行介绍,随后基于vite 搭建一个简单的项目,并通过three.js创建一个简单的场景。
介绍
Three.js 是一个用于在 Web 上创建交互式 3D 图形的 JavaScript 库。它是基于 WebGL 技术的封装,简化了在浏览器中使用 WebGL 进行 3D 图形编程的复杂性。
Three.js 提供了一组易于使用的工具和功能,使开发人员能够创建各种 3D 场景、动画和效果,而无需深入了解底层的 WebGL。它提供了从基本几何形状(如立方体、球体和平面)到复杂的模型、纹理映射、光照、阴影和相机控制等功能。
初始化项目
💡 node版本应该大于16.0初始化npm项目
npm init
安装vite
npm install --save-dev vite
安装three.js
npm install --save three
创建基础文件
新建一个index.html,以及一个js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module" src="./main.js"></script>
</body>
</html>
import * as THREE from 'three';
运行
npx vite
当然也可以修改 package.json
"scripts": {
"dev":"vite"
},
后运行 npm run dev
Hello World
项目搭建完成之后,我们开始创建我们的第一场景。这或许是three.js的hello,world。
Scene
(场景)
场景就像一个容器。您将对象、模型、粒子、灯光等放置在其中,然后在合适的时候我们会让渲染器渲染该场景。
使用 Scene 类,创建场景:
const scene = new THREE.Scene()
对象
在3d的世界里,所有东西都是一个对象。比如灯光,模型,粒子,在本章节我们先创建一个简单的立方体对象。
为了创建红色立方体,我们需要创建一种Mesh
(网格) 对象。网格是Geometry
(几何体)和Material
(材质)的组合。
Geometry
(几何体)
几何体定义了3D对象的形状和结构。如大小,位置,旋转等。
💡 尺寸,在3D世界是复杂的,这些尺寸的单位是以场景的单位(通常是米)为基准。但实际看到的尺寸取决于很多因素,比如相机的参数。在此我们不必深究。创建一个简单的立方体,三个参数分别是长,宽,高:
const geometry = new THREE.BoxGeometry(1, 1, 1)
Material
(材质)
材质定义了网格对象的外观和视觉特性。它决定了网格如何对光线进行反射和阴影的投射。材质可以包含颜色、纹理、透明度、光照计算方式等属性。通过设置不同的材质,我们可以改变对象的外观,比如让它显示为金属、塑料、木材等材质效果。
创建一个简单的单色材质:
const material = new THREE.MeshBasicMaterial({ color: 0xffc0cb})
Mesh
(网格)
在有了几何体和材质之后,我们就可以创建网格
const mesh = new THREE.Mesh(geometry, material)
我们创建了一个正方体网格对象,现在将它添加到场景中
scene.add(mesh)
Camera
相机
相机是用于定义场景中的视角和投影的对象。它决定了用户在渲染的3D场景中所看到的内容。
就像现实中的相机有不同的焦段,Three.js,中的相机可以用**FOV(视野角度)**设置显示器看到的场景范围。
如果您使用非常大的角度,您将能够同时看到每个方向,但会出现很大的失真,因为结果将绘制在一个小矩形上。如果使用小角度,事物看起来会放大。
fov 以度数表示,在本练习中,我们将使用 75
度角。
相机拍摄的照片可以有不同的尺寸,比如3:4,16:9。在three.js中我们可以用**aspect ratio(长宽比)**表示。 我们通常使用画布的长/画布的宽
,这样会让画面以正常的比例显示。
另外两个参数是近截面(near)和远截面(far。 当物体某些部分比摄像机的远截面远或者比近截面近的时候,该这些部分将不会被渲染到场景中。
就像在玩原神时,远处的画面不会被渲染。
现在我们不需要设置这两个值,但未来为了获得更好的渲染性能,就需要去设置合适的值。
const sizes = {
width: 800,
height: 600
}
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
scene.add(camera)
Canvas
我们创建了一个完整的场景,但当你想要施展才华时,需要有一个舞台。恰好html提供的 Canvas
可以满足我们的需求,在index.html中添加。
<canvas class="webgl"></canvas>
Render
渲染
我们拥有画布 canvas
,和场景scence
,但它们还没有任何联系。这时我们需要画家renderer
的帮助。
渲染器的作用就是将我们已经创建好的场景显示到 canvas
中:
const canvas = document.querySelector('canvas.webgl')
const renderer = new THREE.WebGLRenderer({
canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
最后,激动人心的时刻:
renderer.render(scene, camera)
但,现在画面一片漆黑。
我们并没有为摄像头和可爱的小正方体设置位置属性,所以它们现在叠在了一起。默认情况下,我们无法从内部看到对象。
所以需要移动下相机的位置:
💡 在将camera添加到scene之前camera.position.z = 3
画面中出现了一个正方体,虽然它看起来像正方形,
修改一下旋转角度(此属性将在下一节讲解):
💡 在将mesh添加到scene之前mesh.rotation.x =0.5;
mesh.rotation.y =0.5;
可以看到我们确实创建了一个正方体,虽然它看起来并不酷。
下一步
我们创建了第一个three.js页面,虽然它看起来很简单,但我们几乎用到了所有常用到的东西。接下来我们将持续学习,直到打造出一个超酷的网页。在下一节中我们将为这个立方体添加动画,并学习 position
(位置),rotation
(旋转),scale
(尺寸)等知识。
参考
该章节部分内容参考Three.js官网和threejs-journey: