友情链接:threejs 中文文档
目录
(3) 设置几何体顶点.attributes.position
(2) BufferAttribute定义顶点索引.index数据
1. 几何体顶点数据和点模型
(1) 缓冲类型几何体 BufferGeometry
threejs的长方体BoxGeometry、球体SphereGeometry等几何体都是基于BufferGeometry (opens new window)类构建的,BufferGeometry是一个没有任何形状的空几何体,你可以通过BufferGeometry自定义任何几何形状,具体一点说就是定义顶点数据。
//创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();
(2) BufferAttribute定义几何体顶点数据
通过javascript类型化数组 (opens new window)Float32Array创建一组xyz坐标数据用来表示几何体的顶点坐标。
//类型化数组创建顶点数据
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坐标
]);
通过threejs的属性缓冲区对象BufferAttribute (opens new window)表示threejs几何体顶点数据。
// 创建属性缓冲区对象
//3个为一组,表示一个顶点的xyz坐标
const attribue = new THREE.BufferAttribute(vertices, 3);
(3) 设置几何体顶点.attributes.position
通过geometry.attributes.position设置几何体顶点位置属性的值BufferAttribute。
// 设置几何体attributes属性的位置属性
geometry.attributes.position = attribue;
(4) 点模型Points
点模型Points和网格模型Mesh一样,都是threejs的一种模型对象,只是大部分情况下都是用Mesh表示物体。
网格模型Mesh有自己对应的网格材质,同样点模型Points有自己对应的点材质PointsMaterial
// 点渲染模式
const material = new THREE.PointsMaterial({
color: 0xffff00,
size: 10.0 //点对象像素尺寸
});
几何体geometry作为点模型Points参数,会把几何体渲染为点,把几何体作为Mesh的参数会把几何体渲染为面。
const points = new THREE.Points(geometry, material); //点模型对象
2. 线模型对象
(1) 线模型对象渲染数据
下面代码是以上节内容为基础,把几何体作换为线模型Line的参数,你会发现渲染效果是从第一个点开始到最后一个点,依次连成线。
// 线材质对象
const material = new THREE.LineBasicMaterial({
color: 0xff0000 //线条颜色
});
// 创建线模型对象
const line = new THREE.Line(geometry, material);
(2) 线模型LineLoop、LineSegments
threejs线模型除了Line,还提供了LineLoop (opens new window)、LineSegments (opens new window),区别在于绘制线条的规则不同。
// 闭合线条
const line = new THREE.LineLoop(geometry, material);
//非连续的线条
const line = new THREE.LineSegments(geometry, material);
3. 网格模型(三角形概念)
网格模型mesh原理是由n个三角形拼接构成,使用使用网格模型Mesh渲染几何体geometry,就是几何体所有顶点坐标三个为一组,构成一个三角形,多组顶点构成多个三角形,就可以用来模拟表示物体的表面。
网格模型有着正反面之分,默认的情况的下一个三角形只会显示它的正面,threejs的正反面是根据三角形坐标点渲染的顺序来区分的,如果三个点的顺序为顺时针,则为正面,反之则为背面也可以通过设置材质的属性来规定那一面可见
const material = new THREE.MeshBasicMaterial({
color: 0x0000ff, //材质颜色
side: THREE.FrontSide, //只有正面可见
});
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide, //两面可见
});
const material = new THREE.MeshBasicMaterial({
side: THREE.BackSide, //设置只有背面可见
});
4. 几何体顶点索引数据
网格模型Mesh对应的几何体BufferGeometry,拆分为多个三角后,很多三角形重合的顶点位置坐标是相同的,这时候如果你想减少顶点坐标数据量,可以借助几何体顶点索引geometry.index
来实现。
(1) 定义顶点位置坐标数据
每个三角形3个顶点坐标,矩形平面可以拆分为两个三角形,也就是6个顶点坐标
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
80, 0, 0, //顶点2坐标
80, 80, 0, //顶点3坐标
0, 0, 0, //顶点4坐标 和顶点1位置相同
80, 80, 0, //顶点5坐标 和顶点3位置相同
0, 80, 0, //顶点6坐标
]);
(2) BufferAttribute定义顶点索引.index数据
通过javascript类型化数组Uint16Array创建顶点索引.index数据。
// Uint16Array类型数组创建顶点索引数据
const indexes = new Uint16Array([
// 下面索引值对应顶点位置数据中的顶点坐标
0, 1, 2, 0, 2, 3,
])
通过threejs的属性缓冲区对象BufferAttribute表示几何体顶点索引.index数据。
// 索引数据赋值给几何体的index属性
geometry.index = new THREE.BufferAttribute(indexes, 1); //1个为一组
5. 顶点法线数据
当材质由MeshBasicMaterial材质改为MeshLambertMaterial这种受光照影响的材质,会发现原来的矩形平面无法渲染。原因就是使用了受光照影响的材质,几何体BufferGeometry需要定义顶点法线数据。
(1) 数学上法线概念
先来理解一下数学上的法线概念,比如一个平面,法线的就是改平面的垂线,如果是光滑曲面,一点的法线就是该点切面的法线。
(2) 矩形平面几何体法线案例——无顶点索引
Three.js中法线是通过顶点定义,默认情况下,每个顶点都有一个法线数据,就像每一个顶点都有一个位置数据。
// 矩形平面,无索引,两个三角形,6个顶点
// 每个顶点的法线数据和顶点位置数据一一对应
const normals = new Float32Array([
0, 0, 1, //顶点1法线( 法向量 )
0, 0, 1, //顶点2法线
0, 0, 1, //顶点3法线
0, 0, 1, //顶点4法线
0, 0, 1, //顶点5法线
0, 0, 1, //顶点6法线
]);
// 设置几何体的顶点法线属性.attributes.normal
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3);
(3) 矩形平面几何体法线案例——有顶点索引
// 矩形平面,有索引,两个三角形,有2个顶点重合,有4个顶点
// 每个顶点的法线数据和顶点位置数据一一对应
const normals = new Float32Array([
0, 0, 1, //顶点1法线( 法向量 )
0, 0, 1, //顶点2法线
0, 0, 1, //顶点3法线
0, 0, 1, //顶点4法线
]);
// 设置几何体的顶点法线属性.attributes.normal
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3);
6. 旋转、缩放、平移几何体
BufferGeometry通过.scale()、.translate()、.rotateX()、.rotateY()等方法可以对几何体本身进行缩放、平移、旋转,这些方法本质上都是改变几何体的顶点数据。
// 几何体xyz三个方向都放大2倍
geometry.scale(2, 2, 2);
// 几何体沿着x轴平移50
geometry.translate(50, 0, 0);
// 几何体绕着x轴旋转45度
geometry.rotateX(Math.PI / 4);
文章中部分素材选取自Threejs中文网:Three.js中文网