From 3945a6de3ba9645851ae03ad998a77bf5899d0df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Mockers?= Date: Fri, 28 Mar 2025 22:45:02 +0100 Subject: [PATCH] Fix wesl in wasm and webgl2 (#18591) # Objective - feature `shader_format_wesl` doesn't compile in Wasm - once fixed, example `shader_material_wesl` doesn't work in WebGL2 ## Solution - remove special path handling when loading shaders. this seems like a way to escape the asset folder which we don't want to allow, and can't compile on android or wasm, and can't work on iOS (filesystem is rooted there) - pad material so that it's 16 bits. I couldn't get conditional compilation to work in wesl for type declaration, it fails to parse - the shader renders the color `(0.0, 0.0, 0.0, 0.0)` when it's not a polka dot. this renders as black on WebGPU/metal/..., and white on WebGL2. change it to `(0.0, 0.0, 0.0, 1.0)` so that it's black everywhere --- assets/shaders/custom_material.wesl | 7 ++++--- assets/shaders/util.wesl | 4 ++-- .../bevy_render/src/render_resource/shader.rs | 20 +------------------ examples/shader/shader_material_wesl.rs | 7 ++++--- 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/assets/shaders/custom_material.wesl b/assets/shaders/custom_material.wesl index 2fd32fc923..5113e1cbe0 100644 --- a/assets/shaders/custom_material.wesl +++ b/assets/shaders/custom_material.wesl @@ -6,7 +6,8 @@ struct VertexOutput { } struct CustomMaterial { - time: f32, + // Needed for 16-bit alignment on WebGL2 + time: vec4, } @group(2) @binding(0) var material: CustomMaterial; @@ -15,5 +16,5 @@ struct CustomMaterial { fn fragment( mesh: VertexOutput, ) -> @location(0) vec4 { - return make_polka_dots(mesh.uv, material.time); -} \ No newline at end of file + return make_polka_dots(mesh.uv, material.time.x); +} diff --git a/assets/shaders/util.wesl b/assets/shaders/util.wesl index 52461fca48..ebbf023926 100644 --- a/assets/shaders/util.wesl +++ b/assets/shaders/util.wesl @@ -40,5 +40,5 @@ fn make_polka_dots(pos: vec2, time: f32) -> vec4 { is_dot = step(dist_from_center, 0.3 + wave_normalized * 0.2); } - return vec4(dot_color * is_dot, is_dot); -} \ No newline at end of file + return vec4(dot_color * is_dot, 1.0); +} diff --git a/crates/bevy_render/src/render_resource/shader.rs b/crates/bevy_render/src/render_resource/shader.rs index 62849a2f28..005fb07c05 100644 --- a/crates/bevy_render/src/render_resource/shader.rs +++ b/crates/bevy_render/src/render_resource/shader.rs @@ -163,26 +163,8 @@ impl Shader { match import_path { ShaderImport::AssetPath(asset_path) => { - let asset_path = std::path::PathBuf::from(&asset_path); - - // Get the base path and canonicalize it to match the format of the asset path - let mut base_path = bevy_asset::io::file::FileAssetReader::get_base_path(); - base_path.push("assets"); - let base_path = base_path.canonicalize().unwrap_or(base_path); - - // Try to make the path relative to the base path - let relative_path = match asset_path.canonicalize() { - Ok(canonical_asset_path) => { - match canonical_asset_path.strip_prefix(&base_path) { - Ok(rel_path) => rel_path.to_path_buf(), - Err(_) => canonical_asset_path, - } - } - Err(_) => asset_path, - }; - // Create the shader import path - always starting with "/" - let shader_path = std::path::Path::new("/").join(&relative_path); + let shader_path = std::path::Path::new("/").join(&asset_path); // Convert to a string with forward slashes and without extension let import_path_str = shader_path diff --git a/examples/shader/shader_material_wesl.rs b/examples/shader/shader_material_wesl.rs index 9261596f2d..108093de78 100644 --- a/examples/shader/shader_material_wesl.rs +++ b/examples/shader/shader_material_wesl.rs @@ -59,7 +59,7 @@ fn setup( commands.spawn(( Mesh3d(meshes.add(Cuboid::default())), MeshMaterial3d(materials.add(CustomMaterial { - time: 0.0, + time: Vec4::ZERO, party_mode: false, })), Transform::from_xyz(0.0, 0.5, 0.0), @@ -80,7 +80,7 @@ fn update( ) { for (material, mut transform) in query.iter_mut() { let material = materials.get_mut(material).unwrap(); - material.time = time.elapsed_secs(); + material.time.x = time.elapsed_secs(); if keys.just_pressed(KeyCode::Space) { material.party_mode = !material.party_mode; } @@ -95,8 +95,9 @@ fn update( #[derive(Asset, TypePath, AsBindGroup, Clone)] #[bind_group_data(CustomMaterialKey)] struct CustomMaterial { + // Needed for 16 bit alignment in WebGL2 #[uniform(0)] - time: f32, + time: Vec4, party_mode: bool, }