Kaynağa Gözat

WebGPURenderer: Fix getArrayBufferAsync in WebGPUBackend (#30132)

Renaud Rohlinger 1 yıl önce
ebeveyn
işleme
169825313f

+ 16 - 10
examples/webgpu_compute_audio.html

@@ -35,9 +35,9 @@
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
 			let camera, scene, renderer;
-			let computeNode;
+			let computeNode, computeResetNode;
 			let waveBuffer, sampleRate;
-			let waveArray;
+			let waveArray, originalWaveBuffer;
 			let currentAudio, currentAnalyser;
 			const analyserBuffer = new Uint8Array( 1024 );
 			let analyserTexture;
@@ -49,10 +49,9 @@
 
 				if ( currentAudio ) currentAudio.stop();
 
+				await renderer.computeAsync( computeResetNode );
 				// compute audio
-
 				await renderer.computeAsync( computeNode );
-
 				const wave = new Float32Array( await renderer.getArrayBufferAsync( waveArray.value ) );
 
 				// play result
@@ -94,12 +93,14 @@
 
 				// adding extra silence to delay and pitch
 				waveBuffer = new Float32Array( [ ...waveBuffer, ...new Float32Array( 200000 ) ] );
-
+				originalWaveBuffer = waveBuffer.slice();
+			
 				sampleRate = audioBuffer.sampleRate / audioBuffer.numberOfChannels;
 
 				// create webgpu buffers
 
 				waveArray = instancedArray( waveBuffer );
+				const originalWave = instancedArray( originalWaveBuffer ).toReadOnly();
 
 				// The Pixel Buffer Object (PBO) is required to get the GPU computed data to the CPU in the WebGL2 fallback.
 				// As used in `renderer.getArrayBufferAsync( waveArray.value )`.
@@ -113,9 +114,9 @@
 				const delayOffset = uniform( .55 );
 
 
-				// compute (shader-node)
+				// compute
 
-				const computeShaderFn = Fn( () => {
+				computeNode = Fn( () => {
 
 					const index = float( instanceIndex );
 
@@ -144,12 +145,14 @@
 
 					waveStorageElementNode.assign( wave );
 
-				} );
+				} )().compute( waveBuffer.length );
 
+				computeResetNode = Fn( () => {
 
-				// compute
+					waveArray.element( instanceIndex ).assign( originalWave.element( instanceIndex ) );
+
+				} )().compute( waveBuffer.length );
 
-				computeNode = computeShaderFn().compute( waveBuffer.length );
 
 
 				// gui
@@ -194,6 +197,9 @@
 
 				playAudioBuffer();
 
+				// on click replay
+				renderer.domElement.addEventListener( 'click', playAudioBuffer );
+			
 			}
 
 			function onWindowResize() {

+ 9 - 7
src/renderers/webgpu/utils/WebGPUAttributeUtils.js

@@ -227,18 +227,18 @@ class WebGPUAttributeUtils {
 		const device = backend.device;
 
 		const data = backend.get( this._getBufferAttribute( attribute ) );
-
 		const bufferGPU = data.buffer;
 		const size = bufferGPU.size;
 
 		const readBufferGPU = device.createBuffer( {
-			label: attribute.name,
+			label: `${attribute.name}_readback`,
 			size,
 			usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
 		} );
 
-
-		const cmdEncoder = device.createCommandEncoder( {} );
+		const cmdEncoder = device.createCommandEncoder( {
+			label: `readback_encoder_${attribute.name}`
+		} );
 
 		cmdEncoder.copyBufferToBuffer(
 			bufferGPU,
@@ -248,8 +248,6 @@ class WebGPUAttributeUtils {
 			size
 		);
 
-		readBufferGPU.unmap();
-
 		const gpuCommands = cmdEncoder.finish();
 		device.queue.submit( [ gpuCommands ] );
 
@@ -257,7 +255,11 @@ class WebGPUAttributeUtils {
 
 		const arrayBuffer = readBufferGPU.getMappedRange();
 
-		return arrayBuffer;
+		const dstBuffer = new attribute.array.constructor( arrayBuffer.slice( 0 ) );
+
+		readBufferGPU.unmap();
+
+		return dstBuffer.buffer;
 
 	}
 

粤ICP备19079148号