bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
33.55k stars 3.26k forks source link

Support WebGL2 and WebGPU in the same WASM file #13168

Open BD103 opened 2 months ago

BD103 commented 2 months ago

What problem does this solve or what need does it fill?

Bevy currently forces you to choose either WebGL2 or WebGPU when building a project. This is one extra thing that developers need to think about when deploying their games, which is already a complicated enough process.

Since the web is a large, incredibly portable platform, we should attempt to make targeting it as painless as possible.

What solution would you like?

In https://github.com/gfx-rs/wgpu/pull/5044, WGPU added support for detecting WebGL2 and WebGPU at runtime. I think integrating this into Bevy would be incredibly useful, and give WebGPU more exposure. This would be achieved through the existing webgl2 and webgpu features.

webgl2 enabled? webgpu enabled? Behavior
Detect API at runtime, preferring WebGPU and falling back to WebGL2 if not available
Use WebGL2, panicking if not available at runtime
Use WebGPU, panicking if not available at runtime
Fail to compile for WASM

Questions

What alternative(s) have you considered?

Additional context

cc @Elabajaba, who originally migrated Bevy to the WGPU version that introduced this feature.

mockersf commented 2 months ago

Questions

  • What crate(s) will need to implement this functionality? Is there a way we can abstract over both APIs to reduce the amount of logic necessary?

Only rendering part should be affected. mostly bevy_render and bevy_pbr

  • Does WebGPU still need --cfg=web_sys_unstable_apis, and do we handle this already?

No, wgpu now vendors those so they're not needed anymore

  • How difficult will this change be? Is it something we can plan on finishing by Bevy 0.14?

Biggest difficulty I think is that currently some const change value depending on WebGL2 / WebGPU / Native. Deciding them at runtime means they won't be const anymore.

Also I think WebGPU detection is hard to do perfectly, so we need a way to "force" fallback on WebGL2 even if WebGPU is detected

BD103 commented 2 months ago

Biggest difficulty I think is that currently some const change value depending on WebGL2 / WebGPU / Native. Deciding them at runtime means they won't be const anymore.

Ok, that will require a bit of benchmarking then to ensure the performance hit is not too great. This will probably affect all of WASM, even if you don't runtime detection.

Also I think WebGPU detection is hard to do perfectly, so we need a way to "force" fallback on WebGL2 even if WebGPU is detected

You can toggle off the webgpu feature at compile time. If we want to do this at runtime, perhaps there can be a resource that configures it. Quick draft:

// This is a bad name, please ignore it
#[derive(Resource)]
enum WASMBackend {
    WebGPU,
    WebGL2,
    Available, // Prefers WebGPU if possible, could instead be named `PreferWebGPU`
}
mockersf commented 5 days ago

Ideally (parts of) Bevy should also support building without WebGL2 and WebGPU, and support targeting wasi (https://github.com/bevyengine/bevy/issues/4906 & https://github.com/bevyengine/bevy/pull/8520)