Skip to content

WebGPURenderer: Remove inline functions in rendering methods.#33108

Merged
sunag merged 11 commits into
mrdoob:devfrom
PoseidonEnergy:fix/no-draw-object-allocations-1
Mar 3, 2026
Merged

WebGPURenderer: Remove inline functions in rendering methods.#33108
sunag merged 11 commits into
mrdoob:devfrom
PoseidonEnergy:fix/no-draw-object-allocations-1

Conversation

@PoseidonEnergy
Copy link
Copy Markdown
Contributor

@PoseidonEnergy PoseidonEnergy commented Mar 2, 2026

Related issue: #33107

Description

This PR ensures that no objects are allocated in the Renderer._renderObjectDirect() hot path that gets called for each mesh per render.

From my testing this has produced a 20% gain in the performance of Renderer.render(), plus the added benefit of far less garbage being generated in a render() loop.

You can test this PR live at the following JSFiddle: https://jsfiddle.net/v14csauf

image

Garbage Accumulation

image

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 2, 2026

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 359.27
85.31
359.27
85.31
+0 B
+0 B
WebGPU 629.85
174.95
629.94
174.99
+97 B
+37 B
WebGPU Nodes 628.43
174.7
628.52
174.74
+97 B
+36 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 491.03
119.72
491.03
119.72
+0 B
+0 B
WebGPU 703.47
189.95
703.56
189.99
+97 B
+32 B
WebGPU Nodes 652.67
177.34
652.77
177.37
+97 B
+31 B

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Mar 2, 2026

Do you mind splitting the PR in smaller changes and just update WebGPURenderer for now?

I think it makes sense to remove the inline functions in draw() as a first step.

@PoseidonEnergy PoseidonEnergy changed the title 20% render() performance boost: avoid 4x object allocation in Renderer._renderObjectDirect() 20% render() performance boost (Part 1): avoid 4x object allocation in Renderer._renderObjectDirect() Mar 2, 2026
@PoseidonEnergy PoseidonEnergy changed the title 20% render() performance boost (Part 1): avoid 4x object allocation in Renderer._renderObjectDirect() 20% render() performance boost (remove closures): avoid 4x object allocation in Renderer._renderObjectDirect() Mar 2, 2026
@PoseidonEnergy PoseidonEnergy changed the title 20% render() performance boost (remove closures): avoid 4x object allocation in Renderer._renderObjectDirect() 20% render() performance boost Part 1 (remove closures): avoid 4x object allocation in Renderer._renderObjectDirect() Mar 2, 2026
@PoseidonEnergy
Copy link
Copy Markdown
Contributor Author

PoseidonEnergy commented Mar 2, 2026

Do you mind splitting the PR in smaller changes and just update WebGPURenderer for now?

I think it makes sense to remove the inline functions in draw() as a first step.

Here is the new PR for the BufferGeometry.attributes portion: #33111

For some reason the "Files Changed" comparison view for this PR is all jacked up. All I did was turn the const setPipelineAndBindings = () => { ... } and const draw = () => { ... } functions into private methods on the WebGPUBackend class.

@Mugen87 Mugen87 changed the title 20% render() performance boost Part 1 (remove closures): avoid 4x object allocation in Renderer._renderObjectDirect() WebGPURenderer: Remove inline functions in rendering methods. Mar 2, 2026
Comment thread src/renderers/webgpu/WebGPUBackend.js
Comment thread src/renderers/webgpu/WebGPUBackend.js Outdated
@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Mar 2, 2026

Added JSDoc and slightly updated the signature of _draw() in WebGPUBackend.

@Mugen87 Mugen87 added this to the r184 milestone Mar 2, 2026
@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Mar 2, 2026

We should avoid object allocation in hot code paths whenever possible so the changes of this PR are indeed wanted.

@sunag sunag merged commit fd1bddf into mrdoob:dev Mar 3, 2026
10 checks passed
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.

3 participants