最近学习Three.js,此贴供学习记录之用。
学习视频:Three.js教程。讲解很详细,也有配套的笔记,但不包含前端基础知识的讲解,如果是纯小白的朋友,可以找这位up之前的教程学习一下。
文章目录
类型化数组
有关类型化数组的详细介绍请看这里。
类型化数组将实现拆分为缓冲ArrayBuffer和视图DataView两部分,缓冲为具体数据,视图为数据格式,可对同一缓冲创建多个视图。
我的理解是缓冲像一盒水,视图就像是不同形状的冰块模具,过改变模具来得到不同形状的冰块。
模型对象的导出和引入
export default导出
export default导出:
- 1、本模块唯一默认对外接口,只能出现一次
2、只能先定义后导出
export default points;
- export default对应引入
export default对应引入:
- 1、引入不加花括号
2、引入变量可自定义名字
import points from './0621_1module.js';
export导出
export导出:
- 1、export可以有多个
2、可以各自分开导出,也可以多个同时导出
3、可以先定义后导出,也可以在定义的同时导出 如:export const…
4、可使用as进行导出重命名 如:export { mesh as box, … }
// 两种方法均可
export {line, lineLoop, lineSegments};
export {line as l1, lineLoop, lineSegments};
- export对应引入
export对应引入:
- 1、可以一次用*引入所有,也可以用{}引入任意数量
2、引入变量的名字不可以自定义
3、可使用as进行导入重命名 如:import { mesh as box, … } …
// 两种方法均可
import * as LINE from './0621_2module.js';
import { line } from './0621_2module.js';
- .html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>0621_1</title>
<style>
body{
overflow: hidden;
margin: 0;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports":{
"three": "./three.js/build/three.module.js",
"three/addons/": "./three.js/examples/jsm/"
}
}
</script>
<script src="./0621_1.js" type="module"></script>
</body>
</html>
一、点模型
- .js文件
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// export default引入模型对象
/* export default对应引入:
1、引入不加花括号
2、引入变量可自定义名字
*/
import points from './0621_1module.js';
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(100, 100, 100);
scene.add(axesHelper);
// 将点模型加入场景
scene.add(points);
// 光源设置
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(300, 300, 300);
scene.add(directionalLight);
const width = window.innerWidth;
const height = window.innerHeight;
// 相机设置
const camera = new THREE.PerspectiveCamera(30, width/height, 0.1, 3000);
camera.position.set(500, 500, 500);
scene.add(camera);
// 渲染设置
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
// 模型预览
const controls = new OrbitControls(camera, renderer.domElement);
// 渲染循环
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
- 创建缓冲几何体对象
// 创建缓冲几何体对象
const geometry = new THREE.BufferGeometry();
- 类型数组创建顶点类型数据
// 类型数组创建顶点类型数据
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
])
- 创建属性缓冲区对象
创建属性缓冲区对象可将类型数组分割为坐标表示(xyz轴)
// 创建属性缓冲区对象 将类型数组做具体分割
const attribute = new THREE.BufferAttribute(vertices, 3);
- 设置几何体位置
// 使用类型数组设置几何体对象的位置属性
geometry.attributes.position = attribute;
- 创建材质为点材质
const material = new THREE.PointsMaterial({
color: 0xff3e2e,
// 点对象像素尺寸
size: 10,
});
- 创建实体
// 创建点模型对象
const points = new THREE.Points(geometry, material);
- 模型导出
// 导出模型对象
/* export default导出:
1、本模块唯一默认对外接口,只能出现一次
2、只能先定义后导出
*/
export default points;
完整模型文件
// 引入three.js
import * as THREE from 'three';
// 创建一个几合体对象
const geometry = new THREE.BufferGeometry();
// 使用类型数组创建顶点类型数据
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
]);
// 创建属性缓冲区对象 将类型数组做具体分割
const attribute = new THREE.BufferAttribute(vertices, 3);
// 使用类型数组设置几何体对象的位置属性
geometry.attributes.position = attribute;
// 点渲染材质
const material = new THREE.PointsMaterial({
color: 0xff3e2e,
// 点对象像素尺寸
size: 10,
})
// 创建点模型对象
const points = new THREE.Points(geometry, material);
// 导出模型对象
/* export default导出:
1、本模块唯一默认对外接口,只能出现一次
2、只能先定义后导出
*/
export default points;
二、线模型
- .js文件
// js文件引入
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// export引入模型对象
/* export对应引入:
1、可以一次用*引入所有,也可以用{}引入任意数量
2、引入变量的名字不可以自定义
3、可使用as进行导入重命名 如:import { mesh as box, ... } ...
*/
import * as LINE from './0621_2module.js';
// import { line } from './0621_2module.js';
// 场景设置
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(100, 100, 100);
scene.add(axesHelper);
// 线模型对象加入场景
scene.add(LINE.line);
// 灯光设置
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(150, 150, 150);
scene.add(directionalLight);
const width = window.innerWidth;
const height = window.innerHeight;
// 相机设置
const camera = new THREE.PerspectiveCamera(35, width/height, 0.1, 3000);
camera.position.set(300, 300, 300);
scene.add(camera);
// 渲染设置
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.render(scene, camera);
// 插入页面
document.body.appendChild(renderer.domElement);
// 模型预览
const controls = new OrbitControls(camera, renderer.domElement);
// 渲染函数
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
// 窗口调节
window.onresize = function () {
renderer.setSize(window.innerWidth, window.innerHeight)
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
}
线模型对象有三种显示方法:
- 1、非闭合的连续线条
2、闭合的连续线条
3、顶点两两相接构成多个线条
- 创建缓冲几何体对象
const geometry = new THREE.BufferGeometry();
- 类型数组创建顶点类型数据
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
]);
- 创建属性缓冲区对象
const attribute = new THREE.BufferAttribute(vertices, 3);
- 设置几何体位置
geometry.attributes.position = attribute;
- 创建材质为线模型
const material = new LineBasicMaterial({
color: 0xff00ee,
// 线宽 默认为1
// linewidth: 100, // 由于OpenGL Core Profile与 大多数平台上WebGL渲染器的限制,无论如何设置该值,线宽始终为1
});
- 创建实体
// 创建线模型对象 一条连续的线
const line = new THREE.Line(geometry, material);
// 闭合线条 头尾相接
const lineLoop = new THREE.LineLoop(geometry, material);
// 非连续线条 两两相连
const lineSegments = new THREE.LineSegments(geometry, material);
- 模型导出
export { mesh };
完整模型文件
import * as THREE from 'three';
// 创建几何体对象
const geometry = new THREE.BufferGeometry();
// 使用类型数组创建顶点类型数据
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
]);
// 创建属性缓冲区对象 将类型数组做具体分割
const attribute = new THREE.BufferAttribute(vertices, 3);
// 使用类型数组设置几何体对象的位置属性
geometry.attributes.position = attribute;
// 线渲染材质
const material = new THREE.LineBasicMaterial({
color: 0xff00ee,
// 线宽 默认为1
// linewidth: 100, // 由于OpenGL Core Profile与 大多数平台上WebGL渲染器的限制,无论如何设置该值,线宽始终为1
});
// console.log(material.linewidth);
// 创建线模型对象 一条连续的线
const line = new THREE.Line(geometry, material);
// 闭合线条 头尾相接
const lineLoop = new THREE.LineLoop(geometry, material);
// 非连续线条 两两相连
const lineSegments = new THREE.LineSegments(geometry, material);
// 导出模型对象
/* export导出:
1、export可以有多个
2、可以各自分开导出,也可以多个同时导出
3、可以先定义后导出,也可以在定义的同时导出 如:export const...
4、可使用as进行导出重命名 如:export { mesh as box, ... }
*/
export {line, lineLoop, lineSegments};
三、网格模型
- 完整.js文件
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 导入.js文件
import { mesh1 } from './0628module1.js';
import { mesh2 } from './0628module2.js';
// 设置场景
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(100, 100, 200);
scene.add(axesHelper);
// 设置实体
scene.add(mesh1);
// scene.add(mesh2);
// 设置光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(150, 150, 150);
scene.add(directionalLight);
const width = window.innerWidth;
const height = window.innerHeight;
// 设置相机
const camera = new THREE.PerspectiveCamera(30, width/height, 0.1, 3000);
camera.position.set(250, 250, 250);
scene.add(camera);
// 设置渲染
const renderer = new THREE.WebGLRenderer({
antialias: true, // 设置锯齿消除
});
renderer.setSize(width, height);
renderer.render(scene, camera);
// 元素插入
document.body.appendChild(renderer.domElement);
// 渲染循环
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
// 模型预览
const controls = new OrbitControls(camera, renderer.domElement);
// 窗口大小调整
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight;
renderer.render(window.innerWidth, window.innerHeight);
camera.updateProjectionMatrix();
}
1、构建三角形
- 创建缓冲几何体对象
const geometry = new THREE.BufferGeometry();
- 类型数组创建顶点类型数据
const vertices = new Buffer32Array([ // 每三个点构成三角形,不足不构成三角形
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
]);
- 创建属性缓冲区对象
const attribute = new THREE.BufferAttribute(vertices, 3);
- 设置几何体位置
geometry.attributes.position = attribute;
- 创建材质对象
const material = new THREE.MeshBasicMaterial({
color: 0xee4758, // 这个颜色我喜欢
// 三角形逆时针为正面,顺时针为背面
side: THREE.FrontSide, // 默认 正面可见
side: THREE.BackSide, // 背面可见
side: THREE.DoubleSide, // 双面可见
});
- 创建网格模型
const mesh = new THREE.Mesh(geometry, matreial);
- 模型导出
export { mesh1 };
完整模型文件
import * as THREE from 'three';
// 创建几何体对象
const geometry = new THREE.BufferGeometry();
// 用类型数组创建顶点坐标
const vertices = new Float32Array([ // 每三个点构成三角形,不足不构成三角形
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
0, 0, 10, //顶点4坐标
0, 0, 100, //顶点5坐标
50, 0, 10, //顶点6坐标
]);
// 创建属性缓冲区对象,确定顶点
const attribute = new THREE.BufferAttribute(vertices, 3);
// 设置几何体attributes属性的位置属性
geometry.attributes.position = attribute;
// 创建材质对象
const material = new THREE.MeshBasicMaterial({
color: 0xee4758, // 这个颜色我喜欢
// 三角形逆时针为正面,顺时针为背面
side: THREE.FrontSide, // 默认 正面可见
side: THREE.BackSide, // 背面可见
side: THREE.DoubleSide, // 双面可见
})
// 创建实体对象
const mesh1 = new THREE.Mesh(geometry, material);
// 模型对象导出
export { mesh1 };
如果顶点不够三的倍数,未连成三角形的部分将不显示,下图是五个顶点的三角形模型
2、构建四边形
完整模型文件
import * as THREE from 'three';
// 创建几何体对象
const geometry = new THREE.BufferGeometry();
// 使用集合数组创建顶点坐标
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
50, 0, 0, //顶点2坐标
0, 100, 0, //顶点3坐标
50, 100, 0, //顶点4坐标
0, 100, 0, //顶点5坐标
50, 0, 0, //顶点6坐标
]);
// 创建属性缓冲区对象做顶点
const attribute = new THREE.BufferAttribute(vertices, 3);
// 设置几何体对象attributes属性的位置属性
geometry.attributes.position = attribute;
// 创建材质属性
const material = new THREE.MeshBasicMaterial({
color: 0xee4758,
side: THREE.FrontSide,
})
// 创建实体对象
const mesh2 = new THREE.Mesh(geometry, material);
// 模型对象导出
export { mesh2 };