Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bevy 0.12 panics when loading a skinned GLTF mesh with shadow-enabled directional light in WASM #10509

Closed
idanarye opened this issue Nov 11, 2023 · 11 comments
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior O-WebGL2 Specific to the WebGL2 render API

Comments

@idanarye
Copy link

Bevy version

Bevy v0.12.0

[Optional] Relevant system information

  • the Rust version you're using (you can get this by running cargo --version)
    I get this both when building locally and
    $ cargo --version
    
    cargo 1.73.0 (9c4383fb5 2023-08-26)
  • the operating system or browser used, including its version
    $ uname -srvmpio
    
    Linux 6.5.9-arch2-1 #1 SMP PREEMPT_DYNAMIC Thu, 26 Oct 2023 00:52:20 +0000 x86_64 unknown unknown GNU/Linux
    This is a WASM bug though, so the browser version is probably more important:
    $ firefox --full-version
    
    Mozilla Firefox 119.0 20231023160744 20231023160744 

If your bug is rendering-related, copy the adapter info that appears when you run Bevy.

Formatted for readability:

INFO /home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_render-0.12.0/src/renderer/mod.rs:140 AdapterInfo {
    name: "NVIDIA GeForce GTX 980/PCIe/SSE2",
    vendor: 4318,
    device: 0,
    device_type: Other,
    driver: "",
    driver_info: "",
    backend: Gl
}

What you did

  1. Created a simple skinned mesh in Blender - I just added an armature to the startup cube (without automatic weights). Didn't even animate it.
  2. Exported to GLTF (bug replicates with either GLTF or GLB)
  3. Loaded the GLTF it in Bevy.
  4. Added a directional light with shadows.
  5. Built it for WASM, with the WebGL2 backend.
  6. Tried to run it in the browser.

Note that this is a minimal example. If I don't add an armature - the bug does not replicate. If I don't enable shadows on the directional lights - the bug does not replicate. I have no idea how these two are related...

Here is a repository that demonstrates the problem: https://github.com/idanarye/demonstrate-bevy-0.12-wasm-shadows-bug

