一、搭建项目
- 创建文件夹并下载依赖
这里用 vite
打包,也可以选择其他打包构建工具
css
mkdir three-demo
cd three-demo
npm i --save three
npm i --save-dev vite
- 新建
index.html
和main.js
html
<!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>
<canvas class="webgl"></canvas>
<script type="module" src="/main.js"></script>
</body>
</html>
在main.js
导入并打印(后续 js 都添加到此文件)
js
import * as THREE from 'three';
console.log(THREE)
- 修改
package.json
, 配置打包和运行2个命令
js
"scripts": {
"dev": "vite",
"build": "vite build"
},
- Vite 应该显示一个类似于 的 URL
http://localhost:5173/
。将其复制并粘贴到浏览器中,即可像打开任何网站一样打开它。
二、创建场景并制作物品
需要4个元素才能开始:
- 包含对象的场景
- 一些物体
- 相机
- 渲染器
场景
好比容器,将对象、模型、粒子、灯光等放入,指定时间渲染场景
用Scene类创建场景
arduino
const scene = new THREE.Scene()
对象
对象可以是很多东西。可以拥有原始几何图形、导入的模型、粒子、灯光等。
创建一个简单的红色立方体,使用BoxGeometry类,其前 3 个参数对应于盒子的大小
arduino
// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)
为了创建材质,使用带有一个参数的MeshBasicMaterial类:一个{}
包含所有选项的对象。指定它的color
属性。
php
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
颜色值可为:
- JS 十六进制,如
0xff0000
- 字符串十六进制,如
'#ff0000'
- 颜色名称,如
red
创建最终的网格,使用Mesh类并发送geometry
和 作为material
参数
arduino
const mesh = new THREE.Mesh(geometry, material)
使用add(...)
方法将网格添加到场景中,不然看不见它:
csharp
scene.add(mesh)
相机
相机不可见。当渲染场景时,它将是从该摄像机的角度进行的。一般只使用一台相机。
为了创建相机,我们使用PerspectiveCamera类。
我们需要提供两个基本参数。
1. 视野范围
视野是指你的视角有多大。如果您使用非常大的角度,您将能够同时看到每个方向,但会出现很大的失真,因为结果将绘制在一个小矩形上。如果使用小角度,物体看起来会放大。视野(或
fov
)以度数表示,对应于垂直视角。在本练习中,我们将使用75
度角。
3. 纵横比
在大多数情况下,长宽比是画布的宽度除以高度。目前我们还没有指定任何宽度或高度,但稍后我们需要指定。与此同时,我们将创建一个具有可以重复使用的临时值的对象。
js
// Sizes
const sizes = {
width: 800,
height: 600
}
// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
scene.add(camera)
ps: 相机必须添加到场景,不然会导致未知错误!
该
position
属性是一个具有三个相关属性的对象:x
、y
和z
。默认情况下,Three.js 认为前/后轴为z
渲染器
渲染器的工作就是进行渲染。
使用带有一个参数的WebGLRenderer类:一个{}
包含所有选项的对象,指定canvas
与<canvas>
为相对应的属性。
canvas
在代码开头创建一个变量,然后获取在 HTML 中使用创建的元素并将其存储在其中document.querySelector(...)
。 该setSize(...)
方法将自动相应地调整我们的<canvas>
,即渲染器大小:
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
参数:
js
renderer.render(scene, camera)
添加动画
js
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
全部代码
js
import * as THREE from "three";
console.log(THREE);
// 场景 scene
const scene = new THREE.Scene();
// object
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const sizes = {
width: 800,
height: 600,
};
// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
camera.position.z = 5;
scene.add(camera);
const canvas = document.querySelector("canvas.webgl");
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(sizes.width, sizes.height);
renderer.render(scene, camera);
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
附录
参考官网demo: threejs-journey.com/lessons/fir...