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:


d31de3f139/crates/bevy_render/src/globals.rs (L59-L60)

I've added 3 conditional fields to `SkyboxUniforms`.
This commit is contained in:
Waridley 2024-02-24 01:46:00 -06:00 committed by François
parent 784b9bd945
commit b1f061586d
2 changed files with 23 additions and 2 deletions

View file

@ -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)]

View file

@ -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<f32>;
@group(0) @binding(1) var skybox_sampler: sampler;
@group(0) @binding(2) var<uniform> view: View;
@group(0) @binding(3) var<uniform> brightness: f32;
@group(0) @binding(3) var<uniform> uniforms: SkyboxUniforms;
fn coords_to_ray_direction(position: vec2<f32>, viewport: vec4<f32>) -> vec3<f32> {
// 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<f32> {
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;
}