From bfaa64daea1470e0fef171f479ebcf5944df0d9f Mon Sep 17 00:00:00 2001 From: Marco Buono Date: Tue, 30 Jan 2024 22:30:59 -0300 Subject: [PATCH 1/5] Add bind group data shader defs for diffuse and specular transmission --- crates/bevy_pbr/src/pbr_material.rs | 17 +++++++++++++++++ crates/bevy_pbr/src/render/mesh.rs | 8 ++++++-- crates/bevy_pbr/src/render/pbr_functions.wgsl | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index ef106c010e793..47558886019a1 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -740,6 +740,8 @@ pub struct StandardMaterialKey { cull_mode: Option, depth_bias: i32, relief_mapping: bool, + diffuse_transmission: bool, + specular_transmission: bool, } impl From<&StandardMaterial> for StandardMaterialKey { @@ -752,6 +754,8 @@ impl From<&StandardMaterial> for StandardMaterialKey { material.parallax_mapping_method, ParallaxMappingMethod::Relief { .. } ), + diffuse_transmission: material.diffuse_transmission > 0.0, + specular_transmission: material.specular_transmission > 0.0, } } } @@ -816,6 +820,19 @@ impl Material for StandardMaterial { if key.bind_group_data.relief_mapping { shader_defs.push("RELIEF_MAPPING".into()); } + + if key.bind_group_data.diffuse_transmission { + shader_defs.push("STANDARD_MATERIAL_DIFFUSE_TRANSMISSION".into()); + } + + if key.bind_group_data.specular_transmission { + shader_defs.push("STANDARD_MATERIAL_SPECULAR_TRANSMISSION".into()); + } + + if key.bind_group_data.diffuse_transmission || key.bind_group_data.specular_transmission + { + shader_defs.push("STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION".into()); + } } descriptor.primitive.cull_mode = key.bind_group_data.cull_mode; if let Some(label) = &mut descriptor.label { diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 172a032b0401e..a34717fa08946 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -589,8 +589,8 @@ impl MeshPipelineKey { pub fn from_msaa_samples(msaa_samples: u32) -> Self { let msaa_bits = - (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; - Self::from_bits_retain(msaa_bits) + (msaa_samples.trailing_zeros() as u32 & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits_retain(msaa_bits as u32) } pub fn from_hdr(hdr: bool) -> Self { @@ -777,6 +777,10 @@ impl SpecializedMeshPipeline for MeshPipeline { is_opaque = !key.contains(MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE); } + if key.contains(MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE) { + shader_defs.push("READS_VIEW_TRANSMISSION_TEXTURE".into()); + } + if key.contains(MeshPipelineKey::NORMAL_PREPASS) { shader_defs.push("NORMAL_PREPASS".into()); } diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index eca7463d9b178..7e46b127f77a2 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -213,6 +213,7 @@ fn apply_pbr_lighting( let light_contrib = lighting::point_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color); direct_light += light_contrib * shadow; +#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION if diffuse_transmission > 0.0 { // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated // world position, inverted normal and view vectors, and the following simplified @@ -231,6 +232,7 @@ fn apply_pbr_lighting( let light_contrib = lighting::point_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); transmitted_light += light_contrib * transmitted_shadow; } +#endif } // Spot lights (direct) @@ -245,6 +247,7 @@ fn apply_pbr_lighting( let light_contrib = lighting::spot_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color); direct_light += light_contrib * shadow; +#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION if diffuse_transmission > 0.0 { // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated // world position, inverted normal and view vectors, and the following simplified @@ -263,6 +266,7 @@ fn apply_pbr_lighting( let light_contrib = lighting::spot_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); transmitted_light += light_contrib * transmitted_shadow; } +#endif } // directional lights (direct) @@ -286,6 +290,7 @@ fn apply_pbr_lighting( #endif direct_light += light_contrib * shadow; +#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION if diffuse_transmission > 0.0 { // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated // world position, inverted normal and view vectors, and the following simplified @@ -304,11 +309,13 @@ fn apply_pbr_lighting( let light_contrib = lighting::directional_light(i, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); transmitted_light += light_contrib * transmitted_shadow; } +#endif } // Ambient light (indirect) var indirect_light = ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); +#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION if diffuse_transmission > 0.0 { // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated // world position, inverted normal and view vectors, and the following simplified @@ -320,6 +327,7 @@ fn apply_pbr_lighting( // diffuse_occlusion = vec3(1.0) transmitted_light += ambient::ambient_light(diffuse_transmissive_lobe_world_position, -in.N, -in.V, 1.0, diffuse_transmissive_color, vec3(0.0), 1.0, vec3(1.0)); } +#endif // Environment map light (indirect) #ifdef ENVIRONMENT_MAP @@ -339,6 +347,7 @@ fn apply_pbr_lighting( // light in the call to `specular_transmissive_light()` below var specular_transmitted_environment_light = vec3(0.0); +#ifdef STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION if diffuse_transmission > 0.0 || specular_transmission > 0.0 { // NOTE: We use the diffuse transmissive color, inverted normal and view vectors, // and the following simplified values for the transmitted environment light contribution @@ -368,9 +377,14 @@ fn apply_pbr_lighting( T, vec3(1.0), in.world_position.xyz); +#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; +#endif +#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; +#endif } +#endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION #else // If there's no environment map light, there's no transmitted environment // light specular component, so we can just hardcode it to zero. @@ -383,6 +397,7 @@ fn apply_pbr_lighting( let emissive_light = emissive.rgb * output_color.a; +#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION if specular_transmission > 0.0 { transmitted_light += transmission::specular_transmissive_light(in.world_position, in.frag_coord.xyz, view_z, in.N, in.V, F0, ior, thickness, perceptual_roughness, specular_transmissive_color, specular_transmitted_environment_light).rgb; } @@ -401,6 +416,7 @@ fn apply_pbr_lighting( vec3(0.0) // TODO: Pass in (pre-attenuated) scattered light contribution here ).rgb; } +#endif // Total light output_color = vec4( From 33851b79af087c2a1728750a6b2ea4a78ef01b27 Mon Sep 17 00:00:00 2001 From: Marco Buono Date: Wed, 31 Jan 2024 01:29:16 -0300 Subject: [PATCH 2/5] Rename normal map shader def for consistency --- assets/shaders/array_texture.wgsl | 2 +- crates/bevy_pbr/src/pbr_material.rs | 2 +- crates/bevy_pbr/src/render/pbr_fragment.wgsl | 2 +- crates/bevy_pbr/src/render/pbr_functions.wgsl | 8 ++++---- crates/bevy_pbr/src/render/pbr_prepass.wgsl | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/shaders/array_texture.wgsl b/assets/shaders/array_texture.wgsl index f67e08aa06471..7c0216f73e592 100644 --- a/assets/shaders/array_texture.wgsl +++ b/assets/shaders/array_texture.wgsl @@ -43,7 +43,7 @@ fn fragment( double_sided, is_front, #ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP mesh.world_tangent, #endif #endif diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 47558886019a1..25cb24fc14447 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -815,7 +815,7 @@ impl Material for StandardMaterial { let shader_defs = &mut fragment.shader_defs; if key.bind_group_data.normal_map { - shader_defs.push("STANDARDMATERIAL_NORMAL_MAP".into()); + shader_defs.push("STANDARD_MATERIAL_NORMAL_MAP".into()); } if key.bind_group_data.relief_mapping { shader_defs.push("RELIEF_MAPPING".into()); diff --git a/crates/bevy_pbr/src/render/pbr_fragment.wgsl b/crates/bevy_pbr/src/render/pbr_fragment.wgsl index 169d42f0a6f81..be759d38b573e 100644 --- a/crates/bevy_pbr/src/render/pbr_fragment.wgsl +++ b/crates/bevy_pbr/src/render/pbr_fragment.wgsl @@ -190,7 +190,7 @@ fn pbr_input_from_standard_material( double_sided, is_front, #ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP in.world_tangent, #endif #endif diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index 7e46b127f77a2..d8d793c54cbe8 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -50,7 +50,7 @@ fn prepare_world_normal( ) -> vec3 { var output: vec3 = world_normal; #ifndef VERTEX_TANGENTS -#ifndef STANDARDMATERIAL_NORMAL_MAP +#ifndef STANDARD_MATERIAL_NORMAL_MAP // NOTE: When NOT using normal-mapping, if looking at the back face of a double-sided // material, the normal needs to be inverted. This is a branchless version of that. output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; @@ -65,7 +65,7 @@ fn apply_normal_mapping( double_sided: bool, is_front: bool, #ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP world_tangent: vec4, #endif #endif @@ -83,7 +83,7 @@ fn apply_normal_mapping( var N: vec3 = world_normal; #ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP // NOTE: The mikktspace method of normal mapping explicitly requires that these NOT be // normalized nor any Gram-Schmidt applied to ensure the vertex normal is orthogonal to the // vertex tangent! Do not change this code unless you really know what you are doing. @@ -95,7 +95,7 @@ fn apply_normal_mapping( #ifdef VERTEX_TANGENTS #ifdef VERTEX_UVS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP // Nt is the tangent-space normal. var Nt = textureSampleBias(pbr_bindings::normal_map_texture, pbr_bindings::normal_map_sampler, uv, mip_bias).rgb; if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u { diff --git a/crates/bevy_pbr/src/render/pbr_prepass.wgsl b/crates/bevy_pbr/src/render/pbr_prepass.wgsl index e17826a3f4430..8be86b5af2175 100644 --- a/crates/bevy_pbr/src/render/pbr_prepass.wgsl +++ b/crates/bevy_pbr/src/render/pbr_prepass.wgsl @@ -38,9 +38,9 @@ fn fragment( double_sided, is_front, #ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP +#ifdef STANDARD_MATERIAL_NORMAL_MAP in.world_tangent, -#endif // STANDARDMATERIAL_NORMAL_MAP +#endif // STANDARD_MATERIAL_NORMAL_MAP #endif // VERTEX_TANGENTS #ifdef VERTEX_UVS in.uv, From 83a6324777ea0cd2e726a8ec193d7143de28cbb9 Mon Sep 17 00:00:00 2001 From: Marco Buono Date: Wed, 31 Jan 2024 01:49:13 -0300 Subject: [PATCH 3/5] Remove bogus type casts accidentally commited in --- crates/bevy_pbr/src/render/mesh.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index a34717fa08946..2fc4e31b47b3a 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -589,8 +589,8 @@ impl MeshPipelineKey { pub fn from_msaa_samples(msaa_samples: u32) -> Self { let msaa_bits = - (msaa_samples.trailing_zeros() as u32 & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; - Self::from_bits_retain(msaa_bits as u32) + (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits_retain(msaa_bits) } pub fn from_hdr(hdr: bool) -> Self { From 1a2650efcc5b2f0b6e528d887ed272ecd2a2ba78 Mon Sep 17 00:00:00 2001 From: Marco Buono Date: Wed, 31 Jan 2024 03:31:23 -0300 Subject: [PATCH 4/5] Remove accidentally commited bogus shader def --- crates/bevy_pbr/src/render/mesh.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 2fc4e31b47b3a..172a032b0401e 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -777,10 +777,6 @@ impl SpecializedMeshPipeline for MeshPipeline { is_opaque = !key.contains(MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE); } - if key.contains(MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE) { - shader_defs.push("READS_VIEW_TRANSMISSION_TEXTURE".into()); - } - if key.contains(MeshPipelineKey::NORMAL_PREPASS) { shader_defs.push("NORMAL_PREPASS".into()); } From 6806650a5e67037514ba34e859928019c03b26f7 Mon Sep 17 00:00:00 2001 From: Marco Buono Date: Thu, 1 Feb 2024 21:31:43 -0300 Subject: [PATCH 5/5] Remove `if` checks for transmission values --- crates/bevy_pbr/src/render/pbr_functions.wgsl | 182 ++++++++---------- 1 file changed, 85 insertions(+), 97 deletions(-) diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index d8d793c54cbe8..78dbc9a82a70b 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -214,24 +214,22 @@ fn apply_pbr_lighting( direct_light += light_contrib * shadow; #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION - if diffuse_transmission > 0.0 { - // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated - // world position, inverted normal and view vectors, and the following simplified - // values for a fully diffuse transmitted light contribution approximation: - // - // roughness = 1.0; - // NdotV = 1.0; - // R = vec3(0.0) // doesn't really matter - // f_ab = vec2(0.1) - // F0 = vec3(0.0) - var transmitted_shadow: f32 = 1.0; - if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) - && (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { - transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); - } - let light_contrib = lighting::point_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); - transmitted_light += light_contrib * transmitted_shadow; + // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated + // world position, inverted normal and view vectors, and the following simplified + // values for a fully diffuse transmitted light contribution approximation: + // + // roughness = 1.0; + // NdotV = 1.0; + // R = vec3(0.0) // doesn't really matter + // f_ab = vec2(0.1) + // F0 = vec3(0.0) + var transmitted_shadow: f32 = 1.0; + if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) + && (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { + transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); } + let transmitted_light_contrib = lighting::point_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); + transmitted_light += transmitted_light_contrib * transmitted_shadow; #endif } @@ -248,24 +246,22 @@ fn apply_pbr_lighting( direct_light += light_contrib * shadow; #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION - if diffuse_transmission > 0.0 { - // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated - // world position, inverted normal and view vectors, and the following simplified - // values for a fully diffuse transmitted light contribution approximation: - // - // roughness = 1.0; - // NdotV = 1.0; - // R = vec3(0.0) // doesn't really matter - // f_ab = vec2(0.1) - // F0 = vec3(0.0) - var transmitted_shadow: f32 = 1.0; - if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) - && (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { - transmitted_shadow = shadows::fetch_spot_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); - } - let light_contrib = lighting::spot_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); - transmitted_light += light_contrib * transmitted_shadow; + // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated + // world position, inverted normal and view vectors, and the following simplified + // values for a fully diffuse transmitted light contribution approximation: + // + // roughness = 1.0; + // NdotV = 1.0; + // R = vec3(0.0) // doesn't really matter + // f_ab = vec2(0.1) + // F0 = vec3(0.0) + var transmitted_shadow: f32 = 1.0; + if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) + && (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { + transmitted_shadow = shadows::fetch_spot_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); } + let transmitted_light_contrib = lighting::spot_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); + transmitted_light += transmitted_light_contrib * transmitted_shadow; #endif } @@ -291,24 +287,22 @@ fn apply_pbr_lighting( direct_light += light_contrib * shadow; #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION - if diffuse_transmission > 0.0 { - // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated - // world position, inverted normal and view vectors, and the following simplified - // values for a fully diffuse transmitted light contribution approximation: - // - // roughness = 1.0; - // NdotV = 1.0; - // R = vec3(0.0) // doesn't really matter - // f_ab = vec2(0.1) - // F0 = vec3(0.0) - var transmitted_shadow: f32 = 1.0; - if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) - && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { - transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z); - } - let light_contrib = lighting::directional_light(i, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); - transmitted_light += light_contrib * transmitted_shadow; + // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated + // world position, inverted normal and view vectors, and the following simplified + // values for a fully diffuse transmitted light contribution approximation: + // + // roughness = 1.0; + // NdotV = 1.0; + // R = vec3(0.0) // doesn't really matter + // f_ab = vec2(0.1) + // F0 = vec3(0.0) + var transmitted_shadow: f32 = 1.0; + if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) + && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { + transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z); } + let transmitted_light_contrib = lighting::directional_light(i, 1.0, 1.0, -in.N, -in.V, vec3(0.0), vec3(0.0), vec2(0.1), diffuse_transmissive_color); + transmitted_light += transmitted_light_contrib * transmitted_shadow; #endif } @@ -316,17 +310,15 @@ fn apply_pbr_lighting( var indirect_light = ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION - if diffuse_transmission > 0.0 { - // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated - // world position, inverted normal and view vectors, and the following simplified - // values for a fully diffuse transmitted light contribution approximation: - // - // perceptual_roughness = 1.0; - // NdotV = 1.0; - // F0 = vec3(0.0) - // diffuse_occlusion = vec3(1.0) - transmitted_light += ambient::ambient_light(diffuse_transmissive_lobe_world_position, -in.N, -in.V, 1.0, diffuse_transmissive_color, vec3(0.0), 1.0, vec3(1.0)); - } + // NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated + // world position, inverted normal and view vectors, and the following simplified + // values for a fully diffuse transmitted light contribution approximation: + // + // perceptual_roughness = 1.0; + // NdotV = 1.0; + // F0 = vec3(0.0) + // diffuse_occlusion = vec3(1.0) + transmitted_light += ambient::ambient_light(diffuse_transmissive_lobe_world_position, -in.N, -in.V, 1.0, diffuse_transmissive_color, vec3(0.0), 1.0, vec3(1.0)); #endif // Environment map light (indirect) @@ -348,42 +340,40 @@ fn apply_pbr_lighting( var specular_transmitted_environment_light = vec3(0.0); #ifdef STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION - if diffuse_transmission > 0.0 || specular_transmission > 0.0 { - // NOTE: We use the diffuse transmissive color, inverted normal and view vectors, - // and the following simplified values for the transmitted environment light contribution - // approximation: - // - // diffuse_color = vec3(1.0) // later we use `diffuse_transmissive_color` and `specular_transmissive_color` - // NdotV = 1.0; - // R = T // see definition below - // F0 = vec3(1.0) - // diffuse_occlusion = 1.0 - // - // (This one is slightly different from the other light types above, because the environment - // map light returns both diffuse and specular components separately, and we want to use both) - - let T = -normalize( - in.V + // start with view vector at entry point - refract(in.V, -in.N, 1.0 / ior) * thickness // add refracted vector scaled by thickness, towards exit point - ); // normalize to find exit point view vector - - let transmitted_environment_light = bevy_pbr::environment_map::environment_map_light( - perceptual_roughness, - roughness, - vec3(1.0), - 1.0, - f_ab, - -in.N, - T, - vec3(1.0), - in.world_position.xyz); + // NOTE: We use the diffuse transmissive color, inverted normal and view vectors, + // and the following simplified values for the transmitted environment light contribution + // approximation: + // + // diffuse_color = vec3(1.0) // later we use `diffuse_transmissive_color` and `specular_transmissive_color` + // NdotV = 1.0; + // R = T // see definition below + // F0 = vec3(1.0) + // diffuse_occlusion = 1.0 + // + // (This one is slightly different from the other light types above, because the environment + // map light returns both diffuse and specular components separately, and we want to use both) + + let T = -normalize( + in.V + // start with view vector at entry point + refract(in.V, -in.N, 1.0 / ior) * thickness // add refracted vector scaled by thickness, towards exit point + ); // normalize to find exit point view vector + + let transmitted_environment_light = bevy_pbr::environment_map::environment_map_light( + perceptual_roughness, + roughness, + vec3(1.0), + 1.0, + f_ab, + -in.N, + T, + vec3(1.0), + in.world_position.xyz); #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION - transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; + transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; #endif #ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION - specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; + specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; #endif - } #endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION #else // If there's no environment map light, there's no transmitted environment @@ -398,9 +388,7 @@ fn apply_pbr_lighting( let emissive_light = emissive.rgb * output_color.a; #ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION - if specular_transmission > 0.0 { - transmitted_light += transmission::specular_transmissive_light(in.world_position, in.frag_coord.xyz, view_z, in.N, in.V, F0, ior, thickness, perceptual_roughness, specular_transmissive_color, specular_transmitted_environment_light).rgb; - } + transmitted_light += transmission::specular_transmissive_light(in.world_position, in.frag_coord.xyz, view_z, in.N, in.V, F0, ior, thickness, perceptual_roughness, specular_transmissive_color, specular_transmitted_environment_light).rgb; if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u { // We reuse the `atmospheric_fog()` function here, as it's fundamentally