三维空间中绘制点、线、⾯、UV贴图,万能的BufferGeometry(three.js实战起凡三国争霸
4)
使⽤BufferGeometry
1. 序⾔
three.js 中提供了⼀系列绘制⼏何体的类,如BoxGeometry、SphereGeometry,PlaneGeometry、CircleGeometry、CylinderGeometry 等,使⽤这些类,可以快速创建对应的⼏何体,three.js同时提供了对应的 BoxBufferGeometry、SphereBufferGeometry,PlaneBufferGeometry、CircleBufferGeometry、CylinderBufferGeometry等直接使⽤缓存的构建⼏何体的 xxxBufferGeometry 类簇,这些类簇相⽐于 xxxGeometry 类簇,可以有效减少向 GPU 传输数据所需的开销,极⼤提⾼效率,但如果提供的这些⼏何都不能满⾜需求怎么办,这时就需要⽤到万能的 BufferGeometry ,通过它可以向缓存中传输⼏何体的顶点坐标、⾯索引、顶点颜⾊、顶点法向量、顶点UV甚⾄是⾃定义属性, 使⽤⾃定义属性和着⾊器材质配合使⽤强⼤到⽆所不能
这⾥顺便说说ShaderMaterial-着⾊器材质和RawShaderMaterial-原始着⾊器材质,它们都⽀持GLSL语⾔编写的shader,不同之处是ShaderMaterial会把three.js内置attributes和uniforms⼀起传给shader,⽽RawShaderMaterial 不会 向shader中传递任何内置属性
2. 如何使⽤BufferGeometry
2.1 创建BufferGeometry对象
传怎么组词创建BufferGeometry对象与创建其他THREE对象⼀样,⾮常简单,如下
const bufferGeom =new THREE.BufferGeometry();
2.2 向BufferGeometry对象添加属性
这⼀步其实就是初始化绘制⼏何体所需的顶点坐标、⾯索引、顶点颜⾊、顶点法向量、顶点UV等信息,这些属性three.js都是内置属性,属性名已定死,例如:position,color,normal,index等
这⼀步可向BufferGeometry对象添加任意属性,我们以position属性和index为例说明⼀下
添加position属性
⾸先通过Float32Array类创建序列化数组,⽰例中是每3个数构成⼀个点,然后使⽤BufferAttribute类创建于BufferGeometry对象关联的存储缓存,最后使⽤tAttribute⽅法关联缓存,⽰例代码如下
//初始化存放顶点信息的序列化数组
风干鱼怎么做好吃const positions =new Float32Array([
-5.0,3.0,0.0,//point0
5.0,3.0,0.0,//point1
6.0,-3.0,0.0,//point2
-6.0,-3.0,0.0//point3
]);
//设置顶点信息,第⼆个参数3表⽰三个数确定⼀个顶点
bufferGeom.tAttribute('position',new THREE.BufferAttribute(positions,3));
1999年是什么命其他⼀些相关的属性color,normal等以及⾃定义属性的添加都可以参数以上⽅式
添加index属性
index 属性与其他属性添加有⼀些不⼀样,序列化数组的类型是Uint16Array,不是通过tAttribute设
置属性,⽽是直接设置到BufferGeometry实例的index属性下,使⽤BufferAttribute创建缓存数据是第⼆个参数为1,代表⼀个数就是⼀个索引信息
如何成为一个学霸const indexs =new Uint16Array([
0,1,2,
3,0
]);
海宁三扣//设置画⾯的索引
bufferGeom.index =new THREE.BufferAttribute(indexs,1);
2.3 创建Mesh
创建mesh需要两个参数⼀个⼏何体⼀个材质,⼏何体通过上述两步创建,创建材质时,如果设置的顶点颜⾊属性,且需要使⽤⾃定义的也是着⾊,要将材质的vertexColors属性设置为 THREE.VertexColors。表⽰使⽤缓存中的颜⾊着⾊
/
/创建材质
const material =new THREE.MeshBasicMaterial({
vertexColors:THREE.VertexColors,//使⽤缓存中的颜⾊
side:THREE.DoubleSide
});
const mesh =new THREE.Mesh(bufferGeom, material);
3. BufferGeometry使⽤⽰例
3.1 绘制点
申请qq号码⾸先创建BufferGeometry实例,然后创建存放顶信息的序列化数组,接着设置position属性,最后创建PointsMaterial材质并使⽤该材质创建Points对象,就可以完成点的绘制
function drawPointByBufferGeometry(){
//创建BufferGeometry实例
const bufferGeom =new THREE.BufferGeometry();
//初始化存放顶点信息的序列化数组
const positions =new Float32Array([
-5.0,3.0,0.0,//point0
5.0,3.0,0.0,//point1
6.0,-3.0,0.0,//point2
-6.0,-3.0,0.0//point3
]);
//设置顶点信息
bufferGeom.tAttribute('position',new THREE.BufferAttribute(positions,3));
//创建点材质
const material =new THREE.PointsMaterial({
color:'red',
size:2
});
const mesh =new THREE.Points(bufferGeom, material);
scene.add(mesh);
}
绘制效果如下:
3.2 绘制线
创建BufferGeometry实例
使⽤ new THREE.BufferGeometry() 创建bufferGeom实例
设置position,color,index属性
position,color属性设置与之前的⼀样,请注意设置index属性时,index序列化数组的值为0, 1, 2, 3, 0 最终还要回到原点否则最后⼀条线⽆法绘制
创建Mesh
这⾥使⽤LineBasicMaterial创建材质,同样将材质的vertexColors属性设置为 THREE.VertexColors。表⽰使⽤缓存中的颜⾊着⾊,并使⽤Line创建线
function drawLineByBufferGeometry(){
//创建BufferGeometry实例
const bufferGeom =new THREE.BufferGeometry();
//初始化存放顶点信息的序列化数组
const positions =new Float32Array([
-5.0,3.0,0.0,//point0
5.0,3.0,0.0,//point1
6.0,-3.0,0.0,//point2
-6.0,-3.0,0.0//point3
]);
//设置顶点信息
bufferGeom.tAttribute('position',new THREE.BufferAttribute(positions,3)); //初始化存放颜⾊信息的序列化数组
const colors =new Float32Array([
1.0,0.0,0.0,
0.0,1.0,0.0,
0.0,0.0,1.0,
0.0,0.5,0.5
]);
//设置颜⾊信息
bufferGeom.tAttribute('color',new THREE.BufferAttribute(colors,3));
const indexs =new Uint16Array([
0,1,2,
3,0
]);
//设置画⾯的索引
bufferGeom.index =new THREE.BufferAttribute(indexs,1);
//创建材质
const material =new THREE.LineBasicMaterial({
vertexColors:THREE.VertexColors,//使⽤缓存中的颜⾊
side:THREE.DoubleSide
酒店厨房});
const mesh =new THREE.Line(bufferGeom, material);
scene.add(mesh);
}
绘制的结果如上如,会发现绘制的线和使⽤WebGL绘制线⼀样。会根据顶点颜⾊作插值计算
3.3 绘制⾯
创建BufferGeometry实例
使⽤ new THREE.BufferGeometry() 创建bufferGeom实例
设置position,color,index属性
position,color属性设置与之前的⼀样,需要注意的是设置index属性时,index序列化数组的值为0, 1, 2, 0, 2, 3 表⽰使⽤索引为0,1,2的点绘制⼀个三⾓⾯和使⽤索引为0,2,3的点绘制另⼀个三⾓⾯
创建Mesh
使⽤MeshBasicMaterial创建材质,也需要将材质的vertexColors属性设置为 THREE.VertexColors。表⽰使⽤缓存中的颜⾊着⾊,然后创建Mesh对象