前言
📫 大家好,我是南木元元,热衷分享有趣实用的文章,希望大家多多支持,一起进步!
🍅 个人主页:南木元元
目录
Three.js介绍
Three.js应用场景
搭建开发环境
初始化项目
创建文件
配置命令
启动服务
Three.js的一些重要概念
第一个3D场景
渲染器
3D场景的实现
1.创建三维场景
2.创建透视相机
3.创建渲染器
4.添加物体
5.定位相机
结语
Three.js介绍
讲到Three.js,就需要先说一下OpenGL和WebGL,OpenGL是一个跨平台的3D/2D的绘图标准,WebGL是一种3D绘图协议,它允许把JavaScript和OpenGL 结合在一起运用,但使用WebGL原生的API来写3D程序非常的复杂,对于前端开发者来说学习成本非常高。
Three.js是WebGL的JavaScript 3D库,其对WebGL提供的接口进行了非常好的封装,简化了很多细节,大大降低了学习成本,让开发者能更快速的进行3D场景效果的开发。
简单来说,Three.js就是能够实现3D效果的JS库。
官网:Three.js – JavaScript 3D Library
WebGL、OpenGL、Three.js三者的关系:
WebGL:OpenGL + JavaScriptThree.js:一个基于WebGL封装的库Three.js应用场景
three.js应用广泛,在小游戏、产品展示、物联网、智慧城市、机械、建筑、GIS等各个领域基本上都有three.js的身影。
微信小游戏
智慧城市
智慧小区
数字孪生
全景看房
机械领域
GIS
搭建开发环境
本文使用vite来搭建three.js的开发环境,当然你也可以使用webpack等其他打包工具。
初始化项目
创建vite-three目录并执行npm init -y
,初始化 package.json。
npm init -y
安装vite:
npm i vite -D
安装three.js:
npm i three
此时的项目目录如下:
创建文件
创建src目录,src下新建main.js文件,根目录创建index.html,作为vite的入口文件。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vite-three</title> <style> body { margin: 0; } </style></head><body> <!-- 使用模块化方式引入文件 --> <script src="./src/main.js" type="module"></script></body></html>
上述引入js时加上了type="module",代表使用模块化的方式引入,因为main.js中会使用到import模块化语法。main.js文件如下:
import * as THREE from "three";console.log(THREE);
配置命令
在package.json中配置如下命令:
"scripts": { "dev": "vite --open", "build": "vite build", "preview": "vite preview"}
启动服务
终端输入npm run dev,启动开发服务:
npm run dev
在浏览器控制台看到如下信息,就代表Three.js已经成功引入。
Three.js的一些重要概念
在Three.js中,我们需要先理解一些比较重要的概念:
场景:场景就是一个三维的世界,在这个世界中可以放置各种各样的物体。相机:三维空间的观察者,通过相机来查看场景。物体:被观察的对象,不同的物体形状、大小、材质、纹理不同。光源:物体表面的明暗效果会受光照影响,为了更好的模拟三维效果,需要一些光照和阴影。这里需要重点说下相机。
相机分为两种:透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。
Three.js最常使用的是透视相机,它模拟了人眼观察世界的规律:物体近大远小。
// 透视相机参数const fov = 45; const aspect = window.innerWidth / window.innerHeight;const near = 1; const far = 1000; // 创建一个透视相机const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
透视相机有四个构造参数:
fov(视野):相机的视野有多宽,以度为单位。aspect(纵横比):场景的宽度与高度的比率。near(近剪裁平面):任何比这更靠近相机的东西都是不可见的。far(远剪裁平面):任何比这更远离相机的东西都是不可见的。这四个参数构成一个有边界的空间区域,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示。
第一个3D场景
创建一个场景,需要3个对象:场景(scene)、相机(camera)、渲染器(renderer),这样就能通过摄像机渲染出场景。
渲染器
场景和相机我们都已经介绍过了,那什么是渲染器呢?
渲染器(Renderer):从相机的角度去渲染场景,负责将场景绘制到
<canvas>
元素中。
three.js的整个工作机制如下图所示:
将可见对象如网格(mesh)添加到场景(scene)中,然后将需要渲染的数据传递给渲染器(renderer),渲染器负责将场景在 <canvas>
画布上绘制出来。了解了这些,接下来我们就来绘制three.js的第一个3D场景。
3D场景的实现
1.创建三维场景
首先,创建场景,作为我们能看到的一切的载体。
const scene = new THREE.Scene();
2.创建透视相机
创建透视相机,设置相机参数。
// 透视相机参数const fov = 45; const aspect = window.innerWidth / window.innerHeight;const near = 1; const far = 1000; // 创建一个透视相机const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
3.创建渲染器
创建渲染器,并执行render渲染操作。
// 创建渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 渲染renderer.render(scene, camera);
4.添加物体
在three.js
中,使用Mesh
网格表示一个物体,网格包含几何体(Geometry)和材质(Material)。
创建一个立方体,添加到场景中。
// 创建立方体(几何+材质)const geometry = new THREE.BoxGeometry(100, 100, 100);const material = new THREE.MeshNormalMaterial();const mesh = new THREE.Mesh(geometry, material);// 添加到场景scene.add(mesh);
上述代码,创建了长宽高均为100个单位的立方体,使用法向量材质MeshNormalMaterial,然后
基于几何形状和材质创建立方体,最后添加到场景中。
5.定位相机
完成上述步骤后,你却会发现此时的屏幕上是一片黑暗,什么也看不到。
这是因为我们创建的相机和物体最初都位于场景的中心(0, 0, 0),并且相机也默认看向(0, 0, 0)这个点,所以透视相机不会渲染内容。我们只需移动一下相机位置就可以了。
// 定位相机camera.position.set(200, 300, 200); //设置相机位置camera.lookAt(0, 0, 0); //设置相机方向
效果:
完整代码:
import * as THREE from "three";// 创建场景const scene = new THREE.Scene();// 创建透视相机const fov = 45;const aspect = window.innerWidth / window.innerHeight;const near = 1;const far = 1000;const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);// 定位相机camera.position.set(200, 300, 200); camera.lookAt(0, 0, 0); // 创建立方体(几何+材质)const geometry = new THREE.BoxGeometry(100, 100, 100);const material = new THREE.MeshNormalMaterial();const mesh = new THREE.Mesh(geometry, material);// 添加到场景scene.add(mesh);// 创建渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 渲染renderer.render(scene, camera);
结语
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~