Three.js(three入门)

2,653 阅读6分钟

Three.js学习指南:在响应式世界里玩转三维魔法

🌟 第一章:Three.js突破次元壁指南

Three.js简介

three.js官网:threejs.org/
three.js中文官网threejs.org/docs/index.…

1.什么是Three.js?

Three.js是用JavaScript编写的一个第三方库,用于实现很多的3D功能,它是基于WebGL进行封装的。而WebGL又是由OpenGL ES2.0+Javascript进行封装的,而OpenGLES 2.0又是OpenGL 三维图形 API 的一个子集,而OpenGL是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。

1.1 为什么选择Three.js?

一句话定义:​
Three.js就是给浏览器装上「三维显卡」的黑科技!它让JavaScript具备了在网页里创造《头号玩家》级别虚拟世界的能力。

技术栈套娃指南:​

graph LR
    A[OpenGL] --> B(OpenGL ES)
    B --> C(WebGL)
    C --> D(Three.js)
    D --> E{{你的浏览器}}

为什么选择Three.js?

  • 开发效率:原生WebGL写立方体要200行代码,Three.js只要20行!
  • 生态丰富:10万+星星的GitHub仓库,从恐龙模型到黑洞特效应有尽有
  • 跨平台:手机/电脑/VR眼镜,打开浏览器就能跑

2. 下载部署Three本地服务

为什么要安装?首先three本身是一个库,官方提供了调试预览案例编辑器
众所周知国内经常访问不到github,网速差也是通病,那么下载一个本地服务就很有必要了
GitHub仓库地址:github.com/mrdoob/thre…
本地启动即可

3.项目的开发环境引入threejs

比如你采用的是Vue + threejsReact + threejs技术栈,这很简单,threejs就是一个js库,直接通过npm命令行安装就行。

// 比如安装172版本  更新了这么多年还是0.都不算一个大版本😂
npm install three@0.172.0 --save

npm安装后,如何引入three.js

执行import * as THREE from 'three',ES6语法引入three.js核心 (都开始学three了默认会es6哦)。

// 引入three.js
import * as THREE from 'three';

4.第一个3D案例—创建3D场景

1) 三维场景Scene

你可以把三维场景Scene (opens new window)对象理解为虚拟的3D场景,用来表示模拟生活中的真实三维场景,或者说三维世界。

// 创建3D场景对象Scene
const scene = new THREE.Scene();
2) 物体形状:几何体Geometry

Three.js提供了各种各样的几何体API,用来表示三维物体的几何形状。

Snipaste_2025-01-07_17-26-56.png

//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(1, 1, 1)
3) 物体外观:材质Material

如果你想定义物体的外观效果,比如颜色,就需要通过材质Material相关的API实现。

threejs不同材质渲染效果不同,下面就以threejs最简单的网格基础材质MeshBasicMaterial (opens new window)

// 创建材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })

Snipaste_2025-01-07_17-13-35.png

4) 物体:网格模型Mesh

实际生活中有各种各样的物体,在threejs中可以通过网格模型Mesh (opens new window)表示一个虚拟的物体,比如一个箱子、一个鼠标。

// 两个参数分别为几何体geometry、材质material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
5) 模型位置.position

实际生活中,一个物体往往是有位置的,对于threejs而言也是一样的,你可以通过位置属性.position定义网格模型Mesh在三维场景Scene中的位置。

const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
//设置网格模型在三维空间中的位置坐标,默认是坐标原点
mesh.position.set(0,10,0);
6) 透视投影相机PerspectiveCamera

Threejs提供了正投影相机OrthographicCamera (opens new window)和透视投影相机PerspectiveCamera (opens new window)常用的透视投影相机PerspectiveCamera。 透视投影相机PerspectiveCamera本质上就是在模拟人眼观察这个世界的规律。

