gitee 地址
gitee
地址: gittee地址
本篇目标
- 搭建开发环境
- 安装
three.js
- 了解
three.js
的基本内容 - 搭建一个3d立方体并渲染到页面上
搭建
全程采用vite
用作本地服务启动工具。
创建一个文件夹,在终端中打开文件夹并输入以下内容
// pnpm
pnpm create vite
// npm
npm create vite@latest
// yarn
yarn create vite
删除多余文件,并删除main.js
中的内容。文件夹结构如下图:
安装 three.js
// pnpm
pnpm i three -s
// npm
npm i three -s
// yarn
yarn three
//
<script src="https://threejs.org/build/three.js"></script>
了解three.js
three.js
官网地址:官网
在使用的过程中,我们需要用到three.js
的三大组件,分别是场景(Scene)
、相机(Camera)
、渲染器(Renderer)
场景 ( Sene )
场景是所有物体的容器。我们需要将所渲染的内容放入场景中。
//创建场景
const scene = new THREE.Scene();
相机( Camera )
相机决定了场景中那个角度的景色会显示出来。相机就像人的眼睛一样,人站在不同位置,抬头或者低都能够看到不同的景色。场景只有一种,但是相机却有很多种。只要设置不同的相机参数,就能够让相机产生不一样的效果。
StereoCamera | 立体相机 |
---|---|
PerspectiveCamera | 透视相机 |
OrthographicCamera | 正交相机 |
CubeCamera | 立方相机 |
// 创建相机
/*
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面
*/
// 透视相机
const camera = new THREE.PerspectiveCamera(
75, // 摄像机视锥体垂直视野角度,从视图的底部到顶部,以角度来表示。默认值是50。
window.innerWidth / window.innerHeight, // 摄像机视锥体的长宽比,通常是使用画布的宽/画布的高。默认值是1(正方形画布)。
0.1, // 摄像机的近端面,默认值是0.1。
1000 // 摄像机的远端面,默认值 2000
)
渲染器 renderer
渲染器决定了渲染的结果应该画在页面的什么元素上面,并且以怎样的方式来绘制。
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);
//挂载到页面
document.body.appendChild(renderer.domElement)
// 渲染
function animate() {
//scene:前面定义的场景,camera:前面定义的相机
//renderTarget:渲染的目标默认是是渲染到前面定义的render变量中
//forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
renderer.render(scene, camera)
// 使用 requestAnimationFrame 执行动画
requestAnimationFrame(animate)
}
// 渲染
animate()
材质
// 添加材质
const material = new THREE.MeshBasicMaterial({
color: 0xffff0000 });
材质Api列表
MeshNormalMaterial | 法线网格材质 |
---|---|
MeshBasicMaterial | 基础网格材质 |
MeshLambertMaterial | Lambert网格材质 |
MeshPhongMaterial | Phong网格材质 |
MeshToonMaterial | 卡通网格材质 |
three.js 渲染步骤流程
- 生成几何体 -> 生成材质 -> 混合生成模型 -> 添加到场景中
- 场景操作 -> 生成场景(配置参数…) -> 模型导入场景
- 相机操作 -> 生成相机 -> 添加控制器(控制相机)
- 渲染器操作 -> 生成渲染器 -> 场景和相机添加到渲染器中 -> 建立和canvas 关联
- 更新模块(动画模块) -> 动画的连续 ,相机 ,场景的更新控制
实现一个简单的立方体
在main.js
中引入three.js
import * as THREE from "three"
创建一个场景
//创建场景
const scene = new THREE.Scene()
创建相机
这里采用 透视相机
// 创建相机
/*
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面
*/
// 透视相机
const camera = new THREE.PerspectiveCamera(
75, // 摄像机视锥体垂直视野角度,从视图的底部到顶部,以角度来表示。默认值是50。
window.innerWidth / window.innerHeight, // 摄像机视锥体的长宽比,通常是使用画布的宽/画布的高。默认值是1(正方形画布)。
0.1, // 摄像机的近端面,默认值是0.1。
1000 // 摄像机的远端面,默认值 2000
)
创建渲染器
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置大小
renderer.setSize(
1000, // 宽度
500 // 高度
);
//挂载到页面
document.body.appendChild(renderer.domElement)
添加立方体
// 添加物体
/*
width:立方体x轴的长度,
height:立方体y轴的长度,
depth:立方体z轴的长度也是深度
*/
let geometry = new THREE.BoxGeometry(10, 10, 10);
常见几何体
BoxGeometry | 立体矩形 |
---|---|
CircleGeometry | 圆 |
CylinderGeometry | 圆柱 |
ConeGeometry | 圆锥 |
DodecahedronGeometry | 十二面几何体(球) |
PlaneGeometry | 平面几何体 (重要)生成底面 |
RingGeometry | 平面圆环几何体 |
TorusGeometry | 圆环几何体 |
添加材质
// 添加材质
const material = new THREE.MeshBasicMaterial({
color: 0xffff0000 });
添加网格
// 添加网格
const cube = new THREE.Mesh( geometry, material );
// 将网格添加到场景中
scene.add( cube );
设置相机位置
因为相机的默认位置是(0, 0, 0),所以需要修改相机的位置,不然看不到我们创建的立方体
// 设置相机位置
camera.position.z = 50;
渲染到页面上
// 渲染
function animate() {
// 使用 requestAnimationFrame 执行动画
requestAnimationFrame(animate)
//scene:前面定义的场景,camera:前面定义的相机
//renderTarget:渲染的目标默认是是渲染到前面定义的render变量中
//forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
renderer.render(scene, camera)
}
// 渲染
animate()
此时此刻,我们的页面上就会出现一个红色的盒子
我们看到的是一个平面的,我们修改渲染函数,让他动起来并且看到他的完整样子。将渲染函数修改成如下样子
// 渲染
function animate() {
// 使用 requestAnimationFrame 执行动画
requestAnimationFrame(animate)
// 修改其旋转的度数,让其每次渲染增加0.01的弧段进行渲染
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
//scene:前面定义的场景,camera:前面定义的相机
//renderTarget:渲染的目标默认是是渲染到前面定义的render变量中
//forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
renderer.render(scene, camera)
}
requestAnimationFrame
是原生自带的实现动画用的,具体的可以看MDN
现在我们看到的就是一个会转的立方体
让我们来完善一下
- 把黑色背景给他改个颜色
- 并添加一个x,y,z坐标线
- 将6个面的颜色改成不一样的
修改场景背景颜色
// 修改场景背景颜色
scene.background = new THREE.Color(0xffffcc99)
添加x,y,z坐标线
// 添加 三色坐标轴
const axesHelper = new THREE.AxesHelper(20)
scene.add( axesHelper )
修改每个面的颜色。
我们将添加材质那一句修改为如下代码:
// 添加材质
// const material = new THREE.MeshBasicMaterial({ color: 0xffff0000 });
// 添加材质
const materials = []
for(let i = 0; i < 6; i++){
materials.push(new THREE.MeshBasicMaterial({
color: Math.random() * 0x00ff0000 }))
}
// 添加网格
const cube = new THREE.Mesh( geometry, materials );
scene.add( cube );
一个能够自己旋转的立方体我们就做好了。
下篇文章将使用controls
让我们可以通过鼠标、键盘控制我们的盒子模型。