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

Disable irradiance volumes on WebGL and WebGPU. #11909

Merged
merged 1 commit into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/bevy_pbr/src/light_probe/irradiance_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ use super::LightProbeComponent;
pub const IRRADIANCE_VOLUME_SHADER_HANDLE: Handle<Shader> =
Handle::weak_from_u128(160299515939076705258408299184317675488);

/// On WebGL and WebGPU, we must disable irradiance volumes, as otherwise we can
/// overflow the number of texture bindings when deferred rendering is in use
/// (see issue #11885).
pub(crate) const IRRADIANCE_VOLUMES_ARE_USABLE: bool = cfg!(not(target_arch = "wasm32"));

/// The component that defines an irradiance volume.
///
/// See [`crate::irradiance_volume`] for detailed information.
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_pbr/src/light_probe/irradiance_volume.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
light_probes,
};

#ifdef IRRADIANCE_VOLUMES_ARE_USABLE

// See:
// https://advances.realtimerendering.com/s2006/Mitchell-ShadingInValvesSourceEngine.pdf
// Slide 28, "Ambient Cube Basis"
Expand Down Expand Up @@ -50,3 +52,5 @@ fn irradiance_volume_light(world_position: vec3<f32>, N: vec3<f32>) -> vec3<f32>
let NN = N * N;
return (rgb_x * NN.x + rgb_y * NN.y + rgb_z * NN.z) * query_result.intensity;
}

#endif // IRRADIANCE_VOLUMES_ARE_USABLE
8 changes: 7 additions & 1 deletion crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ use crate::render::{
};
use crate::*;

use self::irradiance_volume::IRRADIANCE_VOLUMES_ARE_USABLE;

use super::skin::SkinIndices;

#[derive(Default)]
Expand Down Expand Up @@ -825,7 +827,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs.push("ENVIRONMENT_MAP".into());
}

if key.contains(MeshPipelineKey::IRRADIANCE_VOLUME) {
if key.contains(MeshPipelineKey::IRRADIANCE_VOLUME) && IRRADIANCE_VOLUMES_ARE_USABLE {
shader_defs.push("IRRADIANCE_VOLUME".into());
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just reuse this shader_def instead of using a separate one?

Copy link
Member

Choose a reason for hiding this comment

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

I think there are two reasons:

  1. MeshPipelineKey::IRRADIANCE_VOLUME is currently getting set in scenes like deferred_rendering.rs, even when irradiance volumes aren't used.
  2. IRRADIANCE_VOLUMES_ARE_USABLE is used in a few places unconditionally outside of the context of shader defs.

Copy link
Member

Choose a reason for hiding this comment

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

I think for now we merge as-is. This isn't hurting anything and we're likely to improve this situation in the future.

}

Expand Down Expand Up @@ -865,6 +867,10 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs.push("MULTIPLE_LIGHT_PROBES_IN_ARRAY".into());
}

if IRRADIANCE_VOLUMES_ARE_USABLE {
shader_defs.push("IRRADIANCE_VOLUMES_ARE_USABLE".into());
}

let format = if key.contains(MeshPipelineKey::HDR) {
ViewTarget::TEXTURE_FORMAT_HDR
} else {
Expand Down
36 changes: 23 additions & 13 deletions crates/bevy_pbr/src/render/mesh_view_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ use environment_map::EnvironmentMapLight;

use crate::{
environment_map::{self, RenderViewEnvironmentMapBindGroupEntries},
irradiance_volume::{self, IrradianceVolume, RenderViewIrradianceVolumeBindGroupEntries},
irradiance_volume::{
self, IrradianceVolume, RenderViewIrradianceVolumeBindGroupEntries,
IRRADIANCE_VOLUMES_ARE_USABLE,
},
prepass, FogMeta, GlobalLightMeta, GpuFog, GpuLights, GpuPointLights, LightMeta,
LightProbesBuffer, LightProbesUniform, MeshPipeline, MeshPipelineKey, RenderViewLightProbes,
ScreenSpaceAmbientOcclusionTextures, ShadowSamplers, ViewClusterBindings, ViewShadowBindings,
Expand Down Expand Up @@ -269,11 +272,14 @@ fn layout_entries(
));

// Irradiance volumes
let irradiance_volume_entries = irradiance_volume::get_bind_group_layout_entries(render_device);
entries = entries.extend_with_indices((
(16, irradiance_volume_entries[0]),
(17, irradiance_volume_entries[1]),
));
if IRRADIANCE_VOLUMES_ARE_USABLE {
let irradiance_volume_entries =
irradiance_volume::get_bind_group_layout_entries(render_device);
entries = entries.extend_with_indices((
(16, irradiance_volume_entries[0]),
(17, irradiance_volume_entries[1]),
));
}

// Tonemapping
let tonemapping_lut_entries = get_lut_bind_group_layout_entries();
Expand Down Expand Up @@ -459,28 +465,32 @@ pub fn prepare_mesh_view_bind_groups(
}
}

let irradiance_volume_bind_group_entries =
RenderViewIrradianceVolumeBindGroupEntries::get(
let irradiance_volume_bind_group_entries = if IRRADIANCE_VOLUMES_ARE_USABLE {
Some(RenderViewIrradianceVolumeBindGroupEntries::get(
render_view_irradiance_volumes,
&images,
&fallback_image,
&render_device,
);
))
} else {
None
};

match irradiance_volume_bind_group_entries {
RenderViewIrradianceVolumeBindGroupEntries::Single {
Some(RenderViewIrradianceVolumeBindGroupEntries::Single {
texture_view,
sampler,
} => {
}) => {
entries = entries.extend_with_indices(((16, texture_view), (17, sampler)));
}
RenderViewIrradianceVolumeBindGroupEntries::Multiple {
Some(RenderViewIrradianceVolumeBindGroupEntries::Multiple {
ref texture_views,
sampler,
} => {
}) => {
entries = entries
.extend_with_indices(((16, texture_views.as_slice()), (17, sampler)));
}
None => {}
}

let lut_bindings = get_lut_bindings(&images, &tonemapping_luts, tonemapping);
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_pbr/src/render/mesh_view_bindings.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@
#endif
@group(0) @binding(15) var environment_map_sampler: sampler;

#ifdef IRRADIANCE_VOLUMES_ARE_USABLE
#ifdef MULTIPLE_LIGHT_PROBES_IN_ARRAY
@group(0) @binding(16) var irradiance_volumes: binding_array<texture_3d<f32>, 8u>;
#else
@group(0) @binding(16) var irradiance_volume: texture_3d<f32>;
#endif
@group(0) @binding(17) var irradiance_volume_sampler: sampler;
#endif

// NB: If you change these, make sure to update `tonemapping_shared.wgsl` too.
@group(0) @binding(18) var dt_lut_texture: texture_3d<f32>;
Expand Down