From 3ced49f6723df6e97539dced5655b8bde23a3dac Mon Sep 17 00:00:00 2001 From: IceSentry Date: Mon, 10 Jun 2024 09:26:43 -0400 Subject: [PATCH] Make FOG_ENABLED a shader_def instead of material flag (#13783) # Objective - If the fog is disabled it still generates a useless branch which can hurt performance ## Solution - Make the flag a shader_def instead ## Testing - I tested enabling/disabling fog works as expected per-material in the fog example - I also tested that scenes that don't add the FogSettings resource still work correctly ## Review notes I'm not sure how to handle the removed material flag. Right now I just commented it out and added a not to reuse it instead of creating a new one. --- crates/bevy_pbr/src/deferred/pbr_deferred_types.wgsl | 7 ++----- crates/bevy_pbr/src/pbr_material.rs | 8 ++++---- crates/bevy_pbr/src/render/pbr_functions.wgsl | 4 +++- crates/bevy_pbr/src/render/pbr_types.wgsl | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/bevy_pbr/src/deferred/pbr_deferred_types.wgsl b/crates/bevy_pbr/src/deferred/pbr_deferred_types.wgsl index ef39307b49c22..186f32ec385b1 100644 --- a/crates/bevy_pbr/src/deferred/pbr_deferred_types.wgsl +++ b/crates/bevy_pbr/src/deferred/pbr_deferred_types.wgsl @@ -2,18 +2,16 @@ #import bevy_pbr::{ mesh_types::MESH_FLAGS_SHADOW_RECEIVER_BIT, - pbr_types::{STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT, STANDARD_MATERIAL_FLAGS_UNLIT_BIT}, + pbr_types::{STANDARD_MATERIAL_FLAGS_UNLIT_BIT}, } // Maximum of 8 bits available const DEFERRED_FLAGS_UNLIT_BIT: u32 = 1u; -const DEFERRED_FLAGS_FOG_ENABLED_BIT: u32 = 2u; -const DEFERRED_MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 4u; +const DEFERRED_MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 2u; fn deferred_flags_from_mesh_material_flags(mesh_flags: u32, mat_flags: u32) -> u32 { var flags = 0u; flags |= u32((mesh_flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u) * DEFERRED_MESH_FLAGS_SHADOW_RECEIVER_BIT; - flags |= u32((mat_flags & STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) * DEFERRED_FLAGS_FOG_ENABLED_BIT; flags |= u32((mat_flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) * DEFERRED_FLAGS_UNLIT_BIT; return flags; } @@ -22,7 +20,6 @@ fn mesh_material_flags_from_deferred_flags(deferred_flags: u32) -> vec2 { var mat_flags = 0u; var mesh_flags = 0u; mesh_flags |= u32((deferred_flags & DEFERRED_MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u) * MESH_FLAGS_SHADOW_RECEIVER_BIT; - mat_flags |= u32((deferred_flags & DEFERRED_FLAGS_FOG_ENABLED_BIT) != 0u) * STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT; mat_flags |= u32((deferred_flags & DEFERRED_FLAGS_UNLIT_BIT) != 0u) * STANDARD_MATERIAL_FLAGS_UNLIT_BIT; return vec2(mesh_flags, mat_flags); } diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 59a6792dff5e7..1d21348f29589 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -867,7 +867,7 @@ bitflags::bitflags! { const UNLIT = 1 << 5; const TWO_COMPONENT_NORMAL_MAP = 1 << 6; const FLIP_NORMAL_MAP_Y = 1 << 7; - const FOG_ENABLED = 1 << 8; + // const UNUSED = 1 << 8; // USE THIS IF YOU ADD A NEW FLAG const DEPTH_MAP = 1 << 9; // Used for parallax mapping const SPECULAR_TRANSMISSION_TEXTURE = 1 << 10; const THICKNESS_TEXTURE = 1 << 11; @@ -975,9 +975,6 @@ impl AsBindGroupShaderType for StandardMaterial { if self.unlit { flags |= StandardMaterialFlags::UNLIT; } - if self.fog_enabled { - flags |= StandardMaterialFlags::FOG_ENABLED; - } if self.depth_map.is_some() { flags |= StandardMaterialFlags::DEPTH_MAP; } @@ -1115,6 +1112,7 @@ bitflags! { const CLEARCOAT_UV = 0x040000; const CLEARCOAT_ROUGHNESS_UV = 0x080000; const CLEARCOAT_NORMAL_UV = 0x100000; + const FOG_ENABLED = 0x200000; const DEPTH_BIAS = 0xffffffff_00000000; } } @@ -1222,6 +1220,7 @@ impl From<&StandardMaterial> for StandardMaterialKey { material.clearcoat_normal_channel != UvChannel::Uv0, ); } + key.set(StandardMaterialKey::FOG_ENABLED, material.fog_enabled); key.insert(StandardMaterialKey::from_bits_retain( (material.depth_bias as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT, @@ -1378,6 +1377,7 @@ impl Material for StandardMaterial { StandardMaterialKey::ANISOTROPY_UV, "STANDARD_MATERIAL_ANISOTROPY_UV", ), + (StandardMaterialKey::FOG_ENABLED, "FOG_ENABLED"), ] { if key.bind_group_data.intersects(flags) { shader_defs.push(shader_def.into()); diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index 35e683c4ffd18..f3146b93873fa 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -809,9 +809,11 @@ fn main_pass_post_lighting_processing( var output_color = input_color; // fog - if (view_bindings::fog.mode != mesh_view_types::FOG_MODE_OFF && (pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) { +#ifdef FOG_ENABLED + if (view_bindings::fog.mode != mesh_view_types::FOG_MODE_OFF) { output_color = apply_fog(view_bindings::fog, output_color, pbr_input.world_position.xyz, view_bindings::view.world_position.xyz); } +#endif // FOG_ENABLED #ifdef TONEMAP_IN_SHADER output_color = tone_mapping(output_color, view_bindings::view.color_grading); diff --git a/crates/bevy_pbr/src/render/pbr_types.wgsl b/crates/bevy_pbr/src/render/pbr_types.wgsl index d9b600c40bf90..9f4c311935d05 100644 --- a/crates/bevy_pbr/src/render/pbr_types.wgsl +++ b/crates/bevy_pbr/src/render/pbr_types.wgsl @@ -42,7 +42,7 @@ const STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT: u32 = 16u; const STANDARD_MATERIAL_FLAGS_UNLIT_BIT: u32 = 32u; const STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP: u32 = 64u; const STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y: u32 = 128u; -const STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT: u32 = 256u; +// const STANDARD_MATERIAL_FLAGS_UNUSED_BIT: u32 = 256u; const STANDARD_MATERIAL_FLAGS_DEPTH_MAP_BIT: u32 = 512u; const STANDARD_MATERIAL_FLAGS_SPECULAR_TRANSMISSION_TEXTURE_BIT: u32 = 1024u; const STANDARD_MATERIAL_FLAGS_THICKNESS_TEXTURE_BIT: u32 = 2048u;