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

[Merged by Bors] - enable Webgl2 optimisation in pbr under feature #3291

Closed
wants to merge 13 commits into from

Conversation

mockersf
Copy link
Member

Objective

  • 3d examples fail to run in webgl2 because of unsupported texture formats or texture too large

Solution

  • switch to supported formats if a feature is enabled. I choose a feature instead of a build target to not conflict with a potential webgpu support

Very inspired by superdump@6813b2e, and need #3290 to work.

I named the feature webgl2, but it's only needed if one want to use PBR in webgl2. Examples using only 2D already work.

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Dec 10, 2021
@mockersf mockersf added A-Rendering Drawing game state to the screen and removed S-Needs-Triage This issue needs to be labelled labels Dec 10, 2021
@TheRawMeatball
Copy link
Member

Personally I'd prefer if this was chosen by default for wasm targets, since webgpu is still in beta and IMO it's more important for the common case to "just work". We could revisit this later when webgpu support is rolled out to stable browsers.

@mockersf
Copy link
Member Author

There is already a mostly working webgpu support: https://discord.com/channels/691052431525675048/750833140746158140/915727141130338385

@TheRawMeatball
Copy link
Member

WGPU's webgpu backend being mostly complete is irrelevant IMO since webgpu isn't available on any stable browsers. Right now, people will still be only using webgl2 for any releases since that's the only backend that's actually supported by browsers.

A potential option here could be to check whether wgpu itself is running on webgpu or webgl2 dynamically though.

@mrk-its
Copy link
Member

mrk-its commented Dec 10, 2021

A potential option here could be to check whether wgpu itself is running on webgpu or webgl2 dynamically though.

Now it is not possible AFAIR - wgpu uses webgl feature to select between webgpu and webgl2.

So I would prefer to rename this feature from webgl2 to webgl to be compatible with wgpu. And maybe let's simply add it to bevy's default features to make it default on wasm32?

@cart cart added this to the Bevy 0.6 milestone Dec 10, 2021
Copy link
Contributor

@superdump superdump left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mostly looks good to me. I think it's a good idea to get something like this in for now rather than waiting on implementing the wgpu downlevel/feature/limits stuff. My only change is that I think WebGL2 supports array textures, but not cube array textures, so I think the shader def should be changed to reflect that. I would approve otherwise. :)

And as WebGL2 is supported in browsers where WebGPU is behind developer flags still, I think, then it makes sense to make webgl the default as @mrk-its proposed for now. Later when the landscape changes I guess it will make sense to change the default behaviour. What do you think on this one @cart?

@@ -469,6 +475,9 @@ impl SpecializedPipeline for MeshPipeline {
depth_write_enabled = true;
}

#[cfg(feature = "webgl2")]
shader_defs.push(String::from("NO_ARRAY_TEXTURES_SUPPORT"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is specifically no cube array texture support.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

textures of type D2Array seems to be an issue too, if I don't change them to D2 I don't have shadows for directional lights

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok. Well then I guess this is fine. :)

@mockersf
Copy link
Member Author

And maybe let's simply add it to bevy's default features to make it default on wasm32?

I can either add it as a default feature, which means that everyone will have by default only one point light, and the no array textures, or add it as a feature already selected for wasm target, wich means it won't be possible to disable it on wasm. As far as I know there are no way to specify default feature set by target, rust-lang/cargo#1197 (comment) would be needed for that.

@mockersf mockersf added the O-Web Specific to web (WASM) builds label Dec 11, 2021
@mockersf
Copy link
Member Author

actually bevy_render2 was already enabling wgpu/webgl based on target, so I did the same for this feature, and moved control for bevy_render2 and bevy_pbr2 to a single point in bevy_internal

@mockersf
Copy link
Member Author

mockersf commented Dec 12, 2021

on macOS this works on chrome and firefox but it crashes safari... wgpu examples are working with safari, so maybe an issue on Bevy side

Firefox is logging this warning:

WebGL warning: getBufferSubData: Reading from a buffer with usage other than *_READ causes pipeline stalls. Copy through a STREAM_READ buffer.

and it seems that safari is crashing when calling getBufferSubData

Could we have a buffer somewhere that should be marked as read and isn't?

Chrome is working bug logs

UNSUPPORTED (log once): gldCopyBufferSubData: NEEDS IMPLEMENTATION

so... yeah Chrome 🎉

After some digging, it seems getBufferSubData is called for the vertex buffer of each mesh

@mockersf mockersf force-pushed the webgl2-under-feature branch 2 times, most recently from 30a3310 to 25bf2eb Compare December 19, 2021 08:58
@mockersf
Copy link
Member Author

mockersf commented Dec 19, 2021

with the wgpu update, 3D examples fails with a new error on Safari:

panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `pbr_opaque_mesh_pipeline`
    Internal error in VERTEX | FRAGMENT | VERTEX_FRAGMENT shader: Name conflicts between uniform block field names: _group_0_binding_0

Not sure how to fix that 😞 UI and 2D examples work on safari though

@superdump
Copy link
Contributor

group 0 binding 0 is the View uniform. The mesh pipeline uses the same shader handle for both vertex and fragment stages. The pbr pipeline specialises the mesh pipeline and uses a different shader for the fragment stage. I wonder if the vertex stage shader (mesh.wgsl) containing a fragment entrypoint with the same name (fragment) as the overridden fragment stage shader (pbr.wgsl) that's confusing it somehow...?

@mockersf
Copy link
Member Author

Yup, and somebody did not read the // NOTE:

// NOTE: Keep in sync with pbr.wgsl
struct View {
view_proj: mat4x4<f32>;
projection: mat4x4<f32>;
world_position: vec3<f32>;
};

struct View {
view_proj: mat4x4<f32>;
inverse_view: mat4x4<f32>;
projection: mat4x4<f32>;
world_position: vec3<f32>;
near: f32;
far: f32;
width: f32;
height: f32;
};

but copy pasting to have the same in both didn't fix the issue...

@superdump
Copy link
Contributor

depth is used for the shadow pass. But I also noted that and I wondered how shadows are even working. Hmm...

@mockersf
Copy link
Member Author

crashes with Safari are due to gfx-rs/naga#1617

@cart
Copy link
Member

cart commented Dec 22, 2021

This all looks reasonable to me. I can confirm that this works with the naga fixes:
image

@cart
Copy link
Member

cart commented Dec 22, 2021

Firefox perf is quite bad. But chrome seems smooth (didn't do any actual frametime measurements).

@cart
Copy link
Member

cart commented Dec 22, 2021

bors r+

bors bot pushed a commit that referenced this pull request Dec 22, 2021
# Objective

- 3d examples fail to run in webgl2 because of unsupported texture formats or texture too large

## Solution

- switch to supported formats if a feature is enabled. I choose a feature instead of a build target to not conflict with a potential webgpu support

Very inspired by superdump@6813b2e, and need #3290 to work.

I named the feature `webgl2`, but it's only needed if one want to use PBR in webgl2. Examples using only 2D already work.

Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
@bors bors bot changed the title enable Webgl2 optimisation in pbr under feature [Merged by Bors] - enable Webgl2 optimisation in pbr under feature Dec 22, 2021
@bors bors bot closed this Dec 22, 2021
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 O-Web Specific to web (WASM) builds
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants