文章目录
- 模型 = 几何体 + 材质
- 模型
- 点模型Points - 用于显示点
- 线模型Line | LineLoop | LineSegments
- 网格模型mesh - 三角形
- 几何体BufferGeometry
- 缓冲类型几何体BufferGeometry - 没有任何形状的空几何体
- 创建几何体的方式
- BufferAttribute Types
- 定义顶点法线 geometry.attributes.normal
- 材质 Material
- 点材质PointsMaterial - Points使用的默认材质
- 网格材质
- MeshLamberMaterial
- 高光网格材质 MeshPhongMaterial
模型 = 几何体 + 材质
注意点1:Three.js
的材质默认正面可见、背面不可见
解决办法:材质配置对象中设置side
属性
side取值 | 描述 |
---|---|
THREE.FrontSide | 只有正面可见 |
THREE.DoubleSide | 两面可见 |
THREE.BackSide | 设置只有背面可见 |
模型
点模型Points - 用于显示点
语法:new Points( geometry : BufferGeometry, material : Material )
- geometry 几何体对象(可选),
BufferGeometry
的实例,默认值是一个新的BufferGeometry
。 - material 材质对象(可选),默认值为
PointsMaterial
。
描述:一个用于显示点的类,将几何体geometry
渲染成点。
线模型Line | LineLoop | LineSegments
语法:new Line( geometry : BufferGeometry, material : Material )
- geometry 线段的顶点,默认值是一个新的
BufferGeometry
。 - material 线的材质,默认值是一个新的且随机颜色的
LineBasicMaterial
。
线模型 | 绘制线条的规则 |
---|---|
Line | 从第一个点开始到最后一个点,依次连成线 不闭合 |
LineLoop | 从第一个点开始到最后一个点,依次连成线,并将最后一个顶点连回第一个顶点 闭合 |
LineSegments | 从第一个点开始,第一个点连接第二个点,第三个点连接第四个点…有n个点,就有n/2条线 间断 |
网格模型mesh - 三角形
本质:一个一个三角形拼接
说明:几何体所有顶点坐标三个为一组,构成一个三角形,多组顶点构成多个三角形,用来模拟物体的表面。
三角形的正反面
三个点可以构成一个三角形,从第一个点往第三个点连接
- 正面:相机对着面,连接的顺序是逆时针
- 反面:相机对着面,连接的顺序是顺时针
几何体BufferGeometry
常见几何体可以看成是封装后的BufferGeometry
缓冲类型几何体BufferGeometry - 没有任何形状的空几何体
描述:BufferGeometry
是一个没有任何形状的空几何体,通过定义顶点数据将BufferGeometry
自定义为任何几何形状。每个几何体可以看作是由多个顶点构成的图案。
BufferGeometry实例的属性与方法
属性名/方法 | 描述 |
---|---|
index:BufferAttribute | 绑定几何体的顶点索引,每个三角形都绑定了三个顶点的索引。 允许顶点坐标在三角形中复用。 |
attributes : Object | 存储该几何体相关属性的hashmap (这里直接打印看不见里面的属性) 可以通过 几何体.setAttribute 和 几何体.getAttribute 添加和访问与当前几何体相关的属性。 |
BufferGeometry实例attributes的方法
属性名/方法 | 描述 |
---|---|
position:BufferAttribute | 绑定几何体的顶点坐标,每个顶点绑定三个坐标值(xyz) |
normal |
案例
1.使用 THREE.BufferGeometry
创建一个空的几何体对象
const geometry = new THREE.BufferGeometry();
2.利用Float32Array
定义顶点数据,使用属性缓冲区对象BufferAttribute
表示threejs
几何体顶点数据。
通过javascript类型化数组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坐标
]);
// 创建属性缓冲区对象,3个为一组,表示一个顶点的xyz坐标
const attribue = new THREE.BufferAttribute(vertices, 3);
3.设置几何体的定点.attributes.position
// 设置几何体attributes属性的位置属性
geometry.attributes.position = attribue;
4.渲染顶点
4.1使用点模型渲染顶点数据,会把几何体渲染为点,网格模型Mesh会把几何体渲染为面。
// 点渲染模式
const material = new THREE.PointsMaterial({
color: 0xffff00,
size: 10.0 //点对象像素尺寸
});
const points = new THREE.Points(geometry, material); //点模型对象
4.2使用线模型渲染顶点数据,从第一个点开始到最后一个点,依次连成线。
// 线材质对象
const material = new THREE.LineBasicMaterial({
color: 0xff0000 //线条颜色
});
// 创建线模型对象
const line = new THREE.Line(geometry, material);
4.3用网格模型渲染顶点
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide, //两面可见
});
创建几何体的方式
- 直接利用顶点数据,每一个点对应一个坐标
new Float32Array
构造坐标数组 | 32位的浮点数型数组THREE.BufferAttribute(坐标数组,3)
每三个坐标为一组,构建顶点坐标。顶点的个数等于组数- 赋值给
geometry.attributes.position
- 利用顶点索引,多个顶点可以利用同一个坐标
new Float32Array
构造坐标数组THREE.BufferAttribute(坐标数组,3)
每三个坐标为一组,构建顶点坐标。new Uint16Array
构造索引顶点数组,顶点的个数需要和索引的个数一样 | 16 位无符号整数geometry.index = new THREE.BufferAttribute(indexes, 1)
通过索引去坐标数组中取顶点坐标
案例: 构建一个矩形平面几何体 - 通过顶点数据
顶点坐标:一个矩形平面,可以至少通过两个三角形拼接而成。
三角形方向:两个三角形的正面需要保持一致
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坐标
]);
const attribue = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribue;
几何体顶点索引数据 - 通过顶点索引
在上述案例中,坐标4和坐标5其实是重复的坐标,重复的坐标可以复用吗?
// 删除重复的坐标
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标 | 索引0
80, 0, 0, //顶点2坐标 4坐标 | 索引1
80, 80, 0, //顶点3坐标 5坐标 | 索引2
0, 80, 0, //顶点6坐标 | 索引3
]);
// Uint16Array类型数组创建顶点索引数据
const indexs = new Uint16Array([
// 下面索引值对应顶点位置数据中的顶点坐标
0, 1, 2, 0, 2, 3,
])
// 索引数据赋值给几何体的index属性 1个为1组
geometry.index = new THREE.BufferAttribute(indexs, 1);
BufferAttribute Types
在 three.js
中一共有 9 种 BufferAttribute
,每种和 JavaScript 中的类型相对应Typed Arrays
。使用new创建BufferAttribute对象时,传入数组是什么内省,生成的BufferAttribute就是什么类型
BufferAttribute 类型 | 对应的JS数组类型 |
---|---|
THREE.Float64BufferAttribute | Float64Array |
THREE.Uint32BufferAttribute | Uint32Array |
THREE.Int32BufferAttribute | Int32Array |
THREE.Uint16BufferAttribute | Uint16Array |
THREE.Int16BufferAttribute | Int16Array |
THREE.Uint8ClampedBufferAttribute | Uint8ClampedArray |
THREE.Uint8BufferAttribute | Uint8Array |
THREE.Int8BufferAttribute | Int8Array |
定义顶点法线 geometry.attributes.normal
数学上法线的概念
一个平面,法线的就是改平面的垂线,如果是光滑曲面,一点的法线就是该点切面的法线。
Three.js中法线是通过顶点定义,默认情况下,每个顶点都有一个法线数据。
无顶点索引的使用方式
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
80, 0, 0, //顶点2坐标
80, 80, 0, //顶点3坐标
0, 0, 0, //顶点4坐标
80, 80, 0, //顶点5坐标
0, 80, 0, //顶点6坐标
]);
geometry.attributes.position =new THREE.BufferAttribute(vertices, 3);
const material = new THREE.MeshLambertMaterial({
color: 0xff0000, //线条颜色
side: THREE.DoubleSide
});
// 矩形平面,无索引,两个三角形,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);
有顶点索引的使用方式
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标 顶点4坐标
80, 0, 0, //顶点2坐标
80, 80, 0, //顶点3坐标 顶点5坐标
0, 80, 0, //顶点6坐标
]);
geometry.attributes.position =new THREE.BufferAttribute(vertices, 3);
// 矩形平面,有索引,两个三角形,有2个顶点重合,有4个顶点
// Uint16Array类型数组创建顶点索引数据
const indexs = new Uint16Array([
// 下面索引值对应顶点位置数据中的顶点坐标
0, 1, 2, 0, 2, 3,
])
geometry.index = new THREE.BufferAttribute(indexs, 1);
// 每个顶点的法线数据和顶点位置数据一一对应
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);
材质 Material
点材质PointsMaterial - Points使用的默认材质
语法:new PointsMaterial( parameters : Object )
实例的属性和方法
属性/方法 | 描述 |
---|---|
size:Number | 设置点的大小,默认值为1.0。 |
color:Color | 材质的颜色,默认值为白色 (0xffffff)。 |
网格材质
使用收光照影响的材质时,如果没有光照默认是黑色的(renderer画布设置了颜色可以看出)
MeshLamberMaterial
对光照的反射为漫反射
:光线向四周反射。
高光网格材质 MeshPhongMaterial
- 语法:
new MeshPhongMaterial( parameters : Object )
参数对象的属性 = 自有属性 + Material基类继承的属性 - 对光照的反射为
镜面反射
:想象一面镜子的反射,如果刚好反射光对眼睛,会非常刺眼(某个局部区域高亮,像擦了高光)
注意:AmbientLight环境光没有方向,整体改变场景的光照。所以只有环境光的,高光效果会失效。
MeshPhongMaterial高光网格材质配置参数的自有属性
属性名 | 属性描述 |
---|---|
shininess | 高亮的程度,越高的值越闪亮,默认30 |
specular | 高光颜色,默认为0x111111 灰色 |