djeedai / bevy_hanabi

🎆 Hanabi — a GPU particle system plugin for the Bevy game engine.
Apache License 2.0
908 stars 72 forks source link

WASM compatibility #41

Closed ZettaScript closed 1 month ago

ZettaScript commented 2 years ago

Using bevy_hanabi fails in WASM because VERTEX_WRITABLE_STORAGE is not supported (even if WGPU doc says it is supported by all platforms).

Is it planned to make this crate WASM-compatible?

djeedai commented 2 years ago

No, bevy_hanabi uses compute shaders which are not currently supported on Web.

djeedai commented 2 years ago

The docs says:

This is a native-only feature.

djeedai commented 1 year ago

I'm going to close this issue. I fully appreciate the value of wasm, and I'm kind of sad that this crate doesn't work with it, but it would be such a large amount of work not only to create a separate backend dedicated to wasm that doesn't use compute shaders, but also to maintain two backends in parallel, that I realistically don't have the time to do this.

I hear some Bevy users are working on a CPU particle solution, which would work with wasm (see bevyengine/rfcs#28) so I encourage anyone who needs a particle system that works in wasm to contribute to that RFC and workstream.

If you're familiar with Unity, and to hazard an over-flattering comparison that is probably not realistic (yet?), 🎆 Bevy Hanabi is to Unity's VFX Graph what that CPU solution and RFC for Bevy is to Unity's built-in particle system, with the same advantages and drawbacks. CPU solutions are more versatile, easier to support on all platforms, but limited in terms of performance; on the other hand GPU solutions are vastly more performant but require modern API and hardware features (compute shaders) which are not available everywhere.

johanhelsing commented 1 year ago

too, bad, but I totally undestand your decision. I guess we can only hope that webgpu will solve this in the future...

maybe add a small note in the readme that wasm is not supported?

djeedai commented 1 year ago

maybe add a small note in the readme that wasm is not supported?

I thought I already had but apparently not. Fixed now, it's in the README.

janhohenheim commented 1 year ago

AFAIK compute shaders are now supported by WebGPU. @djeedai would you consider reopening this issue?

djeedai commented 1 year ago

@janhohenheim I would be more than happy to add wasm support to 🎆 Hanabi provided Bevy itself supports compute shaders on wasm. I don't believe this is the case yet though? And I can really spearhead that myself.

janhohenheim commented 1 year ago

@djeedai hmm, I tried running the compute_shader_game_of_life example on wasm on Bevy's main branch and forced the wgpu backend to WebGPU by calling the following on the DefaultPlugin setup:

.set(RenderPlugin {
    wgpu_settings: WgpuSettings {
        backends: Some(Backends::BROWSER_WEBGPU),
        ..default()
    },
})

However, I cannot test this further, since I fail to activate WebGPU on my browsers; I cannot render any WebGPU examples on the internet right now. Maybe someone else has better luck? The steps needed to enable WebGPU are described here.

I double checked, and yes, WebGPU does indeed support compute shaders.

johanhelsing commented 1 year ago

I couldn't get webgpu to work at all in firefox, but on chrome, this example worked: https://cx20.github.io/webgpu-test/examples/rust/triangle/index.html

However, when I tried patching wgpu compute_shader_game_of_life like you suggested, @janhohenheim , I get a panic:

panicked at 'Unable to find a GPU! Make sure you have installed required drivers!', crates\bevy_render\src\renderer\mod.rs:125:10

This was on windows 11 with nvidia gtx 970. May give it another try on linux.

janhohenheim commented 1 year ago

@johanhelsing ah heck! I checked Discord and found this:

image image

I deduce from this that you might get webgpu running if you enable the respective feature on wgpu. But it seems this is not yet part of any public facing Bevy API.

djeedai commented 1 year ago

So yes, that's my understanding, and happy to reopen this once Bevy supports it but until then no luck in afraid.

Dimchikkk commented 1 year ago

Seems like there is official support for WebGPU in bevy's main branch, should this issue be reopened?

mockersf commented 1 year ago

I ported bevy_hanabi to main, and with a few fixes for WebGPU it works in the browser

https://github.com/djeedai/bevy_hanabi/assets/8672791/fa5979ca-3008-42c0-9ae9-00752645bd9d

Dimchikkk commented 1 year ago

@mockersf great, do you have a branch to try? :)

mockersf commented 1 year ago

just pushed it here: https://github.com/mockersf/bevy_hanabi/tree/with-webgpu, started from https://github.com/djeedai/bevy_hanabi/pull/179 for some of the Bevy update needed

Building for WebGPU: RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build --target wasm32-unknown-unknown --example firework --features="bevy/bevy_winit bevy/bevy_pbr bevy/png 3d"

djeedai commented 1 year ago

Reopening the issue now that Bevy has official support.

djeedai commented 1 year ago

I did some initial work and I can build and run all examples. However there's a major bug where only the first effect is visible, and I'm having difficulties debugging on Web (notably, at the minute logs don't show up in console like they should, and I don't know of any way to make GPU captures). So this likely won't make it for the next release unfortunately (next few days, waiting on bevy-inspector-egui to upgrade to Bevy 0.11).

adamtomecek commented 1 year ago

@djeedai could you create a draft PR with that you have? So me and others can maybe help with debugging

djeedai commented 1 year ago

@adamtomecek See the u/wasm branch, I think it has my latest try.

adamtomecek commented 1 year ago

