Bevy and WebGPU
bevyengine.org
bevyengine.org
Also, have you thought of teaming up with anyone who is explicitly teaching webgpu / wgsl? Seeing someone create a rust perspective course on learning webgpu could be nice.
Pros:
- Compared to OpenGL, WebGPU is wayyy better in every way
- Compared to Vulkan/DirectX 12/Metal, WebGPU is 0.5-1 steps higher level (easier to use), and covers macOS/iOS without needing a separate Metal backend
- We get WebGPU (browser) support for free, as mentioned in this post :). wgpu also gives us WebGL2 for free (provided you don't use certain features) which we're using to target browsers until WebGPU is more fully supported.
- WGSL (the shader language) is actually fairly nice coming from Rust, compared to the more C-style GLSL/HLSL
Cons:
- We're leaving performance on the table due to WebGPU validation / extra work it needs to do to abstract differences between platforms and be higher level than the APIs it wraps. Not the worst thing in the world, but it's a downside. Probably can be alleviated on non-browser platforms with opt-in relaxed validation and lower level APIs (wpgu-hal).
- Library/tooling maturity is much worse. Wgpu/naga (the WGSL shader compiler) frequently have bugs (less now than they used to), and error messages leave much to be desired. Shader tooling is much worse - we've had to build our own shader import system, syntax highlighting is provided by a non-bevy VSCode extension someone on the internet kindly maintains, GPU debugging tools don't have source-level info for WGSl shaders, etc. Again this will get better over time.
- We can't access all the latest features. Things like raytracing, subgroup/warp/wave operations, binding arrays, etc. That said, wgpu does provide native-only extensions for some of these. Support inevitably trails behind Vulkan/DirectX 12 though. Not really a huge deal for the most part, but I personally do miss this. Again will get better as wgpu/webgpu finalize and more time can be spent extending the spec with newer features.
- I've left this for last, but the explicit binding model sucks. WebGPU is fairly high level, but keeping explicit binding instead of requiring binding arrays is awful. Every time you want to add a texture/buffer/etc to your shader, you need to modify the bind group layout, modify the bind group, and then modify the shader, and keep those definitions in sync. When you have multiple pipelines, bind groups, shaders, and modular systems that only need certain resources under different conditions or certain parts of different shaders, it's just awful to keep track of. The ergonomics are terrible. I wish WebGPU would've required binding arrays and just accepted losing support for some older devices. In Bevy we plan to write an abstraction that acts more like binding arrays and falls back to explicit bindings where needed, but that's still a lot of work.
Overall, I generally think wgpu was/is the right choice for Bevy. The ergonomics could still use work, we leave performance on the table, we don't get all the advanced and new features, and the growing pains were (and still are, to a lesser degree) real. But we still get better ergonomics compared to other options, WebGPU support for browsers, 1 rendering backend vs at least 3 (Vulkan/Metal/WebGL2), and the rest of the issues are fixable over time and with more work done on both Bevy's side and the library and tooling side.
Sometimes I wish we went with just Vulkan+Metal and could drop down to lower level stuff, get access to new features, and just generally not have to deal with extra layers and immature tooling. But I still think it's the right choice for the project overall. Discalimer: just my own opinion, I don't represent the project.
> Also, have you thought of teaming up with anyone who is explicitly teaching webgpu / wgsl? Seeing someone create a rust perspective course on learning webgpu could be nice.
Learn wgpu (https://sotrh.github.io/learn-wgpu) provides a nice intro to WebGPU/WGSL. I don't think there's really anything Bevy specifically would be able to provide. Once you wrap your head around the APIs themselves, generally the hard part of graphics programming is dealing with the boilerplate, and the actual 3D rendering techniques themselves irrespective of the API you write in.
That said, there's a few improvements I've though about contributing to learn wgpu to cover the more advanced side of things (compute shaders, storage resources, alignment rules, etc), but I haven't had time lately.
It helps us embrace Bevy's core "engine features look like app features" mentality: the APIs we use to implement renderer features are the same APIs that Bevy plugin developers use to implement renderer features.
More on the "Bevy App Model" philosophy: https://bevyengine.org/news/bevys-first-birthday/#the-bevy-a...
And lastly, thank you for your contributions, IMO Bevy has been a massive driver of visual/game efforts for Rust!
Biggest missing piece is an "audio bus" API with effect stacks. For that, plugins like bevy_kira_audio already do a good job. And we'll get there eventually with our official plugin.
I noticed the fox demo's wasm_example_bg.wasm is 22MB. That seems large? Is there code splitting?
Also, seems streaming is broken:
wasm_example.js:285 `WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
What is your use case for needing webgl1?
Bevy is also extremely modular. If you absolutely need webgl1 support, you can implement it yourself as a plugin without losing the rest of the non-rendering parts of bevy like audio, input, the core ECS of course, etc.
We simply don't have the contributors to create and maintain such a renderer, at least at the moment.
I want to try out bevy because I’ve heard it is very modular so it would be easier to swap out stuff like this. What part of bevy would I need to look at modifying to support this?
- bevy_pbr: Bevy's standard physically-based renderer. Provides PBR shaders, user-extensible materials, as well as APIs for organizing draw calls and rendering.
- bevy_core_pipeline: Defines some standard rendering setups like "2d" and "3d - Opaque, transparent, etc", with the goal that you could plug your own wgpu-based renderer into this layer. Also currently holds all of our post-processing effects (TAA, tonemapping, bloom, etc).
- bevy_render: One part wrapper/helpers around wgpu, one part generic renderer utilities like a render node graph and 3D camera types.
There's also some extra crates I didn't cover like bevy_sprite for 2D, bevy_ui for UI, etc.
If you want to build a wgpu-based renderer, you have a couple of options depending on what kind of rendering you need. You can plug in your own custom renderer instead of bevy_pbr using bevy_core_pipeline. You can still use bevy_pbr and just add your own render nodes on top of it. Or, you can ditch wgpu/bevy_render completely and build everything from scratch (at the cost of losing UI/2D support).
Anything you do would take the form of a custom plugin. Bevy is extremely modular - plugins are how we organize and develop the engine itself, so removing certain rendering plugins and adding your own is easy.
EDIT: I encourage you to join Bevy's discord channel and discuss your project in the #rendering channel, it's much easier to provide help and give info than over a forum.
The good is that whole applications can be written in just a handful of mostly declarative code, which is absolutely amazing! The bad is that with all the magic being handled by macros and back-end event processing loops, it can be a little intimidating and not obvious how it is constructed under the hood. I would love to see a class diagram showing both the extant objects and their types, and the control flow during a frame update.
But anyway, thank you for all your hard work and for the response. Now I know where to go first in the source code to do what I need to do.
> If you want to build a wgpu-based renderer, you have a couple of options depending on what kind of rendering you need. You can plug in your own custom renderer instead of bevy_pbr using bevy_core_pipeline. You can still use bevy_pbr and just add your own render nodes on top of it.
I actually have my own wgpu-based renderer done (https://github.com/atomCAD/atomCAD/), so maybe that's the first thing to try. Thanks!
> I encourage you to join Bevy's discord channel and discuss your project in the #rendering channel, it's much easier to provide help and give info than over a forum.
Will do.
I'm really hoping for Bevy and/or Fyrox catch up to Godot. I like all three, but having a Rust ecosystem for gamedev will be a game changer. Especially if they eventually garner the same kind of support that Blender has.
Cheering you on!
Editor: Godot has one, Bevy does not. Animation support: Godot has support for complex animation blending and animating anything that can be serialized. Bevy does not. Audio: Bevy's audio is pretty simple right now and lacks direct world entity driven spatial audio. Rendering: Godot has pretty deep support for higher performance and higher fidelity rendering techniques like automatic instancing and
Everything in this list is being worked on, but require time to bake. Everything else more or less has most of the core pieces in place that Godot has, though may be missing a few small features here or there.
Where is Bevy ahead?
Multithreaded CPU performance. I can almost guarantee your average Bevy app will have higher thread utilization than your average Godot/Unity/Unreal game, and this will continue to scale as more complex computations are required for various engine systems are added.
Testability: ECS makes it really easy to write dependency injection based unit tests, something otherwise difficult to test end-to-end with engines like Godot and Unity.
Extendability and customization: Bevy is plugins all the way down. Godot definitely takes a much more monolithic approach to building an engine, and making significant changes to the core engine will require forking. Where Godot requires exposing deeper APIs for exposing functionality, Bevy already supports ripping out the relevant plugins and subsituting just those with your own.
Memory safety: As the mantra goes, every 1k LoC of C/C++, there's one CVE that is yet to be found, and 70% of those are memory safety issues. Bevy heavily leverages unsafe in the ECS, but rarely touches it in the other core engine crates. We can with high confidence say there are no memory safety problems or problems caused by undefined behavior in Bevy due to Rust's strong safety guarantees.
This question might be a little less fair -- what's the state of Bevy vs Fyrox?
And if you have a guess, how long will animation and editor support take? A wild guess is fine (though if you break out animation a bit, I'd be grateful).
Animation support is growing rapidly. I'm one of the two SMEs (subject matter experts) focused on this area, and we just rounded out the final parts of the animation composition RFC. I'm hoping to get that feature to land in 0.11, but may take until 0.12 to be fully available. There's also an open PR for animating morph targets, the primary other way of deforming meshes for animation, which I think should land in 0.11. I'm also working on inverse kinematics implementation, which should round out the core "animate to move things" features. More powerful animation features are likely going to be reliant on an editor going forward though.
The editor is definitely something we're pushing hard on. Cart recently just opened a PR rewriting the asset system to better support preprocessing and more complex asset interactions, something we desperately needed for the development of an editor. I'd like to say we'll break ground on the editor before Q3 of this year, but that might be an overaggressive target.
Flecs ECS already supports this: https://github.com/SanderMertens/flecs/blob/master/docs/Rela...
(subject matter expert: a formal role in the Bevy project for experts in an area that have a say on big/controversial changes)
Any plans to extract the core ECS functionality out of bevy_ECS and create a bevy_core or something along those lines with no_std (alloc is fine) support, so we can use it to target some console platforms? TY!
If theres enough demand we could probably port bevy_ecs on its own to no-std, but that would add more code and maintenance burden so I'd be a bit hesitant to merge such a port.
I suppose this is already being discussed within the community and they're capturing the same concern you're bringing up: https://github.com/bevyengine/bevy/pull/6581
I know that some efforts have been made to make Bevy deterministic. Which would be great and allow RTS games. Cross-platform determinism is not necessarily needed or wanted. Determinism on AVX2 would be fantastic. What is the plan for determinism?
Overall though I haven't regretted the experience at all. If anyone is on the fence about playing around with Bevy I'd encourage you to jump on in.
On a similar note, Ambient (https://github.com/AmbientRun/Ambient) has been on my radar for their utilization of WebGPU, though they seemingly lack a tangible web demo. Anyone have any insights or comparisons to share?