What went wrong

  • what were you expecting? - The model to show without panicing, as it does with Bevy 0.11
  • what actually happened? - on Bevy 0.12, it does not show the model, and panics with the following error and stack trace:
    panicked at 'No uniform for push constant', /home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-hal-0.17.2/src/gles/command.rs:725:17
    
    Stack:
    
    __wbg_get_imports/imports.wbg.__wbg_new_abda76e883ba8a5f@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:401:21
    console_error_panic_hook::hook::h810134e5e71475d7@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[12678]:0x1072fd2
    core::ops::function::Fn::call::hd416b0b98723df16@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[61618]:0x162d96b
    std::panicking::rust_panic_with_hook::h5cee2a9564faeb6d@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[22527]:0x13b7029
    std::panicking::begin_panic_handler::{{closure}}::h38a949ca54e64e6b@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[26190]:0x146183c
    std::sys_common::backtrace::__rust_end_short_backtrace::hc4f3d2fd3090193f@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[60893]:0x162c01a
    rust_begin_unwind@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[34172]:0x155d6d5
    core::panicking::panic_fmt::h8a19fa1eb63fbb67@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[37376]:0x159a8a4
    wgpu_hal::gles::command::<impl wgpu_hal::CommandEncoder<wgpu_hal::gles::Api> for wgpu_hal::gles::CommandEncoder>::set_push_constants::haa0ecf7056cb7ae8@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[13562]:0x10dc2c0
    wgpu_core::command::render::<impl wgpu_core::global::Global<G>>::command_encoder_run_render_pass_impl::h9147f31103eb7ab8@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[431]:0xcd969
    <wgpu::backend::direct::Context as wgpu::context::Context>::command_encoder_end_render_pass::h55fd06be94875af7@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[2700]:0x801c7c
    <T as wgpu::context::DynContext>::command_encoder_end_render_pass::had3876df2f7853d3@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[36008]:0x1582dbe
    <wgpu::RenderPass as core::ops::drop::Drop>::drop::h14e549d452e2b093@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[28777]:0x14c3d9b
    <bevy_pbr::render::light::ShadowPassNode as bevy_render::render_graph::node::Node>::run::hcc2fd584a282e0c6@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[7648]:0xd68514
    bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph::h9ec389af8302ff13@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[547]:0x23f95c
    bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph::h9ec389af8302ff13@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[547]:0x23fad1
    bevy_render::renderer::graph_runner::RenderGraphRunner::run::h2c80c4203cc4cb19@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[6118]:0xc2086b
    bevy_render::renderer::render_system::h5c5451905bb4512a@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[884]:0x3ead92
    <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run::h9eb783eb279173d7@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[36238]:0x158744a
    <bevy_ecs::schedule::executor::single_threaded::SingleThreadedExecutor as bevy_ecs::schedule::executor::SystemExecutor>::run::h603e5a5c4d0b1965@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[1598]:0x5ed68d
    bevy_ecs::schedule::schedule::Schedule::run::hfe5020fa9d98a947@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[20325]:0x1336368
    bevy_ecs::world::World::schedule_scope::had99d41c0e09f8c0@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[6187]:0xc30f51
    bevy_app::app::App::update::h77e2765c8f6c80f3@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[20747]:0x135195e
    winit::platform_impl::platform::event_loop::EventLoop<T>::spawn::{{closure}}::h56d5bff1e1a4edac@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[470]:0x178b5f
    winit::platform_impl::platform::event_loop::runner::Shared<T>::handle_event::h56dd87b15f500875@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[4311]:0xa42367
    winit::platform_impl::platform::event_loop::runner::Shared<T>::run_until_cleared::hed4a735001e2e75e@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[6526]:0xc7c948
    winit::platform_impl::platform::backend::timeout::AnimationFrameRequest::new::{{closure}}::h52e469b6a796274b@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[36916]:0x1593190
    <dyn core::ops::function::FnMut<()>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h126391ccdb7bc256@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:wasm-function[41621]:0x15ccaa1
    __wbg_adapter_51@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:222:10
    real@https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:203:20
    
    
    bevy_github_ci_template.js:417:21
        __wbg_error_f851667af71bcfc6 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:417
        h810134e5e71475d7 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:17248425
        hd416b0b98723df16 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:23255403
        h5cee2a9564faeb6d https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:20672553
        h38a949ca54e64e6b https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:21370940
        hc4f3d2fd3090193f https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:23248922
        rust_begin_unwind https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22402773
        h8a19fa1eb63fbb67 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22653092
        wgpu_hal::gles::command::<impl wgpu_hal::CommandEncoder<wgpu_hal::gles::Api> for wgpu_hal::gles::CommandEncoder>::set_push_constants::haa0ecf7056cb7ae8 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:17679040
        wgpu_core::command::render::<impl wgpu_core::global::Global<G>>::command_encoder_run_render_pass_impl::h9147f31103eb7ab8 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:842089
        <wgpu::backend::direct::Context as wgpu::context::Context>::command_encoder_end_render_pass::h55fd06be94875af7 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:8395900
        <T as wgpu::context::DynContext>::command_encoder_end_render_pass::had3876df2f7853d3 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22556094
        <wgpu::RenderPass as core::ops::drop::Drop>::drop::h14e549d452e2b093 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:21773723
        <bevy_pbr::render::light::ShadowPassNode as bevy_render::render_graph::node::Node>::run::hcc2fd584a282e0c6 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:14058772
        h9ec389af8302ff13 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:2357596
        h9ec389af8302ff13 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:2357969
        h2c80c4203cc4cb19 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:12716139
        h5c5451905bb4512a https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:4107666
        <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run::h9eb783eb279173d7 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22574154
        <bevy_ecs::schedule::executor::single_threaded::SingleThreadedExecutor as bevy_ecs::schedule::executor::SystemExecutor>::run::h603e5a5c4d0b1965 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:6215309
        hfe5020fa9d98a947 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:20145000
        had99d41c0e09f8c0 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:12783441
        h77e2765c8f6c80f3 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:20257118
        h56d5bff1e1a4edac https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:1543007
        h56dd87b15f500875 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:10756967
        hed4a735001e2e75e https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:13093192
        h52e469b6a796274b https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22622608
        <dyn core::ops::function::FnMut<()>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h126391ccdb7bc256 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template_bg.wasm:22858401
        __wbg_adapter_51 https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:222
        real https://idanarye.github.io/demonstrate-bevy-0.12-wasm-shadows-bug/bevy-0.12/bevy_github_ci_template.js:203
    
@idanarye idanarye added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Nov 11, 2023
@superdump
Copy link
Contributor

I think on webgl2 we had to add a workaround for the base instance index not being part of the instance index value and we had to get the base instance index into the shader via a push constant. I think the bug is something to do with that but can’t look into it right now. See instance_index.wgsl and its get_instance_index function.

