Neopallium / bevy_water

Dynamic ocean material for Bevy.
https://neopallium.github.io/bevy_water/
136 stars 12 forks source link

Error binding when running in wasm #24

Closed CaoKha closed 1 year ago

CaoKha commented 1 year ago

I tried running the ocean example on desktop and it works perfectly with Bevy 0.10. Adapter Info:

2023-06-28T14:37:34.618525Z  INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 3050 Laptop GPU", vendor: 4318, device: 9634, de
vice_type: DiscreteGpu, driver: "NVIDIA", driver_info: "525.116.04", backend: Vulkan }
2023-06-28T14:37:34.791949Z  INFO yogurt_sim::bevy_water::ocean: Move camera around by using WASD for lateral movement
2023-06-28T14:37:34.791972Z  INFO yogurt_sim::bevy_water::ocean: Use Left Shift and Spacebar for vertical movement
2023-06-28T14:37:34.791978Z  INFO yogurt_sim::bevy_water::ocean: Use the mouse to look around
2023-06-28T14:37:34.791981Z  INFO yogurt_sim::bevy_water::ocean: Press Esc to hide or show the mouse cursor
2023-06-28T14:37:34.792265Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux 22.04 Pop!_OS", kerne
l: "6.2.6-76060206-generic", cpu: "12th Gen Intel(R) Core(TM) i7-12700H", core_count: "14", memory: "15.5 GiB" }

But when I tried it in wasm using wasm-pack and I got this error:

panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `pbr_alpha_blend_mesh_pipeline`
    error matching FRAGMENT shader requirements against the pipeline
    shader global ResourceBinding { group: 0, binding: 16 } is not available in the layout pipeline layout
    binding is missing from the pipeline layout

Here is the log from console for Adapter info:

AdapterInfo { name: "Intel(R) HD Graphics", vendor: 32902, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Gl }

What should I do to get rid of this error ?

Neopallium commented 1 year ago

group: 0, binding: 16 is for the Depth Prepass texture, which might not work under wasm?

bevy_water has feature depth_prepass enabled by default.

Try disabling the default features for bevy_water and only enable embed_shaders.

Also could you share a minimal wasm example or the changes needed to build for wasm?

CaoKha commented 1 year ago

Sure. Here is my minimal modification on your code in order to work with wasm in NextJs:

Cargo.toml

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# default = ["console_error_panic_hook", "embed_shaders", "depth_prepass"]
default = ["console_error_panic_hook", "embed_shaders"]

# Embed the shaders at compile-time.
embed_shaders = []

# Enable debug lines in examples.
debug = []

# Enable DepthPrepass in examples.
depth_prepass = []

I attached #[wasm_bindgen] to the main() function in the ocean example, change its name to run_ocean()

use wasm_bindgen::prelude::wasm_bindgen
#[wasm_bindgen]
pub fn run_ocean() {
    let mut app = App::new();
    // the rest of your code
}

I move the example into a lib.rs then run build.sh to compile it into wasm

build.sh

#! /bin/sh
BASEDIR=$(dirname "$0")
# echo "Remove Rust target folder"
# rm -r $BASEDIR/target/
echo "Compiling wasm..."
wasm-pack build "$BASEDIR" --release --target web --out-dir server/pkg -- --features default --verbose
echo "Change directory to server/"
cd $BASEDIR/server
echo "Remove old cache"
rm -r .next node_modules
echo "Installing packages..."
yarn install
echo "Building nextjs server..."
yarn build
echo "Copying assets to public/ folder..."
cd ..
cp -a ./assets ./server/public/
echo "Done."

Then I init the wasm file as follow:

import init, {
  InitOutput,
  run_ocean
} from "testing_wasm";
export async function init_wasm() {
  await init()
    .then((wasm_js: InitOutput) => {
      console.log(wasm_js);
      run_ocean();
    })
    .catch((_: unknown) => {
      // intentional error from wasm, we can ignore this error message:
      // "Using exceptions for control flow, don't mind me. This isn't actually an error ..."
    });
}
export default function Home() {
  init_wasm();
  return <> </>
}

I tried your solution but still, ...got the same error :(

Neopallium commented 1 year ago

I got it to work and added instructions to build the examples (simple and ocean) as wasm.

Right now only WebGL is support, bevy 0.11 which should be released soon has support for WebGPU.

WebGL is very limited and I wasn't able to get the depth_prepass working. Support WebGL also require some refactoring of the shader (split vertex & fragment).

Also bevy_atmosphere uses compute shaders and doesn't support WebGL, so I disabled that for the WASM build of the ocean example.

Neopallium commented 1 year ago

You can see the ocean example here: https://neopallium.github.io/bevy_water/

Neopallium commented 1 year ago

The web_example branch has been updated to support WebGPU: https://github.com/Neopallium/bevy_water/tree/web_examples

You can see both the WebGPU version (with depth_prepass) and the old WebGL version (no depth_prepass) at the example url.

Right now WebGPU is broken on Bevy's main branch, so I had to go back to commit e0b1809 to get that work.

CaoKha commented 1 year ago

Hey Neo, thank you for the hard work. The WebGL version works fine but I got a blank screen with the WebGPU example (with literally no error from Rust except the exception throw by the control flow) . I used Firefox nightly for the test. test_bevy_engine

Neopallium commented 1 year ago

Do the bevy WebGPU examples here work for you? https://bevyengine.org/examples-webgpu/

I am downloading Firefox nightly now, to try.

Neopallium commented 1 year ago

I got the same errors with some of the Bevy WebGPU examples.

In a draw command, indexed:true indirect:false, caused by: The pipeline layout, associated with the current render pipeline, contains a bind group layout at index 0 which is incompatible with the bind group layout associated with the bind group at 0
Command encoder is invalid
In a pass parameter, caused by: Command encoder is invalid

I think this is either a bug with bevy's WebGPU support or Firefox's WebGPU support.

Neopallium commented 1 year ago

Might be best to just use WebGL for now. WebGPU support is still very unstable both in browser support and Bevy support.

CaoKha commented 1 year ago

Thanks for the info!

CaoKha commented 1 year ago

Do the bevy WebGPU examples here work for you? https://bevyengine.org/examples-webgpu/

I am downloading Firefox nightly now, to try.

Yes, almost all the examples there with WebGPU works fine with my Firefox nightly. firefox-nightly

But yeah, there are some examples which didn't show anything or just failed to load their assets.