From 9d420b435ac3eae933926cc3086f9ab0983db2cb Mon Sep 17 00:00:00 2001 From: Waridley Date: Sat, 24 Feb 2024 01:46:00 -0600 Subject: [PATCH] Pad SkyUniforms to 16 bytes for WASM (#12078) # Objective Fixes Skyboxes on WebGL, which broke in Bevy 0.13 due to the addition of the `brightness` uniform, when previously the skybox pipeline only had view and global uniforms. ```ignore panicked at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.19.1/src/backend/wgpu_core.rs:3009:5: wgpu error: Validation Error Caused by: In Device::create_render_pipeline note: label = `skybox_pipeline` In the provided shader, the type given for group 0 binding 3 has a size of 4. As the device does not support `DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED`, the type must have a size that is a multiple of 16 bytes. ``` It would be nice if this could be backported to a 0.13.1 patch as well if possible. I'm needing to rely on my own fork for now. ## Solution Similar to the Globals uniform solution here: https://github.com/bevyengine/bevy/blob/d31de3f1398080661a83a04dcbdd31a7ee9fa76e/crates/bevy_render/src/globals.rs#L59-L60 I've added 3 conditional fields to `SkyboxUniforms`. --- crates/bevy_core_pipeline/src/skybox/mod.rs | 12 ++++++++++++ crates/bevy_core_pipeline/src/skybox/skybox.wgsl | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index c8c128325f..0144a988db 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -93,6 +93,12 @@ impl ExtractComponent for Skybox { skybox.clone(), SkyboxUniforms { brightness: skybox.brightness * exposure, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_8b: 0, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_12b: 0, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_16b: 0, }, )) } @@ -102,6 +108,12 @@ impl ExtractComponent for Skybox { #[derive(Component, ShaderType, Clone)] pub struct SkyboxUniforms { brightness: f32, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_8b: u32, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_12b: u32, + #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] + _wasm_padding_16b: u32, } #[derive(Resource)] diff --git a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl index cfbacf0e63..593b440ee4 100644 --- a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl @@ -1,10 +1,19 @@ #import bevy_render::view::View #import bevy_pbr::utils::coords_to_viewport_uv +struct SkyboxUniforms { + brightness: f32, +#ifdef SIXTEEN_BYTE_ALIGNMENT + _wasm_padding_8b: u32, + _wasm_padding_12b: u32, + _wasm_padding_16b: u32, +#endif +} + @group(0) @binding(0) var skybox: texture_cube; @group(0) @binding(1) var skybox_sampler: sampler; @group(0) @binding(2) var view: View; -@group(0) @binding(3) var brightness: f32; +@group(0) @binding(3) var uniforms: SkyboxUniforms; fn coords_to_ray_direction(position: vec2, viewport: vec4) -> vec3 { // Using world positions of the fragment and camera to calculate a ray direction @@ -63,5 +72,5 @@ fn skybox_fragment(in: VertexOutput) -> @location(0) vec4 { let ray_direction = coords_to_ray_direction(in.position.xy, view.viewport); // Cube maps are left-handed so we negate the z coordinate. - return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0)) * brightness; + return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0)) * uniforms.brightness; }