Skip to content

Bevy 3d_scene not working in WebGL2 on windows #23627

Closed

Description

@DGriffin91

From 87e716f to at least main 2e1acb9

  • The 2d_shapes example seems to work.
  • 3d rendering seems to work for me on MacOS and Linux in the browser (but not for @mockersf in CI).
  • Both firefox and chrome are affected.

Bisected the issue back to #23277 (wgpu update for v29)

ERROR /home/runner/.cargo/git/checkouts/bevy-50d7e162b728c6c6/d06aa47/crates/bevy_render/src/error_handler.rs:114 
Caught rendering error: Validation ErrorCaused by:  In a CommandEncoder    
In a set_pipeline command      
RenderPipeline with 'pbr_opaque_mesh_pipeline' label is invalid

Activity

  1. added
    C-BugAn unexpected or incorrect behavior
    S-Needs-TriageThis issue needs to be labelled
    on Apr 2, 2026
  2. added this to the 0.19 milestone on Apr 2, 2026
  3. added
    O-WindowsSpecific to the Windows desktop operating system
    I-RegressionFunctionality that used to work but no longer does. Add a test for this!
    A-RenderingDrawing game state to the screen
    O-WebGL2Specific to the WebGL2 render API
    and removed
    S-Needs-TriageThis issue needs to be labelled
    on Apr 2, 2026
  4. moved this to Needs SME Triage in Renderingon Apr 2, 2026
  5. dylansechet commented on Apr 2, 2026

    @dylansechet
    Contributor

    I can reproduce on linux by setting WGPU_SETTINGS_PRIO=webgl2, even though everything works fine in an actual browser.

    The issue seems related to hitting limits on the number of uniforms:

    ERROR bevy_render::error_handler: Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_pipeline_layout
        Too many bindings of type UniformBuffers in Stage ShaderStages(FRAGMENT), limit is 11, count was 13. Check the limit `max_uniform_buffers_per_shader_stage` passed to `Adapter::request_device`
    
    ERROR bevy_render::error_handler: Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_render_pipeline, label = 'pbr_opaque_mesh_pipeline'
        PipelineLayout with '' label is invalid
    
    ERROR RenderContextState::apply{system=<Enable the debug feature to see the name>}: bevy_render::error_handler: Caught rendering error: Validation Error
    
    Caused by:
      In a CommandEncoder
        In a set_pipeline command
          RenderPipeline with 'pbr_opaque_mesh_pipeline' label is invalid
    

    wgpu changed the way they calculate the number of bindings in wgu29 (in this PR), which I suspect is why we're only hitting this bug after the update.

  6. mockersf commented on Apr 3, 2026

    @mockersf
    Member

    I tried in CI and I have crashes on all os/browsers in webgl2:

    ERROR  crates/bevy_render/src/error_handler.rs:114  Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_bind_group_layout, label = 'sparse buffer update bind group layout'
        Too many bindings of type StorageBuffers in Stage ShaderStages(COMPUTE), limit is 0, count was 3. Check the limit `max_storage_buffers_per_shader_stage` passed to `Adapter::request_device`
    

    or

    %cERROR%c crates/bevy_render/src/error_handler.rs:114%c Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_pipeline_layout
        BindGroupLayout with 'sparse buffer update bind group layout' label is invalid
    
  7. greeble-dev commented on Apr 19, 2026

    @greeble-dev
    Contributor

    Just want to note that some of these validation errors were happening before the wgpu29 update.

    These errors were happening before the wgpu29 update, and do not appear to break 3d_scene.

    ERROR app: crates\bevy_render\src\error_handler.rs:114 Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_bind_group_layout, label = 'sparse buffer update bind group layout'
        Too many bindings of type StorageBuffers in Stage ShaderStages(COMPUTE), limit is 0, count was 3. Check the limit `max_storage_buffers_per_shader_stage` passed to `Adapter::request_device`
    
    ERROR app: crates\bevy_render\src\error_handler.rs:114 Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_pipeline_layout
        BindGroupLayout with 'sparse buffer update bind group layout' label is invalid
    
    ERROR app: crates\bevy_render\src\error_handler.rs:114 Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_compute_pipeline, label = 'sparse buffer update pipeline'
        PipelineLayout with '' label is invalid
    

    These errors appear after the wgpu29 update, where 3d_scene is broken:

    ERROR app: crates\bevy_render\src\error_handler.rs:114 Caught rendering error: Validation Error
    
    Caused by:
      In Device::create_pipeline_layout
        Too many bindings of type UniformBuffers in Stage ShaderStages(FRAGMENT), limit is 12, count was 13. Check the limit `max_uniform_buffers_per_shader_stage` passed to `Adapter::request_device`
    
    ERROR app: crates\bevy_render\src\error_handler.rs:114 Caught rendering error: Validation Error
    
    Caused by:
      In a CommandEncoder
        In a set_pipeline command
          RenderPipeline with 'pbr_opaque_mesh_pipeline' label is invalid
    
    

    Tested on Win10/Chrome.

  8. kfc35 commented on Apr 23, 2026

    @kfc35
    Contributor

    I did some investigation yesterday evening and here is what I came up with:

    • I’m able to reproduce this on DuckDuckGo on a Mac, which is when the max_uniform_buffers_per_shader_stage is 12. I cannot reproduce on Chrome because max_uniform_buffers_per_shader_stage is 16 there.
    • layout_entries in mesh_view_bindings.rs returns a Vec that has 12 Uniform buffers. OIT is not enabled when running the 3d_scene, but clustered_forward_buffer_binding_type and visibility_ranges_buffer_binding_type are both BufferBindingType::Uniform when running on the web. There are 7 calls to uniform_buffers in layout_entries, + 1 uniform buffer from environment_map_entries[3], and then there are 4 additional uniform buffers due to the *_buffer_binding_types being uniform.
    • The 13th Uniform buffer is added in SpecializeMeshPipeline::specialize via setup_morph_and_skinning_defs. The flags are all set to false, so it uses a model_only_layout. Because max_storage_buffers_per_shader_stage is 0, it ends up using another uniform buffer.

    I’m unsure of what the fix actually should be here, but that at least accounts for all the uniform buffers that are actually being used.

  9. added
    S-Needs-DesignThis issue requires design work to think about how it would best be accomplished
    and removed
    S-Needs-InvestigationThis issue requires detective work to figure out what's going wrong
    on Apr 23, 2026
  10. added
    S-Needs-ReviewNeeds reviewer attention (from anyone!) to move forward
    and removed
    S-Needs-DesignThis issue requires design work to think about how it would best be accomplished
    on Apr 26, 2026
  11. moved this from Needs SME Triage to Done in Renderingon May 1, 2026
  12. added a commit that references this issue on May 1, 2026
    6fcf9a6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorI-RegressionFunctionality that used to work but no longer does. Add a test for this!O-WebGL2Specific to the WebGL2 render APIO-WindowsSpecific to the Windows desktop operating systemS-Needs-ReviewNeeds reviewer attention (from anyone!) to move forward

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions