Three.js创建点云报错:THREE.BufferAttribute需传入类型化数组
问题
我尝试使用以下代码在Three.js中创建点云:
const pcGeom = new THREE.BufferGeometry(); const rows = 100; const columns = 3; const vertices = [...Array(rows)].map(() => [...Array(columns)].fill(0)); for(let i = 0; i < rows; i++) { for (let j = 0; j < columns; j++) { vertices[i][j] = Math.random() * (2 - 0) + 0; } } pcGeom.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); // error at this line const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); const pointCloud = new THREE.Mesh( geometry, material );
但在标注的代码行出现错误:
TypeError: THREE.BufferAttribute: array should be a Typed Array.
我已经初始化了vertices,为何它不是类型化数组?
解答
问题原因:你当前的
vertices是二维普通数组(Array<Array<number>>),而Three.js的BufferAttribute要求必须传入类型化数组(如Float32Array、Uint16Array这类),普通数组不符合要求。修复方案:
- 先将二维数组扁平化为一维普通数组,再转换为
Float32Array类型化数组:// 把二维数组转为一维数组 const flatVertices = vertices.flat(); // 转换为Float32Array类型化数组 const typedVertices = new Float32Array(flatVertices); // 传入BufferAttribute pcGeom.setAttribute('position', new THREE.BufferAttribute(typedVertices, 3)); - 额外修正:创建点云需用
THREE.Points而非THREE.Mesh,材质要使用PointsMaterial替代MeshBasicMaterial,否则无法正确显示点云:const material = new THREE.PointsMaterial({ color: 0xff0000, size: 0.1 }); const pointCloud = new THREE.Points(pcGeom, material);
- 先将二维数组扁平化为一维普通数组,再转换为
优化写法:可以直接初始化类型化数组,省去普通数组转类型化数组的开销:
const pcGeom = new THREE.BufferGeometry(); const pointCount = 100; const vertices = new Float32Array(pointCount * 3); for (let i = 0; i < pointCount * 3; i++) { vertices[i] = Math.random() * 2; } pcGeom.setAttribute('position', new THREE.BufferAttribute(vertices, 3)); const material = new THREE.PointsMaterial({ color: 0xff0000, size: 0.1 }); const pointCloud = new THREE.Points(pcGeom, material);
内容的提问来源于stack exchange,提问作者Mandroid
相关产品推荐
相关产品推荐

