Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: BatchedMesh via drawIndexedIndirect #30645

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from

Conversation

RenaudRohlinger
Copy link
Collaborator

Related issue: #29197 (comment)

Description

multiDrawIndirect was announced in Chrome 131. However, after following its progress for over six months, it’s clear that the Metal backend still lacks a full implementation.

Inspired by @aardgoose’s idea, this PR introduces an alternative approach: using multiple drawIndirect() calls with a single indirect buffer, where each call accesses different offsets within the buffer. This method enables GPU compute-directed rendering, potentially capturing many of the benefits of multidraw indirect.

So far I implemented the first step which corresponds to use multiple drawIndirect() calls with the a single indirect buffer mapped at different offsets at for each call. Second part will probably be to move the onBeforeRender logic of BatchedMesh in compute shaders.

Screenshot 2025-03-04 at 20 47 34

This contribution is funded by Utsubo

Copy link

github-actions bot commented Mar 4, 2025

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 336.02
78.26
336.02
78.26
+0 B
+0 B
WebGPU 523.98
145.48
525.06
145.81
+1.08 kB
+334 B
WebGPU Nodes 523.44
145.38
524.52
145.71
+1.08 kB
+332 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 465.06
112.14
465.06
112.14
+0 B
+0 B
WebGPU 594.38
161.07
595.69
161.44
+1.31 kB
+366 B
WebGPU Nodes 549.5
150.51
550.81
150.87
+1.31 kB
+363 B

@Makio64
Copy link
Contributor

Makio64 commented Mar 4, 2025

By curiosity, by how much does it improve the performance on your test ?

@RenaudRohlinger
Copy link
Collaborator Author

@Makio64 So far, it's more expensive than typical drawIndexed on Chrome macOS since it does almost the same with the overhead of an indirect buffer updated every frame, but the idea is that we handle all this in compute shading, which is where performance should improve.

@Spiri0
Copy link
Contributor

Spiri0 commented Mar 5, 2025

If you reserve the same number of vertices for each geometry, drawIndirect/drawIdexedIndirect works very well, then it's all a single drawCall, because you can assign all objects to the indirectBuffer with atomic add. The disadvantage is that if you have objects with very different vertex counts, you use unnecessary memory because you have to reserve the highest vertex count for all objects. But if, as with an instancedGeometry, all instances have the same vertex count, it's perfect.
I didn't know that WebGPU now also has multiDrawIndirect. I'll have to check that out.

In your case, where you have a dozen different primitives, this would also be very easy to do with drawIndirect/drawIndexedIndirect, since each instance of a primitive has the same vertex count. Then, with 12 different primitives, there would only be 12 drawIndirect drawCalls and you can easily push it up to the buffer limit without causing frame drops.

I'm currently converting my terrain generator to drawIndexedIndirect. I'm almost finished with it now. The entire terrain is a single draw call. Frustum and occlusion also does everything the GPU with a compute shader.
If you continue to follow the topic of multiDrawIndirect, I'm happy, because I am far more of a user and have only limited time to be a contributor.

@RenaudRohlinger Does atomic.add work for you with metal now?
I remember there were problems there.

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