Getting data from GPU

Greetings !

I am working on Attractors extension to Rebelle painting software based on this canonical example but can’t fetch particles coordinates from GPU buffer.

At preset time I am stacked with a following attempt (finalData has 0 length):

async function animate() {
  await renderer.compute( updateCompute );

  const storageAttribute = new THREE.StorageBufferAttribute(new Float32Array(count), 3);
  const resultBuffer = await renderer.getArrayBufferAsync(storageAttribute);
  const finalData = new Float32Array(resultBuffer);
  console.log(finalData);

  renderer.render( scene, camera );
}

Probably the reason explained by the following console message: “WebGPU is not available, running under WebGL2 backend”, but getting positions from GPU buffer still a mystery.

Help me to solve this puzzle, please !

const storageAttribute = new THREE.StorageBufferAttribute(new Float32Array(count), 3);

Is “count” defined somewhere in scope where it can be accessed?

Thanks for reply, yes it defined globally and script works as expected, excluding data fetching to CPU space.

Oh ok. One possible problem that I can think of is that the instance of the storage buffer does not persist because of the animation loop. So somehow on re-render, the data never actually gets created and finalData just returns 0.

Can you try confirming what console.log(resultBuffer.byteLenght) returns?

Thanks for attention to my problem.

console.log(resultBuffer.byteLenght) returns undefined

Also I found the following message (sorry for not to mentioning it earlier):

WebGL: INVALID_OPERATION: getBufferSubData: no buffer

Yh, thanks for the extra detail there, that confirms my suspicion. Try defining storageAttribute before the animate function and let me know what the console.log says this time.

const storageAttribute = new THREE.StorageBufferAttribute(new Float32Array(count), 3);

async function animate() {
  await renderer.compute( updateCompute );
  const resultBuffer = await renderer.getArrayBufferAsync(storageAttribute);
  console.log(resultBuffer.byteLenght)
  renderer.render( scene, camera );
}

Unfortunately result is the same: undefined.

Try with byteLength instead of byteLenght

Ohh, sorry, silly me !
Now it’s ‘0’.

Lol, it happens.
Can you please confirm that the value of count itself is not “0”? If all this is in place then I think a next debugging step is making sure storageAttribute is wrapped in a tsl storageNode and that node is what’s being passed. Something like:

//above the animate function
const storageAttribute = new THREE.StorageBufferAttribute(new Float32Array(count), 3);

const storageNode = storage(storageAttribute, 'vec3', count);

//then inside the function
const resultBuffer = await renderer.getArrayBufferAsync(storageNode);

Then pass the storageNode to getArrayBufferAsync instead of the raw attribute. Ultimately, this seems to be a datatransfer problem and since returnBuffer is not returning an error, then we need to find every possible step of data transfer that might be missing. I write in vanilla wgsl so I’m switching between the docs here on tsl’s implementation

(post deleted by author)