Disable irradiance volumes on WebGL and WebGPU. (#11909)

They cause the number of texture bindings to overflow on those
platforms. Ultimately, we shouldn't unconditionally disable them, but
this fixes a crash blocking 0.13.

Closes #11885.
This commit is contained in:
Patrick Walton 2024-02-16 17:49:46 -08:00 committed by GitHub
parent 8127d44daa
commit 3058c17d6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 14 deletions

View File

@ -157,6 +157,11 @@ use super::LightProbeComponent;
pub const IRRADIANCE_VOLUME_SHADER_HANDLE: Handle<Shader> = pub const IRRADIANCE_VOLUME_SHADER_HANDLE: Handle<Shader> =
Handle::weak_from_u128(160299515939076705258408299184317675488); 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. /// The component that defines an irradiance volume.
/// ///
/// See [`crate::irradiance_volume`] for detailed information. /// See [`crate::irradiance_volume`] for detailed information.

View File

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

View File

@ -50,6 +50,8 @@ use crate::render::{
}; };
use crate::*; use crate::*;
use self::irradiance_volume::IRRADIANCE_VOLUMES_ARE_USABLE;
use super::skin::SkinIndices; use super::skin::SkinIndices;
#[derive(Default)] #[derive(Default)]
@ -825,7 +827,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs.push("ENVIRONMENT_MAP".into()); 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()); shader_defs.push("IRRADIANCE_VOLUME".into());
} }
@ -865,6 +867,10 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs.push("MULTIPLE_LIGHT_PROBES_IN_ARRAY".into()); 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) { let format = if key.contains(MeshPipelineKey::HDR) {
ViewTarget::TEXTURE_FORMAT_HDR ViewTarget::TEXTURE_FORMAT_HDR
} else { } else {

View File

@ -33,7 +33,10 @@ use environment_map::EnvironmentMapLight;
use crate::{ use crate::{
environment_map::{self, RenderViewEnvironmentMapBindGroupEntries}, 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, prepass, FogMeta, GlobalLightMeta, GpuFog, GpuLights, GpuPointLights, LightMeta,
LightProbesBuffer, LightProbesUniform, MeshPipeline, MeshPipelineKey, RenderViewLightProbes, LightProbesBuffer, LightProbesUniform, MeshPipeline, MeshPipelineKey, RenderViewLightProbes,
ScreenSpaceAmbientOcclusionTextures, ShadowSamplers, ViewClusterBindings, ViewShadowBindings, ScreenSpaceAmbientOcclusionTextures, ShadowSamplers, ViewClusterBindings, ViewShadowBindings,
@ -269,11 +272,14 @@ fn layout_entries(
)); ));
// Irradiance volumes // Irradiance volumes
let irradiance_volume_entries = irradiance_volume::get_bind_group_layout_entries(render_device); if IRRADIANCE_VOLUMES_ARE_USABLE {
entries = entries.extend_with_indices(( let irradiance_volume_entries =
(16, irradiance_volume_entries[0]), irradiance_volume::get_bind_group_layout_entries(render_device);
(17, irradiance_volume_entries[1]), entries = entries.extend_with_indices((
)); (16, irradiance_volume_entries[0]),
(17, irradiance_volume_entries[1]),
));
}
// Tonemapping // Tonemapping
let tonemapping_lut_entries = get_lut_bind_group_layout_entries(); let tonemapping_lut_entries = get_lut_bind_group_layout_entries();
@ -459,28 +465,32 @@ pub fn prepare_mesh_view_bind_groups(
} }
} }
let irradiance_volume_bind_group_entries = let irradiance_volume_bind_group_entries = if IRRADIANCE_VOLUMES_ARE_USABLE {
RenderViewIrradianceVolumeBindGroupEntries::get( Some(RenderViewIrradianceVolumeBindGroupEntries::get(
render_view_irradiance_volumes, render_view_irradiance_volumes,
&images, &images,
&fallback_image, &fallback_image,
&render_device, &render_device,
); ))
} else {
None
};
match irradiance_volume_bind_group_entries { match irradiance_volume_bind_group_entries {
RenderViewIrradianceVolumeBindGroupEntries::Single { Some(RenderViewIrradianceVolumeBindGroupEntries::Single {
texture_view, texture_view,
sampler, sampler,
} => { }) => {
entries = entries.extend_with_indices(((16, texture_view), (17, sampler))); entries = entries.extend_with_indices(((16, texture_view), (17, sampler)));
} }
RenderViewIrradianceVolumeBindGroupEntries::Multiple { Some(RenderViewIrradianceVolumeBindGroupEntries::Multiple {
ref texture_views, ref texture_views,
sampler, sampler,
} => { }) => {
entries = entries entries = entries
.extend_with_indices(((16, texture_views.as_slice()), (17, sampler))); .extend_with_indices(((16, texture_views.as_slice()), (17, sampler)));
} }
None => {}
} }
let lut_bindings = get_lut_bindings(&images, &tonemapping_luts, tonemapping); let lut_bindings = get_lut_bindings(&images, &tonemapping_luts, tonemapping);

View File

@ -46,12 +46,14 @@
#endif #endif
@group(0) @binding(15) var environment_map_sampler: sampler; @group(0) @binding(15) var environment_map_sampler: sampler;
#ifdef IRRADIANCE_VOLUMES_ARE_USABLE
#ifdef MULTIPLE_LIGHT_PROBES_IN_ARRAY #ifdef MULTIPLE_LIGHT_PROBES_IN_ARRAY
@group(0) @binding(16) var irradiance_volumes: binding_array<texture_3d<f32>, 8u>; @group(0) @binding(16) var irradiance_volumes: binding_array<texture_3d<f32>, 8u>;
#else #else
@group(0) @binding(16) var irradiance_volume: texture_3d<f32>; @group(0) @binding(16) var irradiance_volume: texture_3d<f32>;
#endif #endif
@group(0) @binding(17) var irradiance_volume_sampler: sampler; @group(0) @binding(17) var irradiance_volume_sampler: sampler;
#endif
// NB: If you change these, make sure to update `tonemapping_shared.wgsl` too. // NB: If you change these, make sure to update `tonemapping_shared.wgsl` too.
@group(0) @binding(18) var dt_lut_texture: texture_3d<f32>; @group(0) @binding(18) var dt_lut_texture: texture_3d<f32>;