Looking to the future: WebGPU Renderer Backend for Godot #4806
Replies: 8 comments 2 replies
-
I've been using WebGPU to learn graphics programming by writing a game framework, and the API is a delight to use. Another implementation to consider would be WGPU-native. It's written in Rust with an officially-supported C FFI and it works very well. WGPU is the backend for Bevy, an up-and-coming open source game engine in Rust, and the very active Bevy community of developers have committed to supporting it along with the original maintainers. Since Dawn and WGPU are implementations of the same spec, the API is the same, except that in WGPU you occasionally need to use a drop function to accommodate for Rust's semantics. I'd personally prefer to support the smaller FOSS community and avoid Google, but that might just be me. |
Beta Was this translation helpful? Give feedback.
-
Whether Dream or WGPU-native the end result would be pretty much the same, so I'd personally be happy with either really. I agree it's nice to support FOSS where possible. Some potential considerations for Dream vs WGPU-native off the top of my head:
On the flip side, WGPU-native seems to be based on WGPU-core, which powers Firefox's WGPU implementation, so that should probably guarantee parity with web builds running in Firefox (albeit Chrome is far more popular than Firefox so that benefit is arguably less significant in that case). It also seems to have best-effort GLES backend support which is probably more useful than a best-effort OpenGL backend like Dream. Mozilla definitely seems to lag a bit in implementing the latest WebGPU API updates, though; not sure how long after standardization it'll take them to be compliant. Dream should be ready ASAP after standardization. |
Beta Was this translation helpful? Give feedback.
-
I'm not an authority on it, but I did find in 2019 the emscripten people mentioned a WebGPU header for both Dawn and WGPU, so I assume yes? On the other point, is there a reason Chrome is particularly important? If two implementations fill out the same spec I imagine differences in rendering would be minimal and beyond the scope or responsibility of those writing the Godot renderer. Two people's desktops are already going to render things differently depending on specs and settings and platform and all that--passing a pixel-perfect rendering check doesn't seem all that important to me, even irrespective of there being a reason to standardize Chrome's rendition over another. At any rate one over the other is largely a FOSS/software ethics question and probably worth talking about later, if/when this proposal is officially considered. |
Beta Was this translation helpful? Give feedback.
-
I think from a indie dev standpoint, it's nice to guarantee your native build and your web build are going to run the same with no code changes (and just statistically you and your players are most likely to be using Chrome or a Chromium-based browser). It's a very annoying experience to have something work in one build but break in another, and having to go digging through forum posts and docs just to find out some shader function is implemented in a weird way in one rendering backend implementation and not another. Less so concerned with running pixel perfect across both and moreso concerned with the potential for obscure and difficult to diagnose implementation quirks. Of course, this is likely to be a rare issue, but it's annoying when it happens (just look at how annoying it can already be to get Vulkan shaders working the same across Windows and Linux and across Nvidia and AMD cards, or WebGL anything to run the same across Chrome, Firefox, and Safari) and worth considering to some extent I think. It eliminates a point where implementation quirks can pop up in a technology space already fraught with implementation quirks. |
Beta Was this translation helpful? Give feedback.
-
Ah, that makes sense. I expect quirks are a bigger issue with the concept of wrapping other APIs in the first place (i.e. implementation diffs pop up running on the Vulkan rather than Metal backend, for instance, the way the 3.4 ES/core renderers in Godot have varying features, although in my experience WebGPU is pretty uniform so far) rather than which implementation of a spec, but I also don't know for sure. I don't have strong feelings about which implementation would be theoretically used except for FOSS motivations as mentioned, and that's not up to me in the end. Godot's generally good about hiding platform details anyway, and this'd be renderer-side rather than user-side. |
Beta Was this translation helpful? Give feedback.
-
Godot has its own RenderingDevice abstraction, which makes it easy to plug additional graphics backends (and doesn't require engine developers to actually care about the underlying API in use). It currently supports only Vulkan, but Metal, Direct3D 12 and WebGPU support can be added to it in the future. The OpenGL ES/WebGL renderer doesn't use the RenderingDevice abstraction, as RenderingDevice is only designed to be used with modern graphics APIs.
I would be wary of going this route. It would mean that we'd have to bundle, compile and rely on a large Google-developed1 library on all platforms, even when it's not strictly necessary. There's also likely some performance overhead and compatibility issues involved, similar to what ANGLE is doing when used on Godot right now. In general, Godot aims to keep its dependency count low to avoid relying on third-party development decisions. We've been bitten by this in the past 🙂 Footnotes
|
Beta Was this translation helpful? Give feedback.
-
Those are valid concerns - and with RenderingDevice abstraction I see providing WebGPU as an optional backend rather than the primary is definitely the route to take. I assume it probably wouldn't be too difficult to transpile Godot shaders to WGSL (-- I had assumed Godot used GLSL; still a Godot noob lol). It's also worth noting that overhead is likely to be much closer to what we see with MoltenVK than what we see with Angle; maybe even lower since WebGPU was explicitly designed to wrap Vulkan/Metal/DX12 unlike Vulkan -> Metal. As a developer on Apple platforms if the overhead is lower than MoltenVK I'd gladly use the WebGPU backend instead even for native builds, for example. Side note - regarding WGPU-native, would it not be possible to provide prebuilt blobs to statically link against? |
Beta Was this translation helpful? Give feedback.
-
For the record, a WebGPU backend is already planned. It will definitely be implemented as a RenderingDevice like Vulkan. The modern renderers (clustered/mobile) will target WebGPU when exporting to web. For more information see the renderer naming and organization proposal here #4261 |
Beta Was this translation helpful? Give feedback.
-
* To start, a big caveat: while WebGPU will be standardized in the near future, the WebGPU API is not standardized yet, so it wouldn't be appropriate to start working on this now. This might be something to consider for Godot 5, or at least as an optional additional backend alongside Godot 4's current Vulkan backend a year or two or more from now.
This is a discussion about the potential of a WebGPU Renderer backend for Godot, either as the primary renderer backend or an optional alternative to other backends like the Vulkan renderer.
What is WebGPU?
In short, WebGPU is to WebGL what Vulkan is to OpenGL. From the W3C working draft:
WebGPU exposes an API for performing operations, such as rendering and computation, on a Graphics Processing Unit.
As the name implies it is intended to be used primarily on the web as a replacement or alternative to WebGL, but its capabilities go beyond that (more on that later).
Unlike WebGL, the WebGPU API is not based on its closest native cousin (a la WebGL with OpenGL ES). It is a completely new API built from scratch and is quite nice to use as far as low-level graphics APIs go. In terms of API semantics, its closest analog would likely be Metal rather than Vulkan or DX12. Like Vulkan, DX12, and Metal, WebGPU offers high-performance low-overhead GPU access for rendering and GPU computation. It also comes with its own shading language, WGSL, which can also be translated to SPIR-V.
Here are some WebGPU demos:
https://gnikoloff.github.io/webgpu-compute-metaballs/
https://webkit.org/demos/webgpu/babylon/oneHelmetWebGPU.html
https://austin-eng.com/webgpu-samples/samples/deferredRendering
(View with Chrome Canary with WebGPU enabled via chrome://flags - again, the API isn't stable quite yet, and Google is the main driving force of implementing WebGPU currently).
What does it have to do with Godot?
The obvious answer is an alternative to the WebGL backend for higher performance in games and apps on the web built with Godot. Like WebGL, you can use WebGPU with Emscripten to render graphics on the web with a C++ codebase.
The less obvious answer, and potentially the one with greater potential for Godot, is that unlike WebGL, WebGPU can be used as a rendering backend for native apps as well.
Google Dawn
Google Dawn is, in essence, a native implementation of the WebGPU API. It is what powers WebGPU rendering in the Chromium and Chrome browsers. What makes Dawn relevant to Godot is two-fold:
Google Dawn is what one would link against to use WebGPU with Emscripten (example), meaning it would require little to no code changes to use WebGPU on the web and Google Dawn for native builds. If you want to use WebGPU with Emscripten, you get the native builds too essentially for free.
From the Google Dawn homepage:
The Google Dawn team provides some C++ examples in their repository. See the building instructions here.
What does this mean?
WebGPU has the potential to reduce labor requirements for maintaining renderer backends for Godot in the long-term, streamline game/app development for Godot developers, and improve consistency of rendering behavior across virtually all platforms.
Once WebGPU is standardized and the Dawn implementation is stable, I think it would be very worthwhile to give it strong consideration to use for Godot's primary rendering backend.
Beta Was this translation helpful? Give feedback.
All reactions