Skip to content

WebGPURenderer: Add ReadbackBuffer as parameter#33315

Closed
sunag wants to merge 4 commits intomrdoob:devfrom
sunag:dev-readbackbuffer
Closed

WebGPURenderer: Add ReadbackBuffer as parameter#33315
sunag wants to merge 4 commits intomrdoob:devfrom
sunag:dev-readbackbuffer

Conversation

@sunag
Copy link
Copy Markdown
Collaborator

@sunag sunag commented Apr 2, 2026

Fixes #33281

Description

Add ReadbackBuffer as a parameter; this should help share the GPU buffer between attributes.

Function signature

Single function signature.

async getArrayBufferAsync( attribute, readbackBuffer, offset, size ) : ArrayBuffer

Simple usage

The same readback buffer will be used for all subsequent requests if you use the simple method await renderer.getArrayBufferAsync(attribute); you can use attribute.dispose() to discard the readback buffer.

const arrayBuffer = await renderer.getArrayBufferAsync( attribute );

Obtain multiple data from the same readback asynchronously

To obtain fractions of the same buffer in parallel, it will be necessary to use instances of ReadbackBuffer. If the dev does not use them, they will receive an alert with instructions.

// start

let buffer1, buffer2;

buffer1 = new THREE.ReadbackBuffer( 8 );
buffer2 = new THREE.ReadbackBuffer( 8 );

// update cycle

const p1 = renderer.getArrayBufferAsync( attribute, buffer1, 0, 8 );
const p2 = renderer.getArrayBufferAsync( attribute, buffer2, 8, 8 );

const [ array1, array2 ] = await Promise.all( [ p1, p2 ] );

// end

buffer1.dispose();
buffer2.dispose();

Note: It will only appear if it uses the same ReadBuffer concurrently.

image

Notes

Based on previous feedback, I am using slice() to clone the ArrayBuffer and then discarding the mapped one; this also allowed me to remove the need for the ReadbackBuffer.release() method, making the API simpler.

/cc @gkjohnson

@sunag sunag added this to the r184 milestone Apr 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 360.57
85.58
360.57
85.58
+0 B
+0 B
WebGPU 635.48
176.41
635.98
176.68
+493 B
+267 B
WebGPU Nodes 633.6
176.11
634.09
176.38
+493 B
+267 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 492.95
120.2
492.95
120.2
+0 B
+0 B
WebGPU 707.66
191.31
708.16
191.58
+496 B
+272 B
WebGPU Nodes 656.88
178.57
657.38
178.84
+496 B
+269 B

@sunag
Copy link
Copy Markdown
Collaborator Author

sunag commented Apr 10, 2026

Closing in favor of #33322

@sunag sunag closed this Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WebGPURenderer: Fix "getArrayBufferAsync" to avoid severe GC pressure

1 participant