Unfortunately no luck running it. It panicks on me with Current version, u/wasm branch and mockersf WASM support branch.

Caused by:
    In Device::create_bind_group_layout
      note: label = `hanabi:bind_group_layout:dispatch_indirect_dispatch_indirect`
    Too many bindings of type StorageBuffers in Stage ShaderStages(COMPUTE), limit is 0, count was 3
djeedai commented 1 year ago

Looks like a bug on Hanabi side though, unless that 0 limit somehow means something is not supported on wasm? Not sure...

mockersf commented 1 year ago

Are you building for WebGL2 or WebGPU?

adamtomecek commented 1 year ago

Good question. Not sure. I'm pretty new to Rust/Bevy but I think it's safe to say I'm using default values?

RUSTFLAGS=--cfg=web_sys_unstable_apis cargo run --target wasm32-unknown-unknown this is a command I'm using to run it. On M2 Mac

adamtomecek commented 1 year ago

I take it back. I finally figured out how to build Bevy with WebGPU and it works spot on with your u/wasm branch.

djeedai commented 1 year ago

Can you run all examples? At the time I made the branch I could only run examples with a single effect. As soon as there were more, only the first rendered.

adamtomecek commented 1 year ago

...works spot on with my game, but I use multiple effects. I create all effects while loading the game, save Handles and run effect when needed.

I'll give examples here a try and let you know

djeedai commented 1 year ago

I tested on latest, there's no change. See for example the spawn example, it's missing the second and third effects. I have no idea how to debug the GPU on WASM in the browser, I don't think there's any tool like RenderDoc. So it might take a while to figure out what the browser is not liking.

image

adamtomecek commented 1 year ago

@djeedai

Screenshot 2023-09-04 at 16 21 55

I see all three effects. I couldn't compile examples from your u/wasm branch, I use my custom rebased with my Cargo.toml. But I think removing WorldInspectorPlugin did the trick. With the plugin, I wasn't able to see any effects.

I'll make a working example and send you a link.

djeedai commented 1 year ago

Yes I had to remove the inspector too, but I still don't see the other effects beyond the first one.

I'm using the latest Chrome 116 to run the examples on Windows. That looks more and more like a platform bug in Bevy or Wgpu.

adamtomecek commented 1 year ago

@djeedai code that's working for me. Sadly can't see any major changes compared to your version. Running it like this RUSTFLAGS=--cfg=web_sys_unstable_apis cargo run --example spawn --features="bevy/bevy_winit bevy/bevy_pbr 3d" --target wasm32-unknown-unknown with added Cargo config file for a WASM runner.

djeedai commented 1 year ago

@adamtomecek Indeed the code looks the same. The build command too, mine is:

cargo b --release --example spawn --target wasm32-unknown-unknown --no-default-features --features="bevy/bevy_winit bevy/bevy_pbr 3d"
wasm-bindgen --out-name wasm_spawn --out-dir examples/wasm/target --target web target/wasm32-unknown-unknown/release/examples/spawn.wasm

From there I run basic-http-server examples/wasm and point Chrome at http://127.0.0.1:4000. I'm unclear what you're doing on your side, I don't know what "added Cargo config file for a WASM runner." means. Can you also please confirm on which platform you run? Just to see if there's a pattern here.

I noted you build in Debug, while I build in Release. However I tried in Debug and it doesn't change anything. I've also upgraded my NVidia drivers to latest just in case, but that had no effect.

adamtomecek commented 1 year ago

@djeedai

I'm unclear what you're doing on your side, I don't know what "added Cargo config file for a WASM runner." means

[target.wasm32-unknown-unknown]
runner = "wasm-server-runner"

My config. I think the result should be identical. Release and Debug makes no difference for me. Both work.

Can you also please confirm on which platform you run?

I have a Macbook Air M2 with latest MacOS

adamtomecek commented 1 year ago

@djeedai do you see effects in this "game" I made? https://tds.tmck.cz/ There should be firework like effect when you hit an enemy.

djeedai commented 1 year ago

@djeedai do you see effects in this "game" I made? https://tds.tmck.cz/ There should be firework like effect when you hit an enemy.

Only on the first killed enemy. Well that's kind of a partial relief, I'm not getting insane, this really looks like a platform bug.

FYI @superdump see the above website, on Windows PC with Chrome 116 I don't see the effects after the first one, whereas @adamtomecek can see them all on a Macbook Air M2. This looks like a Chrome bug maybe?

adamtomecek commented 1 year ago

Had a friend running W10 and latest Chrome test it and he also sees only first one.

mockersf commented 1 year ago

on macOS with an m1 and chromium 117, I see them all... so yeah looks like a chrome bug

Elabajaba commented 11 months ago

https://tds.tmck.cz/

Windows + chrome 117 I also only get the first effect (per enemy type).

On firefox nightly (119.01a 2023-09-23) with webgpu enabled it works! It's laggy, but particles spawn every time I kill an enemy. I had to set dom.webgpu.wgpu-backend = vulkan (it was defaulting to dx12 which wasn't working) and dom.webgpu.indirect-dispatch.enabled = true in about:config for it to work.

djeedai commented 11 months ago

Thanks for the data point, much appreciated. Do you recall what kind of error if any you had with dx12? I'll dig into that indirect dispatch flag too, try to understand why it's not active by default.

AlienSmith commented 1 month ago

Good news everyone. The spawn example works fine with win10 + Chrome(124.0.6367.202) and it works on Edge too. image