@JMS55 JMS55 added A-Rendering Drawing game state to the screen O-WebGL2 Specific to the WebGL2 render API and removed S-Needs-Triage This issue needs to be labelled labels Nov 12, 2023
@JMS55 JMS55 added this to the 0.12.1 milestone Nov 12, 2023
@cart
Copy link
Member

cart commented Nov 16, 2023

Just repro-ed with the animated_fox example.

@DGriffin91
Copy link
Contributor

It looks like animated_fox works on bevy main. Was there a PR that fixed this?

Also discussion about possible workaround on discord: https://discord.com/channels/691052431525675048/743663924229963868/1174881166705315880

@cart
Copy link
Member

cart commented Nov 22, 2023

Following up: sounds like this is only broken on some platform configurations. Still broken, but so far only reproducible on linux + nvidia.

@ramirezmike
Copy link
Contributor

Following up: sounds like this is only broken on some platform configurations. Still broken, but so far only reproducible on linux + nvidia.

and linux + integrated radeon graphics 👍

@cart
Copy link
Member

cart commented Nov 23, 2023

A summary of the problem:

  1. As of Bevy 0.12, we're using a new approach to accessing mesh information that relies on @builtin(instance_index). Sadly, current versions of wgpu do not support instance_index on WebGL2 (main does support this but there has not been a release yet), so we worked around this with push constants (which are emulated as uniforms via wgpu because WebGL2 doesn't natively support push constants).
  2. Sadly, we've discovered that wgpu also has issues with push constants on WebGL 2. Again, this has been fixed on main, but does not have a release yet

@cwfitzgerald let us know that one way to work around this is to ensure that every shader uses the push constant. Sure enough, by adding this to prepass.wgsl, we do fix the problem:

#ifdef VERTEX_OUTPUT_INSTANCE_INDEX
    out.instance_index = get_instance_index(vertex_no_morph.instance_index);
#endif
    // Hack: adding this line ensures the push constant is always used, as get_instance_index accesses the push constant
    out.position.x += f32(get_instance_index(0u)) * 0.00001;
    return out;
}

However, this breaks down the second a shader is used that doesn't use the push constant. Therefore it is not a "real" fix, although it does make simple examples work / any game that sticks with the built in materials + shaders.

Therefore as a short term solution I think we should roll with this.

One medium term-solution is to cut out the "push constant" entirely and use a uniform buffer. Given that this is what wgpu's WebGL2 push constant emulation is doing anyway, thats actually not too big of a deal. This will take a bit of engineering work to update our data flow.

The long-term solution is to wait for the next wgpu release so we can use instance_index everywhere.

@cwfitzgerald
Copy link

Given that this is what wgpu's WebGL2 push constant emulation is doing anyway,

This isn't actually true, we emulate them using gl uniforms which are closer to push constants than a proper buffer. If this change is made, once 0.19 comes out, it probably should be rolled back.

@cart
Copy link
Member

cart commented Nov 23, 2023

Makes sense. Thanks!

github-merge-queue bot pushed a commit that referenced this issue Nov 28, 2023
…10706)

# Objective

 Kind of helps #10509 

## Solution

Add a line to `prepass.wgsl` that ensure the `instance_index` push
constant is always used on WebGL 2. This is not a full fix, as the
_second_ a custom shader is used that doesn't use the push constant, the
breakage will resurface. We have satisfying medium term and long term
solutions. This is just a short term hack for 0.12.1 that will make more
cases work. See #10509 for more details.
@cart cart modified the milestones: 0.12.1, 0.13 Nov 28, 2023
@cart
Copy link
Member

cart commented Nov 28, 2023

Moving to 0.13 as we have kind of mitigated this for 0.12.1 with #10706

cart added a commit that referenced this issue Nov 30, 2023
…10706)

# Objective

 Kind of helps #10509 

## Solution

Add a line to `prepass.wgsl` that ensure the `instance_index` push
constant is always used on WebGL 2. This is not a full fix, as the
_second_ a custom shader is used that doesn't use the push constant, the
breakage will resurface. We have satisfying medium term and long term
solutions. This is just a short term hack for 0.12.1 that will make more
cases work. See #10509 for more details.
@alice-i-cecile alice-i-cecile removed this from the 0.13 milestone Jan 24, 2024
@rparrett
Copy link
Contributor

rparrett commented Feb 8, 2024

Did wgpu 0.19 fix this?

@rparrett
Copy link
Contributor

Seems like the entire mechanism for working around this was removed in #11280, and my code that previously used the workaround seems to work fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior O-WebGL2 Specific to the WebGL2 render API
Projects
None yet
Development

No branches or pull requests

9 participants