From fc5c1806b486ec86e685e637c56f44eb28ff6b3f Mon Sep 17 00:00:00 2001 From: Kevin Chen Date: Mon, 4 May 2026 00:52:30 -0400 Subject: [PATCH] Revert Screen Space Transmission Gate for Mesh Bind Groups (#24089) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective - Alongside #24086, helps with #24084, although I think we should double check any other added conditionals for bind group entries to make sure they are accurate. ## Solution So, originally the `SCREEN_SPACE_TRANSMISSION` was enabled with `key.intersects(MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS)`. However, a low quality transmission would make this false, since low’s MeshPipelineKey is configured like this: `const SCREEN_SPACE_SPECULAR_TRANSMISSION_LOW = 0 << Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS;`. So, a ScreenSpaceTransmission with Low Quality would break rendering (since another if-block merely checks that the `ScreenSpaceTransmission` component exists) Making it so that the low transmission truly does *not* include the view_transmission_textures makes the transmission render not properly - the spheres disappear! So, I think the proper fix here is to remove the gating around transmission textures. Edit: Another potential fix is to change the condition of the `intersects` but I’m not sure how to encode what we want unless we want to add another bit for `ScreenSpaceTransmission` component exists essentially? Happy to close this PR if that is an acceptable direction. ## Testing `cargo run --example transmission` works for all quality levels. --- crates/bevy_pbr/src/deferred/mod.rs | 3 - crates/bevy_pbr/src/render/mesh.rs | 4 -- .../bevy_pbr/src/render/mesh_view_bindings.rs | 56 ++++++++----------- .../src/render/mesh_view_bindings.wgsl | 2 - 4 files changed, 23 insertions(+), 42 deletions(-) diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 521ee66cae..e2b9450774 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -290,9 +290,6 @@ impl SpecializedRenderPipeline for DeferredLightingLayout { if key.contains(MeshPipelineKey::ATMOSPHERE) { shader_defs.push("ATMOSPHERE".into()); } - if key.intersects(MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS) { - shader_defs.push("SCREEN_SPACE_TRANSMISSION".into()); - } shader_defs.push("STANDARD_MATERIAL_CLEARCOAT".into()); // Always true, since we're in the deferred lighting pipeline diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index ad1981542d..253540c6db 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -3555,10 +3555,6 @@ impl SpecializedMeshPipeline for MeshPipeline { shader_defs.push("SHADOW_FILTER_METHOD_TEMPORAL".into()); } - if key.intersects(MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS) { - shader_defs.push("SCREEN_SPACE_TRANSMISSION".into()); - } - let blur_quality = key.intersection(MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS); diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 37e4b85a4e..ecec2a5620 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -1,7 +1,6 @@ use crate::{ - AreaLightLuts, DfgLut, ScreenSpaceTransmission, ViewEnvironmentMapUniformOffset, - ViewFogUniformOffset, ViewLightProbesUniformOffset, ViewLightsUniformOffset, - ViewScreenSpaceReflectionsUniformOffset, + AreaLightLuts, DfgLut, ViewEnvironmentMapUniformOffset, ViewFogUniformOffset, + ViewLightProbesUniformOffset, ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset, }; use bevy_core_pipeline::{ oit::{ @@ -94,10 +93,9 @@ bitflags::bitflags! { const SCREEN_SPACE_AMBIENT_OCCLUSION = 1 << 10; const IRRADIANCE_VOLUME = 1 << 11; const SCREEN_SPACE_REFLECTIONS = 1 << 12; - const SCREEN_SPACE_TRANSMISSION = 1 << 13; - const CONTACT_SHADOWS = 1 << 14; - const DISTANCE_FOG = 1 << 15; - const AREA_LIGHT_LUTS = 1 << 16; + const CONTACT_SHADOWS = 1 << 13; + const DISTANCE_FOG = 1 << 14; + const AREA_LIGHT_LUTS = 1 << 15; } } @@ -170,9 +168,6 @@ impl From for MeshPipelineViewLayoutKey { if value.contains(MeshPipelineKey::SCREEN_SPACE_REFLECTIONS) { result |= MeshPipelineViewLayoutKey::SCREEN_SPACE_REFLECTIONS; } - if value.intersects(MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS) { - result |= MeshPipelineViewLayoutKey::SCREEN_SPACE_TRANSMISSION; - } if value.contains(MeshPipelineKey::CONTACT_SHADOWS) { result |= MeshPipelineViewLayoutKey::CONTACT_SHADOWS; } @@ -408,16 +403,14 @@ fn layout_entries( } } - if layout_key.contains(MeshPipelineViewLayoutKey::SCREEN_SPACE_TRANSMISSION) { - // View Transmission Texture - entries = entries.extend_with_indices(( - ( - 25, - texture_2d(TextureSampleType::Float { filterable: true }), - ), - (26, sampler(SamplerBindingType::Filtering)), - )); - } + // View Transmission Texture + entries = entries.extend_with_indices(( + ( + 25, + texture_2d(TextureSampleType::Float { filterable: true }), + ), + (26, sampler(SamplerBindingType::Filtering)), + )); // OIT if layout_key.contains(MeshPipelineViewLayoutKey::OIT_ENABLED) { @@ -649,7 +642,7 @@ pub fn prepare_mesh_view_bind_groups( Option<&RenderViewLightProbes>, Option<&RenderViewLightProbes>, ), - (Has, Has), + Has, ( &ViewUniformOffset, &ViewLightsUniformOffset, @@ -728,7 +721,7 @@ pub fn prepare_mesh_view_bind_groups( atmosphere_textures, tonemapping, (render_view_environment_maps, render_view_irradiance_volumes), - (has_atmosphere, has_transmission), + has_atmosphere, ( view_uniform_offset, view_lights_offset, @@ -869,19 +862,16 @@ pub fn prepare_mesh_view_bind_groups( entries = entries.extend_with_indices(((17, ssao_view),)); } - if has_transmission { - layout_key |= MeshPipelineViewLayoutKey::SCREEN_SPACE_TRANSMISSION; - let transmission_view = transmission_texture - .map(|transmission| &transmission.view) - .unwrap_or(&fallback_image_zero.texture_view); + let transmission_view = transmission_texture + .map(|transmission| &transmission.view) + .unwrap_or(&fallback_image_zero.texture_view); - let transmission_sampler = transmission_texture - .map(|transmission| &transmission.sampler) - .unwrap_or(&fallback_image_zero.sampler); + let transmission_sampler = transmission_texture + .map(|transmission| &transmission.sampler) + .unwrap_or(&fallback_image_zero.sampler); - entries = entries - .extend_with_indices(((25, transmission_view), (26, transmission_sampler))); - } + entries = + entries.extend_with_indices(((25, transmission_view), (26, transmission_sampler))); // When using WebGL, we can't have a multisampled texture with `TEXTURE_BINDING` // See https://github.com/gfx-rs/wgpu/issues/5263 diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl b/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl index 93fc3af33e..6903b6a75c 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl @@ -103,10 +103,8 @@ const VISIBILITY_RANGE_UNIFORM_BUFFER_SIZE: u32 = 64u; @group(0) @binding(24) var deferred_prepass_texture: texture_2d; #endif // DEFERRED_PREPASS -#ifdef SCREEN_SPACE_TRANSMISSION @group(0) @binding(25) var view_transmission_texture: texture_2d; @group(0) @binding(26) var view_transmission_sampler: sampler; -#endif #ifdef OIT_ENABLED @group(0) @binding(27) var oit_settings: types::OrderIndependentTransparencySettings;