// 实例化一个透视投影相机对象
const camera = new THREE.PerspectiveCamera(
    45, //视角
    window.innerWidth / window.innerHeight, //宽高比
    0.1, //近平面
    1000 //远平面
)
8) 相机观察目标.lookAt()

你用相机拍照你需要控制相机的拍照目标,具体说相机镜头对准哪个物体或说哪个坐标。对于threejs相机而言,就是设置.lookAt()方法的参数,指定一个3D坐标。

// 设置相机位置
camera.position.z = 5
camera.lookAt(0, 0, 0) //原点
9) WebGL渲染器WebGLRenderer
// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
// 设置Canvas画布尺寸`.setSize()`
renderer.setSize(window.innerWidth, window.innerHeight)
10) 渲染器Canvas画布属性.domElement

渲染器WebGLRenderer通过属性.domElement可以获得渲染方法.render()生成的Canvas画布,.domElement本质上就是一个HTML元素:Canvas画布。

document.body.appendChild(renderer.domElement);
11)渲染器渲染方法.render()
renderer.render(scene, camera); //执行渲染操作
12).add()方法

在threejs中你创建了一个表示物体的虚拟对象Mesh,需要通过.add()方法,把网格模型mesh添加到三维场景scene中。

scene.add(mesh); 
13) 第一个融合案例:会跳舞的Vue立方体
🔮 套娃警告!Three.js的俄罗斯套娃式家谱
  • Three.js:"我是WebGL的贴心小棉袄,专治原生API的996福报"
  • WebGL:"OpenGL ES你别嘚瑟,看我JS附体变身浏览器特供版"
  • OpenGL:"三维图形界的AK47,从诺基亚贪吃蛇到赛博朋克都能突突"
    (👉 附技术栈关系图:Three.js→WebGL→OpenGL ES→OpenGL
🎮 手把手教学:5分钟召唤旋转の绿魔方
// 超能力三件套:场景+相机+渲染器(比灭霸手套少3个宝石)
const 舞台 = new THREE.Scene();  // 空荡荡的元宇宙地块
const 导演镜头 = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); // 第4个参数叫"视奸距离"
const 魔法画布 = new THREE.WebGLRenderer(); // 比达芬奇还牛的动态画布

// 创世代码:绿魔方的诞生(颜色值16进制是程序员的浪漫)
const 魔方 = new THREE.Mesh(
  new THREE.BoxGeometry(1,1,1), // 谁说方块不能当主角?
  new THREE.MeshBasicMaterial({ color: 0x00FF00 }) // 要想生活过得去...
);
魔方.position.set(0,0,0); // 中心点坐标,学不会的建议背诵全文

// 导演说Action!
导演镜头.position.z = 5;    // 悄悄后撤步
魔法画布.setSize(window.innerWidth, window.innerHeight); // 全屏警告
document.body.appendChild(魔法画布.domElement); // 给浏览器来点小小的三维震撼

// 旋转吧!小方块!(帧动画比德芙还丝滑)
function 宇宙大爆炸() {
  requestAnimationFrame(宇宙大爆炸);
  魔方.rotation.x += 0.01; // 转太快会晕3D的亲
  魔方.rotation.y += 0.01; 
  魔法画布.render(舞台, 导演镜头);
}
宇宙大爆炸();
// 导入threejs
import * as THREE from 'three'
// 创建场景
const scene = new THREE.Scene()
// 创建相机
const camera = new THREE.PerspectiveCamera(
    45, //视角
    window.innerWidth / window.innerHeight, //宽高比
    0.1, //近平面
    1000 //远平面
)
// 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const geometry = new THREE.BoxGeometry(1, 1, 1)
// 创建材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
// 创建网络
const cube = new THREE.Mesh(geometry, material)
// 网络添加到场景
scene.add(cube)
// 设置相机位置
camera.position.z = 5
camera.lookAt(0, 0, 0) //原点

// 渲染函数
;(function animate() {
    requestAnimationFrame(animate)
    // 旋转
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01
    renderer.render(scene, camera)
})()