javascriptthree.js

TypeError: THREE.BufferAttribute: array should be a Typed Array


I am trying to create a point cloud in threejs as:

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 );

But this gives error(at line annotated above):

TypeError: THREE.BufferAttribute: array should be a Typed Array.

'vertices' is initialized, so I guess it's typed, isn't?


Solution

  • Judging by the documentation, the array parameter must be a TypedArray. So if you're working with Vector3 vertices, you may consider using Float32Array.

    The TypedArray must be flat, and the itemSize parameter indicates the size of each component (Vector3 which is 3). So the first vertex would be [vertices[0], vertices[1], vertices[2]] and the second vertex is [vertices[3], vertices[4], vertices[5]] so on and so forth. Something like this should work:

    const pcGeom = new THREE.BufferGeometry();
    const rows = 100;
    const columns = 3;
    const vertices = new Float32Array(rows * columns);
    for(let i = 0; i < rows; i++) {
      for (let j = 0; j < columns; j++) {
         vertices[i * columns + j] = Math.random() * (2 - 0) + 0;
      }
    }
    pcGeom.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
    const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
    const pointCloud = new THREE.Mesh( pcGeom, material );